{"id":20549233,"url":"https://github.com/zenika/faq-slack-bot","last_synced_at":"2026-04-20T01:34:34.623Z","repository":{"id":49872646,"uuid":"150405793","full_name":"Zenika/faq-slack-bot","owner":"Zenika","description":"A chatbot that answers questions using external APIs","archived":false,"fork":false,"pushed_at":"2022-12-22T08:51:43.000Z","size":1002,"stargazers_count":0,"open_issues_count":6,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-02-25T10:01:49.427Z","etag":null,"topics":["chatbot","faq","message","messenger-bot","slack","slash-commands","workplace"],"latest_commit_sha":null,"homepage":"https://zenika.facebook.com/Chat-bot-FAQ-2218338505157978/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Zenika.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-09-26T09:57:35.000Z","updated_at":"2021-07-22T15:37:13.000Z","dependencies_parsed_at":"2023-01-30T06:16:49.571Z","dependency_job_id":null,"html_url":"https://github.com/Zenika/faq-slack-bot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zenika%2Ffaq-slack-bot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zenika%2Ffaq-slack-bot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zenika%2Ffaq-slack-bot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zenika%2Ffaq-slack-bot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Zenika","download_url":"https://codeload.github.com/Zenika/faq-slack-bot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242153242,"owners_count":20080461,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chatbot","faq","message","messenger-bot","slack","slash-commands","workplace"],"created_at":"2024-11-16T02:17:00.965Z","updated_at":"2026-04-20T01:34:29.593Z","avatar_url":"https://github.com/Zenika.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Zenbot - Un chatbot qui répond aux questions en consultant des APIs externes.\n\nZenbot permet l'intégration (interfaçage) d'APIs comme la [FAQ Zenika](https://zenika.faq.team/gql) ou encore [Stack Overflow](https://stackoverflow.com/) au sein de messageries instantanées telles que Messenger ou Slack.\n\n## Liste des commandes Slack\n\n| Command  | Argument            | Explication                                           |\n| -------- | ------------------- | ----------------------------------------------------- |\n| _/faq_   | `text de recherche` | **Lance une recherche sur https://zenika.faq.team/**  |\n| _/stack_ | `text de recherche` | **Lance une recherche sur http://stackoverflow.com/** |\n\n## Tuto\n\n_Ce Readme présente en 3 étapes la démarche qui a permis de créer et d'intégrer Zenbot aux plate-formes [Messenger](https://www.messenger.com/) et [Slack](https://slack.com)._\n\n## Etape 1 : La configuration d'une application\n\nLa première étape de création d'un bot passe par la configuration d'une application qui représentera le bot et contrôlera ses actions sur la plate-forme concernée.\nCette configuration se fait manuellement au niveau de chaque plate-forme.\nElle permet de définir tout un tas d'informations sur le bot telles que son nom, une description, les différentes permissions qui lui sont accordées, etc.\n\n#### Workplace\n\nSur Workplace, il s'agit de créer une **\"Custom Intégration\"**.\nLorqsu'on crée une **\"custom intégration\"**, 2 objets sont en fait crées :\n\n- Une application (avec des autorisations qui lui sont spécifiques).\n- Une page de type **Bot** (uniquement visible au sein de votre communauté Workplace).\n  Cette page servira entre autre de point d'entrée et de découverte de votre bot sur workplace.\n\nPendant la configuration, il vous sera demandé plusieurs informations sur votre bot dont l'URL sur laquelle le contacter.\nNous verrons comment obtenir cette URL à l'étape 3.\nIl vous sera aussi démandé de définir un token de vérification _verify token_.\nCe token permet de vérifier l'authenticité des échanges entre la plate-forme Messenger et le **webhook déployé sur votre serveur**.\nA l'issue de cette configuration, un **token (Page Accesss Token)** est généré.\nCe token servira par la suite à légitimer toute les actions de votre webhook en tant que bot associé à l'application que vous venez de créer.\nConservez le précieusement et ne le divulguez qu'aux personnes de confiance (ex: l'équipe de développement).\nNous verons dans la suite de ce readme, comment utiliser ce token.\n\n![alt text](https://github.com/Zenika/Zenbot/blob/master/docs/custom_integration_token.png 'Page Accesss Token')\n\nVous trouverez plus de détails sur la création d'une application Workplace ici: [Creating Apps for Workplace](https://developers.facebook.com/docs/workplace/integrations/custom-integrations/apps).\n\n#### Slack\n\nPour ce qui est de l'intégration de Zenbot dans Slack, nous avons fait le choix d'utiliser les **Slash Commands**.\nLes **Slash Commands** permettent à l'utilisateur d'effectuer des actions (dans notre cas des recherches) en tapant des commandes depuis slack.\nPar exemple, pour consulter la FAQ à propos des _\"notes de frais\"_ l'utilisateur pourra taper la commande _\"/faq note de frais\"_ depuis slack; il verra alors s'afficher une liste de résultats correspondant à sa recherche.\n\nLa page [Mes Applications](https://api.slack.com/apps) liste l'ensemble des applications que vous possédez sur Slack.\nPour en créer une nouvelle, il suffit de cliquer sur le bouton **\"Create New App\"** depuis cette page, puis renseigner le nom de l' application et l'espace de travail (**Development Slack Workspace**) auquel elle sera associée.\n\nUne fois l'application créée, il va falloir la configurer.\nPour ce faire, il faut se rendre sur la page de configuration de l'application en cliquant sur son nom dans la liste des applications.\nLa page de configuration contient nombre d'informations sur l'application dont son identifiant (**App Id**), le token de vérification(**Verification Token**), etc.\nCette page permet également de gérer les permissions ainsi que les différentes features (**Bot**, **Slash Commands**, etc) dont vous aurez besoin pour faire fonctionner votre application.\n\nPour faire tourner Zenbot nous avons eu besoin d'activer 2 features :\n\n- **Incoming Webhooks** : permet de poster des messages dans Slack depuis une source externe.\n- **Slash Commands** : permet aux utilisateurs d'effectuer des actions en tapant des commandes.\n  Cette feature nécessite d'être configurée en renseignant :\n\n  - un nom de commande (ex : _/faq_)\n  - une url de requête (l'url que Slack contactera à chaque fois qu'un utilisateur entrera la commande _/faq_). Nous verrons à l'étape 3 comment obtenir cette url.\n  - une courte description de la commande\n  - une instruction d'utilisation (court message expliquant comment utiliser la commande).\n\n  ![alt text](https://github.com/Zenika/Zenbot/blob/master/docs/slash_commands.png 'slash-command /faq')\n\nUne fois que la configurations de l'application et ses commandes terminées, il vous faudra installer l'application depuis le volet **\"Install your app to your workspace\"**.\nVous pourrez également choisir de distribuer votre application sur Slack, au delà de votre espace de travail.\n\nPour de plus amples précisions sur la création d'une application, vous pouvez consulter ceci: [Building Slack apps](https://api.slack.com/slack-apps).\n\nAnd Voilà! Vous savez désormais configurer une application Slack ou Workplace. Nous allons maintenant voir comment coder un **webhook** pour répondre aux reqûetes des utilisateurs.\n\n## Etape 2 : La création de Webhooks\n\nUn [webhook](https://en.wikipedia.org/wiki/Webhook) est une fonction de rappel HTTP (user-defined HTTP callback) généralement déclenchées lors d'un évènement (dans notre cas l'envoi d'un message à notre bot).\nPour faire simple notre webhook jouera le rôle d'intermédiaire entre notre chatbot et la FAQ Zenika.\nIl nous permettra de recevoir, gérer et envoyer des messages.\nA chaque fois qu'un utilisateur écrira un message à notre bot, il sera envoyé au webhook qui effectuera une recherche auprès de l'Api de la FAQ, puis retournera une réponse (le plus souvent au format JSON) à l'utilisateur.\n\nLa création de notre webhook consiste à créer quelques points de terminaison (endpoints) sur un serveur HTTP comme [Express](https://expressjs.com/fr/) par exemple.\n\n#### Workplace\n\nLa configuration du webhook sur Workplace se fait en 2 étapes :\n\n- L'ajout du _endpoint de vérification du webhook_.\n  Sur ce endpoint seront envoyées des requêtes de type GET servant à vérifier le token **\"Verify Token\"** défini lors de la configuration de la **\"Custom Intégration\"** vue à l'étape 1.\n  Cette étape est requise par la plate-forme Messenger pour garantir l'authenticité de notre webhook.\n\n  ```Javascript\n  // Adds support for GET requests to our webhook\n  app.get('/webhook', (req, res) =\u003e {\n\n  // Your verify token. Should be a random string.\n  let VERIFY_TOKEN = \"\u003cYOUR_VERIFY_TOKEN\u003e\"\n\n  // Parse the query params\n  let mode = req.query['hub.mode'];\n  let token = req.query['hub.verify_token'];\n  let challenge = req.query['hub.challenge'];\n\n  // Checks if a token and mode is in the query string of the request\n  if (mode \u0026\u0026 token) {\n\n    // Checks the mode and token sent is correct\n    if (mode === 'subscribe' \u0026\u0026 token === VERIFY_TOKEN) {\n\n      // Responds with the challenge token from the request\n      console.log('WEBHOOK_VERIFIED');\n      res.status(200).send(challenge);\n\n    } else {\n      // Responds with '403 Forbidden' if verify tokens do not match\n      res.sendStatus(403);\n    }\n  }\n  });\n  ```\n\n- L'ajout du _endpoint principal_.\n  Sur ce endpoint seront envoyées des requêtes de type POST correspondant aux messages envoyés par les utilisateurs.\n\n  ```Javascript\n  // Creates the endpoint for our webhook\n  app.post('/webhook', (req, res) =\u003e {\n\n  let body = req.body;\n\n  // Checks this is an event from a page subscription\n  if (body.object === 'page') {\n\n    // Iterates over each entry - there may be multiple if batched\n    body.entry.forEach(function(entry) {\n\n      // Gets the message. entry.messaging is an array, but\n      // will only ever contain one message, so we get index 0\n      let webhook_event = entry.messaging[0];\n      console.log(webhook_event);\n\n      // Get the sender PSID\n      let sender_psid = webhook_event.sender.id;\n      console.log('Sender PSID: ' + sender_psid);\n\n      // Check if the event is a message or postback and\n      // pass the event to the appropriate handler function\n      if (webhook_event.message) {\n        handleMessage(sender_psid, webhook_event.message);\n      } else if (webhook_event.postback) {\n        handlePostback(sender_psid, webhook_event.postback);\n      }\n    });\n\n    // Returns a '200 OK' response to all requests\n    res.status(200).send('EVENT_RECEIVED');\n  } else {\n  // Returns a '404 Not Found' if event is not from a page subscription\n  res.sendStatus(404);\n  }\n  });\n  ```\n\nVous trouverez plus de détails sur la configuration du webhook ici : [webhook setup](https://developers.facebook.com/docs/messenger-platform/getting-started/webhook-setup/).\n\nMessenger définit 2 types d'évènements entrant: les **messages** et les **postbacks**.\nLes messages représentent les messages textuels écrits par l'utilisateur (textos) tandis que les postbacks sont des retours (clic sur un bouton par exemple).\nUne fois notre endpoint principal configuré, nous aurons besoin de lui ajouter des fonctions de gestion d'évènements :\n\n- une fonction _handleMessage_ pour gerer les textos.\n- une fonction _handlePostback_ pour gerer les retours (clic boutons, sélections, etc).\n- une fonction _callSendAPI_ permettant d'envoyer des messages à l'utilisateur via l'API Send de Messenger.\n\n```Javascript\n// Handles messages events\nfunction handleMessage(sender_psid, received_message) {\n   let response = {};\n  //...\n  callSendAPI(sender_psid, response);\n}\n\n// Handles messaging_postbacks events\nfunction handlePostback(sender_psid, received_postback) {\n  let response = {};\n  //...\n  callSendAPI(sender_psid, response);\n}\n\n// Sends response messages via the Send API\nfunction callSendAPI(sender_psid, response) {\n// Construct the message body\nlet request_body = {\n  \"recipient\": {\n    \"id\": sender_psid\n  },\n  \"message\": response\n}\n\n// Send the HTTP request to the Messenger Platform\nrequest({\n  \"uri\": \"https://graph.facebook.com/v2.6/me/messages\",\n  \"qs\": { \"access_token\": PAGE_ACCESS_TOKEN }, //do not forget to specify the Page Access Token\n  \"method\": \"POST\",\n  \"json\": request_body\n}, (err, res, body) =\u003e {\n  if (!err) {\n    console.log('message sent!')\n  } else {\n    console.error(\"Unable to send message:\" + err);\n  }\n});\n}\n```\n\nIl y a ici 2 choses importantes à retenir:\n\n- On appelle toujours la fonction _callSendAPI_ pour envoyer une reponse lors de la réception d'un texto ou d'un retour.\n- Pour que la requête de réponse soit acceptée par la plate-forme Messenger, il faut **obligatoirement** ajouter dans le paramètre _qs (query string)_ de la requête le token **_Page Access Token_** généré à l'issue de l'étape 1.\n\nPour finir, il ne nous reste plus qu'à définir la structure de nos réponses. Celles-ci sont généralement au format JSON.\nMessenger dispose d'une grande variété de [templates](https://developers.facebook.com/docs/messenger-platform/send-messages/templates) prédéfinis pour nous aider à contruire nos messages de réponse.\nOn peut ainsi, envoyer un simple texto :\n\n```Javascript\n    response = {\n      \"text\": `Hello! Je suis Zenbot 😊.`\n    }\n```\n\nou bien un riche message composé d'un titre, d'une image et de boutons :\n\n```Javascript\nresponse = {\n      \"attachment\": {\n        \"type\": \"template\",\n        \"payload\": {\n          \"template_type\": \"generic\",\n          \"elements\": [{\n            \"title\": \"Is this the right picture?\",\n            \"subtitle\": \"Tap a button to answer.\",\n            \"image_url\": attachment_url,\n            \"buttons\": [\n              {\n                \"type\": \"postback\",\n                \"title\": \"Yes!\",\n                \"payload\": \"yes\",\n              },\n              {\n                \"type\": \"postback\",\n                \"title\": \"No!\",\n                \"payload\": \"no\",\n              }\n            ],\n          }]\n        }\n      }\n    }\n```\n\nVous connaissez maintenant les grandes lignes de la création d'un webhook pour la plate-forme Messenger.\nVous trouverez ici ([quick start](https://developers.facebook.com/docs/messenger-platform/getting-started/quick-start)) un tutoriel complet sur la conception d'un bot Messenger.\n\n#### Slack\n\nPour rappel, nous avons fait le choix d'utiliser les slash-commands pour implémenter notre bot sur Slack.\nLes slash-commands sont envoyées de la même manière qu'un message classique depuis la barre d'envoi des messages.\nCependant les slash-commands ne sont pas à proprement parler des messages.\nLa soumission d'une slash-command entraînera l'envoi à notre webhook d'une requête POST contenant en son corps une charge utile de données (payload).\n\nSur Slack, la création du webhook fonctionne à peu près de la même manière que sur Messenger.\nIl s'agit toujours de créer un ou plusieurs endpoints sur un serveur HTTP.\nCes endpoints recevront les charges utliles envoyées lors des soumissions de la commande _/faq_ puis retourneront une réponse au format JSON.\n\n\u003e A noter que sur slack, la [vérification du webhook](https://api.slack.com/docs/verifying-requests-from-slack) est possible mais pas obligatoire.\n\nPour tout savoir du fonctionnement d'une slash-command et de l'implémentation de son webhook associé, ça se passe ici : [Slash Commands](https://api.slack.com/slash-commands).\n\nTout comme Messenger, Slack dispose d'un système de templating pour les réponses au format JSON. Ce système de templating va nous aider à structurer et enrichir nos messages.\nEn plus de la structuration des messages, slack offre une grande variété d'outils de formatage des messages incluant le formatage des dates, l'ajout de fragments de code, etc.\nLa page [An introduction to messages](https://api.slack.com/docs/messages) explique en détail comment composer un message structuré.\nIl est également possible de trouver sur le compte github de Slack une [feuille de route](https://github.com/slackapi/slack-platform-assets) des templates les plus communément utilisés.\n\nVoilà pour ce qu'il en est de la création d'un webhook pour slack.\nVous trouverez plus de détails sur les intégrations Slack en général ici : [Building internal integrations for your workspace](https://api.slack.com/internal-integrations).\n\nNous avons fini de configurer notre webhook, il faut maintenant le déployer pour le rendre disponible sur web.\n\n## Etape 3 : Le déploiement\n\nPour déployer notre webhook, nous avons choisi d'utiliser la solution d'hébergement [Clever-cloud](https://www.clever-cloud.com/en/).\nClever Cloud fournit aux développeurs une plate-forme d'automatisation informatique avec une infrastructure robuste et une mise à l'échelle automatique.\nL'avantage d'utiliser Clever-cloud réside dans l'automatisation, surtout l'automatisation du déploiement de chaque nouvelle version de notre bot.\nEn effet, nous n'avons pas eu besoin d'utiliser d'outils d'intégration continue (CI).\nUne fois Clever-cloud connecté au repository git du projet, un simple _push_ sur la branche _master_ déclenche un redéploiement.\nDans cette étape nous expliquerons commennt déployer notre webhook sur Clever-cloud.\nDepuis le tableau de bord (une fois loggué, et les organisations renseignées), il est possible de créer une nouvelle application.\nPour ce faire, il faut:\n\n- cliquer sur le boutton : \"**create**\"\n  - puis choisir \"**an application**\"\n    - et enfin selectionner le repository du projet à partir du menu déroulant \"**Select your Github repository**\" .\n- Définir le type d'application que représente notre projet en choisissant _**Node**_ parmi la liste proposée.\n- Choisir le nombre d'instances nécessaires.\n- On peut ensuite ajouter une description et une région (de préférence pour l'hébergement), puis cliquer sur \"**CREATE**\" pour lancer la création de notre application sur Clever-cloud.\n- Nous n'avons pas besoin d'_add-on_, nous pouvons donc passer l'étape correspondante et cliquer directement sur _next_.\n- Enfin, il nous est demandé de définir un certain nombre de variables d'environnement.\n  C'est le parfait endroit pour renseigner toutes les valeurs en dur de notre bot comme par exemple le _token de verification_ qui doit rester confidentiel.\n  Il faut finalement cliquer sur _Next_ pour lancer le déploiement de notre application sur le web.\n\nLa vidéo _NodeJS Mongo demo_ résume bien ces différentes étapes de création d'une application sur Clever-cloud:\n[![IMAGE ALT TEXT HERE](https://github.com/Zenika/Zenbot/blob/master/docs/clever_cloud.png)](https://static-assets.cellar.services.clever-cloud.com/website/home/powerful-features-videos/deploy.mp4)\n\nSi tout s'est bien passé, une notification nous averti que le déploiement de notre application a été un succes.\nYay! Notre bot est en ligne 🎉🎉🎉 .\nMais attention ce n'est pas encore fini.\nNous devons encore récupérer l'URL sur laquelle notre bot a été déployé et la renseigner dans la configuration de la plate-forme d'intégration de notre bot (Messenger/Slack) comme vu à l'étape 1.\nL'URL de déploiement est disponible et configurable à partir du menu \"**_Domaine names_**\" de notre application sur le tableau de bord Clever-cloud.\n\nC'est terminé!\nNous pouvons maintenant tester que tout fonctionne correctement en écrivant quelques messages à notre bot depuis Messenger ou bien en utilisant la commandes _/faq_ sur Slack! Et, petite cerise sur le gateau, ils est possible de configurer un message de bienvenu sur Messenger en suivant les instructions de la page [Welcome screen](https://developers.facebook.com/docs/messenger-platform/discovery/welcome-screen/).\n\nPour finir, voici les liens vers les documentations respectives des plateformes [Messenger](https://developers.facebook.com/docs/messenger-platform) et [Slack](https://api.slack.com).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzenika%2Ffaq-slack-bot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzenika%2Ffaq-slack-bot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzenika%2Ffaq-slack-bot/lists"}