Chatbot-Entwicklung für Facebook Messenger auf node.js

Das Material, dessen Übersetzung wir Ihnen heute vorstellen, ist der Entwicklung eines Chat-Bots für Facebook Messenger gewidmet. Ein Bot namens Aww Bot, der mit Benutzern kommuniziert, sendet ihnen Bilder von niedlichen Katzen und Hunden.



Erste Schritte


Beginnen wir mit der Erstellung einer Seite auf Facebook, indem wir die erforderlichen Felder ausfüllen. Diese Seite ist für den Bot. Darüber hinaus erstellen wir eine Facebook-Anwendung. Anschließend verbinden wir auf der Seite Produkt hinzufügen das Messenger-Produkt mit der Anwendung. Als nächstes befinden wir uns auf der Seite mit den Messenger-Einstellungen. Hier müssen Sie den Abschnitt Token-Generierung finden - wählen Sie die Bot-Seite in der Seitenliste aus. Danach werden wir nach Berechtigungen gefragt und ein Zugriffstoken erstellt. Der Bot verwendet dieses Token, um die Facebook Messenger-API aufzurufen, mit der er mit Benutzern kommunizieren kann.

Webserver-Setup


Wir werden node.js und express.js verwenden, um einen HTTP-Server zu erstellen. Führen Sie den folgenden Befehl aus:

npm install express body-parser request config --save 

Fügen Sie index.js den folgenden Code index.js , mit dem Sie einen einfachen HTTP-Server erstellen können:

 'use strict'; let express = require('express'),   bodyParser = require('body-parser'),   app = express(); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.listen(8989, () => console.log('Example app listening on port 8989!')); app.get('/', (req, res) => res.send('Hello World!')); 

Wenn Sie nun den Server starten und Ihren Browser unter http://127.0.0.1:8989 , wird eine Seite mit der Antwort des Servers angezeigt - Hello World! .

HTTPS und die lokale Entwicklungsumgebung


Bevor wir zur Webhook-Technologie übergehen, müssen wir HTTPS für die Entwicklungsumgebung konfigurieren. Der Messenger akzeptiert nicht die Webhook-Adresse, die zum Senden von Benachrichtigungen an unseren Server verwendet wird, wenn Sie ein selbstsigniertes SSL-Zertifikat verwenden. Ein kostenloses Zertifikat ist bei Let's Encrypt erhältlich . Hier können Sie jedoch ein Zertifikat nur für eine Domain und nicht für eine IP-Adresse erhalten. Wir werden den ngrok- Dienst verwenden, mit dem Sie den Zugriff auf den lokalen Server über eine öffentliche URL organisieren können, die HTTPS verwendet.

Ngrok-Setup


ngrok einfach. Sie müssen nur das komprimierte Archiv von der Projektsite herunterladen, entpacken und den folgenden Befehl ausführen:

 ./ngrok http 80 

Denken Sie daran, Port 80 in den WAN-Einstellungen Ihres Routers auf 8989 umzuleiten. Infolgedessen erstellt ngrok öffentliche HTTP- und HTTPS-Adressen für den lokalen Server.

Arbeiten mit Webhook-Benachrichtigungen


Der Messenger verwendet die Webhook-Technologie zur Authentifizierung und zum Senden von Benachrichtigungen über Ereignisse an Ihre Anwendung. Aus programmtechnischer Sicht läuft alles auf die üblichen Rückruffunktionen für die Verarbeitung von HTTP-Anforderungen hinaus, die Daten zu Ereignissen empfangen, z. B. Nachrichten, die vom Chatbot empfangen werden. Um GET- und POST-Anforderungen zu analysieren, verwenden wir das body-parser Modul.

