Erstellen eines motivierenden Facebook Messenger-Bots mit Node.js.

Ich habe heute Morgen zum Spaß an einem kleinen Nebenprojekt gearbeitet: Ein Messenger-Bot, der meinen Freunden regelmäßig Motivationsnachrichten senden kann.

Das Erstellen eines einfachen Messenger-Bots ist einfach. Es gibt eine Reihe grundlegender Online-Tutorials sowie einige fortgeschrittene, die NLP verwenden, um den Bot intelligenter zu machen. Für meine Zwecke brauchte ich nur einen unkomplizierten Bot, der einige einfache Aufgaben ausführen kann.

Dieser Artikel kann als Tutorial für diejenigen dienen, die mit dem Erstellen ihres ersten Messenger-Bots beginnen möchten.

Die Idee

Ich wollte einen Bot, der meinen Freunden täglich ein Motivationszitat schicken kann. Aus technischer Sicht bedeutete dies, dass der Bot eine Verbindung zu einer externen API herstellte, ein Angebot abrief und es zu einer bestimmten Tageszeit an eine Gruppe von Personen sendete.

Was ich benutzt habe

  • Node.js für meinen Webhook. Sie können eine andere Umgebung verwenden, wenn Sie möchten. Ich persönlich finde das Einrichten von Node.js für ein kleines Projekt wie dieses blitzschnell.
  • Heroku für die Bereitstellung meiner App in der Cloud. Auch hier gibt es andere Möglichkeiten, aber ich finde, dass Heroku für kleine Projekte am einfachsten ist.
  • Meine persönliche Quotes API. Dies ist eine sehr grundlegende API, die ich vor Jahren erstellt habe. Es ermöglicht mir, Angebote aus / zu einer Datenbank abzurufen oder hinzuzufügen. Es hat auch eine Live-Homepage, die zufällige Zitate abruft und sie anzeigt.
  • mLab zum Bereitstellen einer MongoDB-Instanz, um die Benutzerinformationen zu verfolgen, die mein Bot zum Senden von Nachrichten benötigte.

Anfangen

In diesem Handbuch wird davon ausgegangen, dass Sie Node.js und den Heroku Toolbelt auf Ihrem System installiert haben. Ich werde die Details dieser beiden Dinge beschönigen, da ich davon ausgehe, dass der Leser bereits Erfahrung mit Node und Heroku hat.

Als erstes müssen wir unsere Knotenumgebung einrichten. Navigieren Sie zu dem Ordner, in dem Sie das Projekt starten möchten, und führen Sie eine kurze npm-Init aus, um die Grundlagen einzurichten.

Sie müssen Express, Body Parser und Request installieren, da wir sie in Kürze verwenden werden. npm install express body-parser request --save

Damit die Dinge ins Rollen kommen, soll unsere Datei index.js folgendermaßen aussehen:

'use strict'; const express = require ('express'); const bodyParser = require ('body-parser'); const request = require ('request'); const app = express (); app.set ('port', (process.env.PORT || 8000)); app.use (bodyParser.urlencoded ({erweitert: false})); app.use (bodyParser.json ()); // Home app.get ('/', function (req, res) {res.send ('Hallo Welt!');});
// Starten Sie den Server app.listen (app.get ('port'), function () {console.log ('läuft auf Port', app.get ('port'));});

Dies sollte sich für jeden wie zu Hause anfühlen, der zuvor mit Node und Express gearbeitet hat.

Nun zum lustigen Teil. Wenn unsere App auf Heroku läuft (sehr bald), müssen wir sie für Facebook überprüfen. Wenn wir unseren Bot einrichten, werden wir von Facebook aufgefordert, eine Rückruf-URL anzugeben. Sie werden außerdem aufgefordert, ein Bestätigungstoken bereitzustellen, das an unsere URL gesendet wird.

Dies bedeutet, dass wir eine Route einrichten müssen, die wir als Rückruf-URL angeben. In unserer Datei index.js benötigen wir:

