Guide · SaaS & dev
Bot Discord : interactions HTTP, puis Docker
Premier bot Discord officiel, puis guide Node.js Docker. Deux tutoriels distincts. Endpoint /interactions. Commandes non rejouées le 2026-10-18.
Discord n’a pas, dans les pages relues le 2026-10-18, un tutoriel « mettez ce bot dans Docker ». Il a un premier bot HTTP, Building your first Discord Bot. Docker a un guide Node.js, Node.js language-specific guide, dont l’exemple est une API Express qui répond {"message":"Hello World"}, pas le dépôt d’exemple Discord.
Cet article suit le bot jusqu’à l’URL d’interactions, puis dit ce que le guide Docker couvre vraiment. Il ne fusionne pas les deux dépôts. Les commandes n’ont pas été rejouées. Pas de jeton, pas de capture. Le guide Discord en montre. Ici, non.
Architecture d’un bot Discord IA et Claude Code pour un bot Discord parlent de structure et de commandes, pas de cette image. Déployer un agent IA avec Docker couvre l’utilisateur non privilégié, les secrets et les volumes. Ne le recopiez pas : appliquez-le au conteneur une fois le CMD aligné sur le script du dépôt Discord. Docker Compose pour un SaaS couvre réseaux et volumes si vous ajoutez une base. Le premier bot officiel n’en a pas.
Étape 0, dépôt d’exemple
Node.js installé. Puis, dans l’ordre de la page :
git clone https://github.com/discord/discord-example-app.git
cd discord-example-app
npm install
La page suppose un peu de JavaScript. L’app d’exemple joue à une variante de pierre-feuille-ciseaux. Nous n’avons pas cloné le dépôt, donc nous ne listons pas ses fichiers au-delà de ceux que la page nomme : .env.sample, commands.js, app.js, utils.js, game.js.
Étape 1, l’app dans le portail
Créer l’app depuis le lien de la page, lui donner un nom, Create. La page General Information montre l’Application ID et le champ Interactions Endpoint URL. L’URL vient plus tard. La laisser vide à cette étape est ce que le guide fait.
Renommer .env.sample en .env. Ne collez aucune valeur secrète ici. Le fichier attend trois valeurs :
- Application ID, page General Information, à la place de
<YOUR_APP_ID> - Public Key, même page, à la place de
<YOUR_PUBLIC_KEY> - Bot token : page Bot, Reset Token, à la place de
<YOUR_BOT_TOKEN>
Le jeton ne va pas dans Git, ni dans une image, ni dans un log. Le guide Déployer un agent IA avec Docker dit comment injecter un secret au runtime. Le fichier .env du tutoriel Discord est un fichier local. Ne le COPY pas.
La page Bot permet les privileged intents et l’install par d’autres utilisateurs. Le guide dit de ne rien changer ici pour ce premier bot.
Installation : cocher User Install et Guild Install. Install Link : Discord Provided Link. Dans Default Install Settings, la page coche applications.commands pour l’install utilisateur. Pour l’install serveur, applications.commands et bot, puis la permission Send Messages dans l’exemple de l’auteur. Ce n’est pas la liste minimale universelle. C’est ce que cette page coche pour la suite.
Coller le lien d’install. Add to server sur un serveur de test, puis le même lien, Add to my apps. La page dit que le bot apparaît dans la liste des membres, et qu’on peut ouvrir un DM avec l’app installée sur le compte. Nous n’avons pas de serveur de test.
Étape 2, enregistrer les commandes
npm run register
Le script pousse ALL_COMMANDS, en bas de commands.js, en commandes globales, via PUT /applications/<APP_ID>/commands. La page dit que les commandes apparaissent, et que les lancer ne fait rien tant que l’app ne reçoit pas les requêtes.
Résultat attendu, d’après la page : les commandes visibles, sans réponse. Non vérifié ici.
Étape 3, endpoint public
npm run start
La page attend un processus sur le port 3000. Express vérifie les en-têtes et répond aux PING. Puis, dans un autre terminal, ngrok installé depuis sa page de téléchargement :
ngrok http 3000
Prendre l’URL Forwarding, pas l’interface locale 127.0.0.1:4040. Dans General Information, Interactions Endpoint URL : cette URL plus /interactions. Save Changes. La vérification, dans l’exemple, passe par PUBLIC_KEY et le paquet discord-interactions, et par une réponse aux PING.
Interactions Overview précise le contrat, et il est plus strict que le résumé du quickstart :
- Deux livraisons s’excluent. Par défaut, la Gateway. L’URL d’interactions est un opt-in HTTP. Si vous remplissez l’URL, vous n’êtes plus sur la Gateway pour ces interactions.
- Au moment d’enregistrer l’URL, Discord envoie un
POSTde type1(PING). Il faut répondre200avec un corps de type1, et unContent-Typevalide. - Chaque requête porte
X-Signature-Ed25519etX-Signature-Timestamp. Signature invalide :401. Le corps vérifié est le corps brut. - Discord renvoie aussi des signatures invalides, exprès. Si l’endpoint les accepte, Discord retire l’URL et prévient par e-mail et DM système.
Le quickstart s’arrête à ngrok. Une URL ngrok de session n’est pas une URL de prod. Quand le tunnel tombe, l’endpoint ne vérifie plus.
La page dit ensuite de déclencher /test. La réponse attendue est un message du canal, avec « hello world » et un emoji tiré d’une fonction du dépôt. Puis /challenge, défini comme CHALLENGE_COMMAND dans commands.js, avec des options tirées de RPSChoices dans game.js. Nous n’avons pas lancé la commande.
Docker, sans prétendre que c’est le même exemple
Le guide Node.js de Docker, relu le 2026-10-18, demande Docker Desktop, un peu de JavaScript et de TypeScript, et les notions d’image et de Dockerfile. Son exemple à lui se crée dans nodejs-docker-example. Ce n’est pas discord-example-app.
Ordre de sa section « Containerize » :
- Fichiers de l’app d’exemple, ou le script d’échafaudage de la page.
src/index.tsécouteprocess.env.PORTou 3000. - Si Node est installé :
npm install,npm run dev, ounpm run buildpuisnpm start. Sinon, la page dit de sauter : la suite tourne dans le conteneur. docker login dhi.io, pour tirer les images Node durcies listées dans le catalogue.Dockerfileen trois étapes :builder(dépendances ettsc),deps(prod seulement),runner(copie dedistet denode_modules, utilisateurnode,EXPOSE 3000,CMD ["node", "dist/index.js"]).compose.yaml: serviceserver, build du dossier courant, port3000:3000..dockerignore, pour laisser secrets et caches hors du contexte. Le.gitignorede l’exemple Docker ignore déjà.env.
docker compose up --build
Résultat attendu pour l’exemple Docker, pas pour Discord : http://localhost:3000 renvoie le JSON de salutation. Arrêt : ctrl+c, ou docker compose down si vous avez lancé avec -d.
Le dépôt Discord, d’après son quickstart, se lance avec npm run start et écoute 3000. Nous n’avons pas ouvert son package.json. Ne lui collez pas node dist/index.js parce que c’est le CMD de l’autre guide. Ouvrez le script start du dépôt cloné, et faites correspondre le CMD à ce script. Si le dépôt n’est pas en TypeScript, les étapes tsc et dist/ du guide Docker ne s’appliquent pas telles quelles.
Le quickstart Discord utilise ngrok devant un processus local. Un conteneur qui n’écoute que dans le réseau Docker ne reçoit pas les POST de Discord tant qu’une URL HTTPS publique ne pointe pas vers le port publié, et tant que cette URL plus /interactions n’est pas enregistrée. Le guide Docker ne crée pas cette URL. N’en inventez pas une.
Héberger n8n sur un VPS sépare l’installation d’un outil et son exposition publique. Ce n’est pas un bot Discord, et ce n’est pas ce Dockerfile. Si vous sortez de ngrok vers une machine, lisez ce guide pour la frontière install / exposition, pas pour les commandes n8n.
Une app qui reste connectée à la Gateway est un autre processus que l’Express du quickstart. L’overview le dit : Gateway ou URL HTTP, pas les deux. Cet article ne fournit pas de Dockerfile de Gateway. Les intents privilégiés, que le quickstart laisse de côté, sont documentés sur la page Bot. Ils ne s’activent pas en copiant l’exemple.
Sources
- Building your first Discord Bot : clone,
.env, scopes,npm run register,npm run start,ngrok http 3000, suffixe/interactions. - Interactions Overview : Gateway ou HTTP,
PINGtype 1, signatures, retrait de l’URL si la vérif échoue. - Node.js language-specific guide : autre exemple, login
dhi.io, trois étapes,docker compose up --build. - Dépôt cité par Discord : discord-example-app. Non cloné le 2026-10-18.
Sources recontrôlées le 2026-10-19. Commandes non rejouées. Pas de jeton dans cet article. Si le quickstart change le port ou le chemin /interactions, c’est la page qui compte.