Fügen Sie der Anwendung die folgende Route hinzu. Es wird für die Verarbeitung von Webhook-Überprüfungsanforderungen benötigt.

 //   GET-  webhook app.get('/webhook', (req, res) => {   //  .    ,       let VERIFY_TOKEN = "SOMETHING_RANDOM";   //      let mode = req.query['hub.mode'];   let token = req.query['hub.verify_token'];   let challenge = req.query['hub.challenge'];   // ,     mode  token   if (mode && token) {       //   mode  token       if (mode === 'subscribe' && token === VERIFY_TOKEN) {           //   challenge             console.log('WEBHOOK_VERIFIED');           res.status(200).send(challenge);       } else {           //   '403 Forbidden'                res.sendStatus(403);       }   } }); 

Jetzt müssen Sie die Messenger-Einstellungen öffnen, dort den Abschnitt Webhooks finden und die Anwendungsintegration mit Webhook-Benachrichtigungen konfigurieren. Geben Sie auf der Einstellungsseite im Feld Rückruf-URL unsere von ngrok empfangene HTTPS-URL ein. Das Verifikationstoken (das im Code vorhanden ist und eine von uns erstellte zufällige Zeichenfolge darstellt) muss in das Feld Verifikationstoken eingefügt werden. Danach sollten Sie in der Lage sein, die Einstellungen zu überprüfen und zu speichern, indem Sie auf die Schaltfläche Überprüfen und Speichern klicken, wenn Ihre URL für die Verarbeitung von Webhook-Benachrichtigungen verfügbar ist und das Überprüfungstoken mit der im Code übereinstimmt.


Konfigurieren Sie das Token und die URL für die Anwendung, um Webhook-Benachrichtigungen zu erhalten

Wählen Sie nach dem Speichern Ihre Seite aus der Dropdown-Liste aus und abonnieren Sie Seitenereignisse.

Erstellen Sie nun eine POST-Route, um POST-Ereignisse vom Messenger zu verarbeiten. Fügen Sie der Anwendung den folgenden Code hinzu.

 //     webhook app.post('/webhook', (req, res) => {   let body = req.body;   if (body.object === 'page') {       // ,               body.entry.forEach(function(entry) {           //  entry.messaging  ,            //     ,    0           let webhook_event = entry.messaging[0];           console.log(webhook_event);           //  PSID            let sender_psid = webhook_event.sender.id;           console.log('Sender PSID: ' + sender_psid);           //  ,  , message   postback,           //     -           if (webhook_event.message) {               console.log(webhook_event.message)           } else if (webhook_event.postback) {               console.log(webhook_event.postback)           }       });       //  '200 OK'            res.status(200).send('EVENT_RECEIVED');   } else {       //  '404 Not Found',      ,           res.sendStatus(404);   } }); 

Wir haben die Anwendung so eingerichtet, dass sie zwei Arten von Ereignissen behandelt - message und postback . Öffnen Sie den Messenger und senden Sie eine Nachricht an die Bot-Seite, um die Funktion des Webhook-Benachrichtigungsmechanismus zu überprüfen. Wenn alles ordnungsgemäß funktioniert, werden die PSID, die Ereignisinformationen und der Nachrichteninhalt des Absenders protokolliert. Jetzt schreiben wir Handlerfunktionen für die Ereignisse, die für uns von Interesse sind.

 //   message const handleMessage = (sender_psid, received_message) => {   let response;   if (received_message.text) {   } } //   postback const handlePostback = (sender_psid, received_postback) => {   let response;   //    postback   let payload = received_postback.payload;   if(payload === 'GET_STARTED'){   } } 

Die handleMessage() -Methode ist für die Verarbeitung eingehender Nachrichten verantwortlich, und die handlePostback() -Methode ist für die Verarbeitung eingehender postback Ereignisse verantwortlich. Aktualisieren Sie Ihren vorhandenen Code, indem Sie diesen Methoden Aufrufe hinzufügen:

 //   //     - if (webhook_event.message) {   handleMessage(sender_psid, webhook_event.message); } else if (webhook_event.postback) {   handlePostback(sender_psid, webhook_event.postback); } 