app.get ('/ mybot', Funktion (req, res) {if (req.query ['hub.verify_token'] === 'THIS_IS_MY_VERIFICATION_TOKEN') {res.send (req.query ['hub.challenge'] );} res.send ('Falscher Token!');});

Denken Sie an das oben angegebene Token!

Lassen Sie uns dieses süße kleine Ding ganz schnell in die Cloud bringen, bevor wir weiter gehen. Da wir Heroku verwenden, benötigen wir ein Procfile in unserem Verzeichnis mit nur web: node index.js.

Als nächstes wollen wir dieses Projekt in Heroku erstellen und das, was wir bisher haben, vorantreiben. In Ihrem Terminal müssen Sie Folgendes tun:

> git init> heroku create> git add. > git commit -m 'Grundeinstellung'> git push heroku master

Das ist alles für Heroku (vorerst). Wir haben unsere App auf Heroku und es ist Zeit, Facebook dazu zu bringen, mit ihr zu kommunizieren.

Einrichten der Facebook App

Sie müssen eine Facebook-Seite erstellen, um diesen Schritt abzuschließen. Hier können Sie eine neue Facebook-Seite erstellen.

Gehen Sie zu https://developers.facebook.com/apps und erstellen Sie eine neue Anwendung.

Klicken Sie anschließend neben der Messenger-Karte auf Setup.

Das Wichtigste auf der nächsten Seite ist der Abschnitt Webhooks. Klicken Sie auf die Schaltfläche, um einen neuen Webhook einzurichten, und Sie werden folgendermaßen begrüßt:

Der letzte Schritt: Holen Sie sich das Seitenzugriffstoken für Ihre App. Sie finden es über dem Abschnitt Webhooks. Hinweis: Das Seitenzugriffstoken unterscheidet sich von Ihrem Bestätigungstoken. Bewahren Sie Ihr Seitenzugriffstoken sicher auf. wir werden es später brauchen.

Gehen Sie zum Schluss zurück zu Ihrem Terminal und geben Sie Folgendes ein:

curl -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token= ""

Dadurch sendet Ihre Facebook-App Nachrichten.

Ein einfaches Echo

Lassen Sie unseren Bot Nachrichten empfangen und zurücksenden, um zu sehen, ob die Dinge funktionieren.

Wir müssen unserer Node-App eine POST-Route hinzufügen.