Wenn wir nun message oder postback empfangen, werden die Daten zusammen mit der PSID des Absenders an die entsprechenden Handler übertragen.

Konfigurieren des Begrüßungsbildschirms und der Postback-Ereignisse zum Starten eines Dialogs mit dem Bot


Wenn ein neuer Benutzer ein Gespräch mit dem Bot beginnt, wird im Chat-Fenster die Schaltfläche Erste Schritte angezeigt. Sie können Ihr eigenes Postback-Ereignis für diese Situation konfigurieren. Legen Sie beispielsweise eine Nachricht für einen Benutzer fest, die den Bot beschreibt und wie er mit ihm kommuniziert. Führen Sie diesen curl Befehl im Terminal aus, um Ihre eigene Begrüßung zu konfigurieren:

 curl -X POST -H "Content-Type: application/json" -d '{ "greeting": [   {     "locale":"default",     "text":"Hello {{user_first_name}}! Are you ready to see the cutests cats and dogs"   } ] }' "https://graph.facebook.com/v2.6/me/messenger_profile?access_token=YOUR_PAGE_ACCESS_TOKEN" 

Wir haben Aww Bot so eingerichtet, dass eine Meldung angezeigt wird, in der der Benutzer gefragt wird, ob er bereit ist, die süßesten Katzen und Hunde zu sehen. Führen Sie diesen Befehl im Terminal aus, um das Postback-Ereignis zu konfigurieren:

 curl -X POST -H "Content-Type: application/json" -d '{ "get_started": {"payload": "GET_STARTED"} }' "https://graph.facebook.com/v2.6/me/messenger_profile?access_token=YOUR_PAGE_ACCESS_TOKEN" 

So sieht die Chat-Sitzung mit dem Bot aus.


Erste Schritte Bildschirm

Anwendungssetup


Wir werden das Konfigurationsmodul npm verwenden, um das Seitenzugriffstoken in einer separaten Konfigurationsdatei zu speichern. Erstellen Sie das config in unserem Projekt und die Datei default.json darin. In dieser Datei müssen Sie das Zugriffstoken zur Seite hinzufügen und diese Datei in .gitignore .

 { "facebook": {   "page": {     "access_token": "PAGE_ACCESS_TOKEN"   } } } 

Wir erhalten das Seitenzugriffstoken in der callSendAPI() -Methode mit dem config.get('facebook.page.access_token') .

Behandlung eines Startereignisses


Hier ist der Code zur Behandlung von Startereignissen.

 const handlePostback = (sender_psid, received_postback) => {   let response;   //   postback-   let payload = received_postback.payload;   if(payload === 'GET_STARTED'){       response = askTemplate('Are you a Cat or Dog Person?');       callSendAPI(sender_psid, response);   } } 

Erstellen wir die askTemplate() -Methode, die ein korrekt vorbereitetes askTemplate() für die Messenger-API askTemplate() . Die callSendAPI() -Methode sendet eine Nachricht an den Benutzer. Fügen Sie der Anwendung die folgenden Methoden hinzu:

 const askTemplate = (text) => {   return {       "attachment":{           "type":"template",           "payload":{               "template_type":"button",               "text": text,               "buttons":[                   {                       "type":"postback",                       "title":"Cats",                       "payload":"CAT_PICS"                   },                   {                       "type":"postback",                       "title":"Dogs",                       "payload":"DOG_PICS"                   }               ]           }       }   } } //     API Send const callSendAPI = (sender_psid, response, cb = null) => {   //      let request_body = {       "recipient": {           "id": sender_psid       },       "message": response   };   //  HTTP-  Messenger Platform   request({       "uri": "https://graph.facebook.com/v2.6/me/messages",       "qs": { "access_token": config.get('facebook.page.access_token') },       "method": "POST",       "json": request_body   }, (err, res, body) => {       if (!err) {           if(cb){               cb();           }       } else {           console.error("Unable to send message:" + err);       }   }); } 

Wir senden dem Benutzer eine Nachricht mit zwei Schaltflächen und Text. Wenn der Benutzer durch Klicken auf die entsprechende Schaltfläche auswählt, was er benötigt, wird eine Anfrage mit den Daten des postback Ereignisses an unsere Webhook-Adresse gesendet und von uns verarbeitet.


Der Benutzer wird aufgefordert, den Bildtyp auszuwählen, der ihn interessiert.

Behandlung von benutzerdefinierten Postback-Ereignissen


Aktualisieren Sie den Funktionscode des Postback-Ereignishandlers:

 const handlePostback = (sender_psid, received_postback) => {   let response;   //   postback-   let payload = received_postback.payload;   //  ,       if (payload === 'CAT_PICS') {       response = imageTemplate('cats', sender_psid);       callSendAPI(sender_psid, response, function(){           callSendAPI(sender_psid, askTemplate('Show me more'));       });   } else if (payload === 'DOG_PICS') {       response = imageTemplate('dogs', sender_psid);       callSendAPI(sender_psid, response, function(){           callSendAPI(sender_psid, askTemplate('Show me more'));       });   } else if(payload === 'GET_STARTED'){       response = askTemplate('Are you a Cat or Dog Person?');       callSendAPI(sender_psid, response);   }   //   } 

Wenn der Benutzer auf die Schaltfläche Cats klickt, wird eine Anfrage mit einem postback Ereignis mit CAT_PICS Daten an unsere Adresse CAT_PICS , die zur Verarbeitung von Webhook-Benachrichtigungen verwendet wird. Wenn Sie die Option Dogs postback wird ein postback Ereignis mit DOG_PICS Daten DOG_PICS . Wir haben dem System eine weitere Methode hinzugefügt, imageTemplate() , die eine Nachricht zurückgibt, die einen Link zu einem Bild einer Katze oder eines Hundes enthält.

Erstellen Sie eine einfache API, die Bildverknüpfungen zurückgibt


Wir werden eine einfache API schreiben, um Links zu Bildern von Katzen oder Hunden zurückzugeben, die in Nachrichten verwendet werden, die der Bot an Benutzer sendet. Erstellen Sie eine pics.js Datei und fügen Sie den folgenden Code hinzu:

 module.exports = {   cats : [       'https://i.imgur.com/Qbg7CeM.jpg',       'https://i.imgur.com/nUzkpJY.jpg',       'https://i.imgur.com/NpDcKph.jpg',       'https://i.imgur.com/oJtSDaO.jpg',       'https://i.redd.it/82ajpsrd17111.jpg',       'https://i.redd.it/00km1d2rt0111.jpg',       'https://i.redd.it/rdbavhp0y7111.jpg',       'https://i.redd.it/5hn3mg0n98111.jpg',       'https://i.redd.it/d23pb8mta6111.jpg',       'https://i.redd.it/d2gyrwgy7oz01.jpg',       'https://i.redd.it/z4sgl84q72z01.jpg',       'https://i.redd.it/wvykzo8n1cy01.jpg'   ],   dogs : [       'https://i.redd.it/6tjihi2qe7111.jpg',       'https://i.imgur.com/etRCs56.jpg',       'https://i.redd.it/nibw50f8y4111.jpg',       'https://i.redd.it/izcvnvj1o7111.jpg',       'https://i.redd.it/eqs1g9dldz011.jpg',       'https://i.redd.it/civ9dnu9u1111.jpg',       'https://i.redd.it/kk03qwclkp011.jpg',       'https://i.redd.it/2694pupjne011.jpg',       'https://i.redd.it/qk49ls5y6oy01.jpg',       'https://i.imgur.com/oM3mKgB.jpg',       'https://i.redd.it/8kx2riaulux01.jpg'   ] }; 

Verbinden Sie es nun in der Anwendung.

 images = require('./pics'); 

Fügen Sie dem Code, der zum Erstellen einer Nachricht mit einem Link zum Bild verwendet wird, die folgende Methode hinzu.

 const = imageTemplate(type, sender_id) => {   return {       "attachment":{           "type":"image",           "payload":{               "url": getImage(type, sender_id),               "is_reusable":true           }       }   } } 

Während der Benutzerinteraktion mit dem Bot werden Bilder nacheinander aus dem Array extrahiert und als Bot-Antworten an den Benutzer gesendet. Nach dem Senden des letzten Bildes kehren wir an den Anfang der Liste zurück.

Wir fügen dem Projekt den folgenden Code hinzu, mit dem Daten über Benutzer gespeichert und verarbeitet werden sollen, die mit dem Bot kommunizieren.

 let users = {}; const = getImage(type, sender_id) => {   //       -     if(users[sender_id] === undefined){       users = Object.assign({           [sender_id] : {               'cats_count' : 0,               'dogs_count' : 0           }       }, users);   }   let count = images[type].length, //            user = users[sender_id], // ,         user_type_count = user[type+'_count'];   //          let updated_user = {       [sender_id] : Object.assign(user, {           [type+'_count'] : count === user_type_count + 1 ? 0 : user_type_count + 1       })   };   //      users = Object.assign(users, updated_user);   console.log(users);   return images[type][user_type_count]; } 

Wir speichern die PSID jedes Benutzers, der mit dem Bot kommuniziert, als Schlüssel im users . Wenn noch kein Benutzerdatensatz vorhanden ist, erstellen Sie einen neuen Datensatz. Wir aktualisieren die Bildnummerninformationen jedes Mal, wenn ein Benutzer ein Bild einer Katze oder eines Hundes anfordert. Dann geben wir den absoluten Pfad zu dem Bild zurück, das in der Nachrichtenvorlage verwendet wird. Als nächstes senden wir eine Nachricht mit dem Bild in Form einer Antwort auf das postback Ereignis, das generiert wird, wenn der Benutzer den postback auswählt, der ihn interessiert.

 //  ,    postback- if (payload === 'CAT_PICS') {   response = imageTemplate('cats', sender_psid);   callSendAPI(sender_psid, response, function(){       callSendAPI(sender_psid, askTemplate('Show me more'));   }); } else if (payload === 'DOG_PICS') {   response = imageTemplate('dogs', sender_psid);   callSendAPI(sender_psid, response, function(){       callSendAPI(sender_psid, askTemplate('Show me more'));   }); } else if(payload === 'GET_STARTED'){   response = askTemplate('Are you a Cat or Dog Person?');   callSendAPI(sender_psid, response); } 

Darüber hinaus übergeben wir nach dem Senden des Bildes eine Rückruffunktion an die callSendAPI() -Methode, um dem Benutzer eine neue Frage zu den Bildern zu senden, an denen er interessiert ist. Bei Erfolg rufen wir diese Funktion auf. Dieses Arbeitsschema ermöglicht es dem Benutzer, unter Berücksichtigung der Asynchronität der Rückruffunktionen eine Nachricht mit einer Frage zum nächsten Bild zu empfangen, nachdem ihm eine Nachricht mit dem zuvor angeforderten Bild gesendet wurde.


Kommunikation mit dem Bot

Zusammenfassung


Hier ist das Repository für dieses Projekt. Dort finden Sie in der Datei readme.md Anweisungen zum Installieren und Konfigurieren des Bots. Damit andere Personen mit Ihrem Bot chatten können, muss Ihre Facebook-Anwendung genehmigt werden. Bis zu diesem Zeitpunkt können nur Administratoren und Tester Ihrer Anwendung mit dem Bot sprechen. Hier ist ein Video, das den Prozess der Kommunikation mit dem Bot demonstriert.

Liebe Leser! Planen Sie Bots für Facebook Messenger zu erstellen?

Source: https://habr.com/ru/post/de414081/


All Articles