const token = " ";
app.post ('/ webhook /', Funktion (req, res) {var messaging_events = req.body.entry [0] .messaging; für (var i = 0; i 
Funktion sendTextMessage (Absender, Text) {var messageData = {text: text}; Anfrage ({url: 'https://graph.facebook.com/v2.6/me/messages', qs: {access_token: token}, Methode: 'POST', json: {Empfänger: {id: Absender}, message: messageData,}}, function (Fehler, Antwort, body) {if (Fehler) {console.log ('Fehler:', Fehler);} else if (response.body.error) {console.log ('Fehler : ', response.body.error);}}); }}

Die Logik hier ist einfach: Wenn eine Nachricht empfangen wird, geben Sie sie mit einem „!“ Zurück.

Mal sehen, ob das funktioniert. Um dies zu testen, gehen Sie zur Facebook-Seite Ihrer App und testen Sie die Schaltfläche "Nachricht senden" (Hinweis: Wenn Sie keine Schaltfläche sehen, müssen Sie sie für Ihre Seite einrichten).

Es klappt!

Was haben wir bisher gelernt?

  1. Wenn eine Nachricht empfangen wird, empfängt unsere Node-App eine POST-Anfrage mit den Nachrichtenereignissen, die unter anderem den Text der Nachricht und eine Absender-ID enthalten (die wir mit einem einfachen Konsolenprotokoll überprüfen können).
  2. Um etwas zurückzusenden, müssen wir eine POST-Anfrage an eine bestimmte URL mit Parametern wie unserem Zugriffstoken, der Empfänger-ID und dem Nachrichtentext senden.

Dies sind gute Informationen für unseren nächsten Schritt.

Benutzer im Auge behalten

Die Tatsache, dass wir Empfänger-IDs in der Anfrage erhalten, ist ein gutes Zeichen. Wenn ich einen Bot erstellen möchte, der täglich eine Nachricht an mehrere Benutzer sendet, müssen wir diese IDs verfolgen.

Ich habe mLab verwendet, um die Empfänger-IDs zu verfolgen. Sie können Ihren bevorzugten Datenbank-Hosting-Service verwenden, wenn Sie möchten. Ich möchte nicht auf die Details eingehen, aber ich werde meinen Code hier als Referenz veröffentlichen.

const mongo = require ('mongodb'). MongoClient;
Funktion addUserToDB (Absender) {
var mLabUri = "mongodb: //" + process.env.userId + ":" + process.env.userPass + "@ ds157641.mlab.com: 57641 / motivate-bot";
mongo.connect (mLabUri, function (err, client) {if (err) {throw err; res.end (err);} else {var db = client.db ("motivate-bot"); db.collection (" Empfänger "). findOne ({" Absender ": Absender}, Funktion (err, Ergebnis) {if (Ergebnis === null) {// Benutzer nicht gefunden; jetzt hinzufügen var data = {" Absender ": Absender}; db .collection ("Empfänger"). insertOne (Daten, Funktion (err, res) {if (err) {console.log (err);} if (res) {console.log (res);} client.close () ;});} else {// Benutzer gefunden client.close ();}});}}); }}

Diese Funktion überprüft die Datenbank, um festzustellen, ob der Absender zuvor gesehen wurde. Wenn nicht, wird es hinzugefügt.

Wir möchten jetzt nicht, dass diese Funktion jedes Mal aufgerufen wird, wenn der Benutzer uns eine Nachricht sendet. Vielleicht sollten wir uns an den Benutzer erinnern, wenn er so etwas wie "Start" hat.

Lassen Sie uns unsere POST-Funktion ein wenig ändern,

app.post ('/ webhook /', Funktion (req, res) {var messaging_events = req.body.entry [0] .messaging; für (var i = 0; i 

Wenn Sie diese Logik verstanden haben, werden Sie leicht verstehen, dass wir Benutzer auch löschen können, wenn sie danach fragen. Unsere letzte Funktion sollte folgendermaßen aussehen:

app.post ('/ webhook /', Funktion (req, res) {var messaging_events = req.body.entry [0] .messaging; für (var i = 0; i 

Angebote einholen

Ich erwähnte, dass ich meine persönliche Quotes-API verwenden würde. Mit dieser API ein zufälliges Angebot zu erhalten ist einfach - Sie müssen nur eine GET-Anfrage stellen. Ich habe dies mit dem Anforderungsmodul für Node gemacht.

Funktion getQuote (Rückruf) {request ({url: "https://getquote.herokuapp.com/getmotivational", Methode: "GET"}, Funktion (Fehler, Antwort, Text) {if (Fehler) {console.log ( "Fehler:", Fehler);} else if (response.body.error) {console.log ("Fehler:", response.body.error);}
     var parsedBody = JSON.parse (body);
var quote = "" + parsedBody.data.text + "-" + parsedBody.data.author; Rückruf (Zitat); }); }}

Sie können jede der anderen APIs verwenden, wenn Sie dies wünschen. Ich mag meine, weil ich die Zitate mag, die ich in meiner Datenbank habe.

Nachrichten regelmäßig senden

Wir haben einen Server, wir haben eine Sammlung von Empfängern, wir haben eine Möglichkeit, Angebote zu erhalten. Das einzige, was Sie noch tun müssen, ist, unseren Bot einmal täglich ein Angebot an alle abonnierten Empfänger senden zu lassen.

Eine einfache Lösung ist die Verwendung von setInterval in JavaScript

Bevor wir so etwas machen, gibt es ein Problem. Die Messenger-Plattform von Facebook verfügt über ein 24-Stunden-Nachrichtenfenster. Dies bedeutet, dass unser Bot bis zu 24 Stunden nach seiner Nachricht eine Nachricht an einen Benutzer senden kann. Danach muss der Benutzer eine weitere Nachricht an unseren Bot senden, um eine Nachricht zu erhalten. Das wollen wir nicht.

Um dies zu erreichen, müssen wir Subscription Messaging einrichten. Sie müssen den Anweisungen von Facebook folgen und eine Anfrage senden, um Abonnementnachrichten zuzulassen. Beachten Sie, dass die Genehmigung bis zu 5 Werktage dauern kann.

Angenommen, Sie haben Subscription Messaging eingerichtet, können Sie Nachrichten an Benutzer außerhalb des 24-Stunden-Fensters senden, indem Sie Ihrer Nachricht ein NON_PROMOTIONAL_SUBSCRIPTION-Nachrichtentag hinzufügen.

Dies bedeutet, dass unsere sendTextMessage-Funktion jetzt folgendermaßen aussehen sollte:

Funktion sendTextMessage (Absender, Text) {var messageData = {text: text}; Anfrage ({url: "https://graph.facebook.com/v2.6/me/messages", qs: {access_token: token}, Methode: "POST", json: {Empfänger: {id: Absender}, message: messageData, tag: "NON_PROMOTIONAL_SUBSCRIPTION"}}, Funktion (Fehler, Antwort, Text) {if (Fehler) {console.log ("Fehler:", Fehler);} else if (response.body.error) {console .log ("Fehler:", response.body.error);}}); }}

Der einzige Unterschied ist das Tag in der JSON-Nutzlast.

Bisher haben wir Folgendes getan:

  • Erstellt und bereitgestellt eine Node-App
  • Erstellt einen einfachen Bot, der Antworten senden kann
  • Erstellt eine Funktion, mit der ein zufälliges Motivationszitat abgerufen werden kann
  • Verbunden mit einer Datenbank, um abonnierte Benutzer zu verfolgen

Folgendes werden wir als nächstes tun:

  • Senden Sie jedem abonnierten Benutzer ein Motivationsangebot
  • Verwenden Sie setInterval, um regelmäßig Angebote zu senden

Beides ist einfach: Zuerst gehen wir einfach die Liste der abonnierten Benutzer durch und senden jedem von ihnen ein Angebot. Dann implementieren wir setInterval

Funktion sendDailyMessage () {getQuote (Funktion (Zitat) {
var mLabUri = "mongodb: //" + process.env.userId + ":" + process.env.userPass + "@ ds157641.mlab.com: 57641 / motivate-bot";
mongo.connect (mLabUri, function (err, client) {if (err) {throw err; res.end (err);} else {var db = client.db ("motivate-bot"); db.collection (" Empfänger "). find (). toArray (Funktion (err, docs) {für (var i = 0; i 
setInterval (sendDailyMessage, 60000); // 1 Minute zum Testen

Und ... voila.

Unser Bot sollte jede Minute ein neues Motivationszitat an alle Benutzer senden. Natürlich möchten wir dies auf 24 Stunden (86400000 Millisekunden) ändern, wenn wir sicher sind, dass es funktioniert (ich habe meine getestet, es hat funktioniert).

Dieses Tutorial war nur eine einfache Einführung. Messenger-Bots können viel mehr als nur Nachrichten senden. Vielleicht spiele ich mehr mit ihnen herum und schreibe in Zukunft ein weiteres Tutorial. In der Zwischenzeit werde ich meine Freunde bitten, meinen Bot zu abonnieren.

- -

Ein Hinweis zu Heroku: Wenn Sie den kostenlosen Plan haben, wird Ihr Server nach einer Weile in den Ruhezustand versetzt, wenn keine Anfragen an ihn gestellt werden. Da wir möchten, dass unser Bot wach bleibt, müssen wir diese Einschränkung umgehen. Es gibt viele Möglichkeiten, dies zu tun, aber die einfachste (meiner Meinung nach) besteht darin, ab und zu eine eigene URL zu pingen.

const http = require ("http"); setInterval (function () {http.get ("http://yours.herokuapp.com");}, 300000); // 5 Minuten