Web-Hooks von Dialogflow: Lokale Entwicklung und Bereitstellung für Cloud-Funktionen

Als unser Team bei LINE HACK 2018 mit dem Aufbau des Nila-Chatbots begann, wussten wir genau wie Jon Snow, wie man einen Web-Hook erstellt. Einige von uns hatten einige Erfahrungen mit Firebase und dem Schreiben von Cloud-Funktionen. Daher gingen wir davon aus, dass dies recht einfach sein würde, insbesondere, als wir den Inline-Editor fanden. Am Ende erstellten wir jedoch die erste Version vollständig auf Glitch, einer Live-Umgebung zum Ausführen von Node .js Apps. Glitch eignet sich hervorragend zum Lernen, aber wir hätten unser Leben einfacher gestalten können, indem wir eine lokale Entwicklungsumgebung eingerichtet hätten.

In diesem Artikel wird erläutert, wie Sie einen Web-Hook erstellen, indem Sie ihn lokal entwickeln und in der Cloud bereitstellen. Diese Tipps und Tricks machen die Entwicklung von Web Hooks schneller, praktischer und sicherer:

  • Schneller - lokal ausführen, nur bei Bedarf bereitstellen
  • Praktisch - Debuggen Sie Ihre Anwendung mit Live-Anfragen von Ihrem Web-Hook
  • Sicherer fusseln und automatisch vervollständigen mit Ihrem Lieblingseditor

1. Beginnen Sie mit einer Vorlage und führen Sie sie lokal aus

Während der Fokus in diesem Artikel auf Dialogflow-Web-Hooks liegt, vermute ich, dass diese Schritte für die Entwicklung von Web-Hooks identisch sind. Wenn Sie Dialogflow verwenden, können Sie zur Erfüllung mit dem Inline-Editor beginnen. Das erste, was Sie tun müssen, ist, diesen Code zu erfassen und ihn so zu ändern, dass er lokal ausgeführt wird.

In simpleServer.js habe ich den Dialogflow-Erfüllungscode aus dem Inline-Editor genommen, den Firebase-spezifischen Code entfernt und Express hinzugefügt, um den Web-Hook zu bedienen. Sie benötigen ein package.json mit den Abhängigkeiten für Express, Dialogflow-Fulfillment und Actions-on-Google. Führen Sie den Web-Hook über den Knoten simpleServer.js aus und öffnen Sie dann http: // localhost: 8080 /, um zu überprüfen, ob er funktioniert.

2. Verwenden Sie ngrok, um lokales http für öffentliches https bereitzustellen

Ngrok ist ein kostenloser Dienst, mit dem Sie eine öffentliche sichere https-URL zu Ihrem lokalen Webserver erhalten. Sie können ngrok global installieren (Binärdatei herunterladen oder npm global installieren), aber ich bevorzuge die Installation als Dev-Abhängigkeit:

npm install ngrok --save-dev

Und ändern Sie dann Ihre package.json:

  ...
  "Skripte": {
    Tunnel: ngrok http 8080
  },

Wenn Sie jetzt eine https-URL für Ihre lokale Entwicklerumgebung erstellen möchten, verwenden Sie einfach npm run tunnel. Ngrok wird ausgeführt und eine https-URL erstellt:

Ausführen von ngrok, um eine öffentliche https-URL für Ihren lokalen Server abzurufen

Jetzt können Sie die https-URL unter "Weiterleitung" (rot hervorgehoben) als Web-Hook für Ihre Erfüllung in Dialogflow kopieren:

Konfigurieren Sie die Erfüllung von Dialogflow so, dass eine ngrok-Weiterleitungs-URL verwendet wird

An dieser Stelle würde ich testen, ob alles funktioniert, indem ich in der Testkonsole von Dialogflow ein „Hallo“ sende:

Ich bevorzuge die Installation als Entwicklungsabhängigkeit, weil ein anderer Entwickler, der dem Team beitritt, keine zusätzliche Installation benötigt. Er kann einfach npm run tunnel verwenden, um seine https-URL zu erstellen.

Sie können ngrok mit Strg-C beenden (und die öffentliche URL wird nicht mehr angezeigt). Bei jedem Neustart von ngrok erhalten Sie eine neue URL. Dies bedeutet, dass Sie die URL in der Dialogflow-Konsole aktualisieren müssen. Eine Möglichkeit, dies zu umgehen, besteht darin, ein Upgrade auf einen der kostenpflichtigen Pläne von ngrok durchzuführen.

3. Neuladen (nodemon) und Debuggen (VS Code)

Zu diesem Zeitpunkt haben Sie eine öffentliche URL, die den gesamten Datenverkehr auf unseren lokalen Computer leitet, auf dem eine grundlegende Dialogflow-Vorlage ausgeführt wird. Wir werden den Code bearbeiten und die Änderungen sofort in unserem Web-Hook sehen wollen (z. B. über den Dialogflow-Simulator).

Nodemon ist der beste Freund von Node.j und startet den Server neu, sobald er Änderungen feststellt. Wie ngrok installiere ich es als Entwicklungsabhängigkeit:

npm installiere nodemon --save-dev

Und ändern Sie Ihre package.json-Skripte erneut:

  "Skripte": {
    "dev": "nodemon --inspect simpleServer.js",
    Tunnel: ngrok http 8080
  },

Dann starte deine Entwicklungsumgebung mit npm run dev.

Das Argument --inspect aktiviert den Debugger. In VS Code können Sie eine Debug-Konfiguration erstellen, die mit nodemon wie folgt funktioniert:

  1. Wählen Sie im Menü "Debuggen" die Option "Konfigurationen öffnen", um die Datei launch.json zu öffnen.
  2. Verwenden Sie die Schaltfläche "Konfiguration hinzufügen ...", um eine neue Debug-Konfiguration für "Node.js: Attach" hinzuzufügen. Die resultierende Konfiguration sollte folgendermaßen aussehen:
"Konfigurationen": [
  {
    "Typ": "Knoten",
    "request": "attach",
    "name": "Attach",
    "port": 9229
  }
]

Um dies zu testen, drücken Sie F5, um das Debuggen zu starten (im Terminal sollte Debugger angezeigt werden). Platzieren Sie dann einen Haltepunkt in Ihrem welcome () Agent. Rufen Sie die Dialogflow-Testkonsole auf und sagen Sie erneut "Hallo". Der Debugger stoppt die Ausführung an Ihrem Haltepunkt.

4. Codestil (optional)

Während wir VS Code einrichten, ist es möglicherweise ein guter Zeitpunkt, einen Linter einzurichten. Ich verwende gern den JavaScript-Standardstil, weil er einfach ist. Ich mag nicht 100% der Regeln, aber er ist nah genug und ich mag die Tatsache, dass er ein fester Stil ist, so dass es keine zeitaufwändige Auseinandersetzung mit ESLint gibt Optionen. Es ist auch einfach zu installieren:

npm install standard --save-dev

Fügen Sie Ihrem package.json einen lint-Befehl hinzu:

"Skripte": {
    ...
    "fussel": "standard"
  },

Dann können Sie Ihren Code mit npm run lint überprüfen oder alle Fehler mit npm run lint - --fix beheben.

Wahrscheinlich möchten Sie die Korrekturfunktion jedoch in Ihrem Editor. VS Code hat eine Erweiterung für Standard. Nachdem Sie dies installiert haben, fügen Sie {"key": "cmd + l", "command": "standard.executeAutofix"} zu Ihrer keybindings.json hinzu und ändern Sie cmd + l für jede Tastenkombination, die Sie verwenden möchten. Jetzt können Sie diese Verknüpfung drücken, um Ihren Code im Standardstil zu halten. :)

5. (a) Bereitstellung in Cloud-Funktionen für Firebase

Nachdem wir uns in Schritt 1 von den Cloud-Funktionen verabschiedet haben, müssen wir zur Bereitstellung zurückkehren. Denken Sie daran, dass unser ursprünglicher Cloud-Funktionscode folgendermaßen aussah:

exports.dialogflowFirebaseFulfillment =
    functions.https.onRequest ((Anfrage, Antwort) => {...})

Es stellt sich heraus, dass eine Express-App auch eine Funktion ist, die eine Anfrage / Antwort entgegennimmt, sodass sie die Cloud-Funktionsanforderungen für (Anfrage, Antwort) => {...} erfüllt.

Daher können wir unsere vorhandenen simpleServer.js in server.js und app.js aufteilen. Die Datei app.js enthält unsere Anwendung, die entweder auf Node.js oder Cloud-Funktionen ausgeführt werden kann.

Ausführen einer Express-App über Cloud-Funktionen

Diese Architektur gibt uns die Möglichkeit, bei der Entwicklung lokal mit ngrok und node zu arbeiten und Cloud Functions für die Produktion bereitzustellen.

Das Ergebnis:

Vergessen Sie nicht, die Abhängigkeiten für Firebase zu installieren: npm install firebase-functions firebase-admin --save.

Als nächstes wird der Einsatz…

Wenn Sie nicht mit der Bereitstellung von Cloud-Funktionen vertraut sind, können Sie die Firebase-Dokumentation lesen.

Grundlagen:

  1. Installieren Sie die Firebase-CLI: npm install -g firebase-tools @ latest
  2. Erstellen Sie firebase.json mit:
    {"functions": {"source": ".", "predeploy": ["npm run lint"]}}
  3. Führen Sie firebase aus. Verwenden Sie --add in Ihrem Projektordner, um Ihr Firebase-Projekt auszuwählen und einen Alias ​​zuzuweisen.
  4. Bearbeiten Sie Ihre package.json so, dass das "main" -Skript auf "cloudFuncs.js" verweist:
    "main": "cloudFuncs.js",
  5. Wenn Sie Node 8 verwenden möchten (wahrscheinlich auch!), Fügen Sie dies ebenfalls zu package.json hinzu:
    "engines": {"node": "8"},
  6. Versuchen Sie bereitzustellen: firebase deploy - nur Funktionen
Stellen Sie einen Web-Hook für Cloud-Funktionen in Firebase bereit

Wenn die Bereitstellung erfolgreich abgeschlossen wurde, können Sie den Testendpunkt in Ihrem Browser unter folgender Adresse öffnen: https: // us-central1- [yourprojectid] .cloudfunctions.net / app / (Beachten Sie, dass der abschließende Schrägstrich / für den Routenabgleich von Express erforderlich ist).

Die Web-Hook-URL lautet https: // us-central1- [yourprojectid] .cloudfunctions.net / app / dialogflow.

Fügen Sie schließlich Ihrem package.json ein Bereitstellungsskript hinzu, sodass Sie npm run deploy-cf ausführen können, um es jederzeit in Firebase bereitzustellen:

  "Skripte": {
    ...
    "deploy-cf": "firebase deploy --only functions"
  },

Lokale Node.js vs Cloud-Funktionen

  • Umgebungsvariablen müssen über den Befehl firebase festgelegt werden. Beispiel:
    Firebase-Funktionen: config: set apiKey = "DER API-SCHLÜSSEL"
  • Automatisieren Sie das Abrufen und Festlegen der Umgebungsvariablen mithilfe eines Skripts nach den Anweisungen von Allan Hasegawa.
  • Globale Variablen verhalten sich nicht wie erwartet:
    "Es gibt keine Garantie dafür, dass der Status einer Cloud-Funktion für zukünftige Aufrufe erhalten bleibt." Https://cloud.google.com/functions/docs/bestpractices/tips

5. (b) Bereitstellung auf Google App Engine (Bonus!)

Google hat App Engine kürzlich um flexiblere Skalierungsfunktionen und die Unterstützung für Knoten 10 erweitert. Der Unterschied zwischen der Ausführung Ihres Web-Hooks auf App Engine- und Cloud-Funktionen ist recht subtil. Soweit ich weiß, führt Firebase möglicherweise viele Cloud-Funktionen auf vielen Instanzen zusammen aus und verwaltet, welche deaktiviert sind, wenn sie nicht verwendet werden. App Engine hingegen führt Ihre App auf einer oder mehreren dedizierten Instanzen aus, die je nach Bedarf automatisch skaliert werden können.

Wenn die Nachfrage Null ist, kann App Engine auf null Instanzen skaliert werden. Dies ist die Standardeinstellung, mit der die Kosten beim Experimentieren verwaltet werden können. App Engine bietet kostenlose Kontingente (28 Instanzstunden pro Tag). Dies bedeutet, dass möglicherweise keine Kosten für eine einzelne Instanz anfallen (aber zitieren Sie mich nicht dazu!).

Ich fand die Bereitstellung in App Engine viel einfacher als Cloud-Funktionen.

  1. Installieren Sie das Befehlszeilentool gcloud (siehe Dokumentation)
  2. Aktivieren Sie die Cloud Build-API für Ihr Projekt auf der Seite API & Services von Google Cloud Platform.
  3. Erstellen Sie im Stammverzeichnis Ihres Projekts eine Datei mit dem Namen app.yaml, die Folgendes enthält:
    Laufzeit: nodejs8
    oder alternativ für die neuesten Node.js zu bieten hat:
    Laufzeit: nodejs10
    (Wenn Sie nodejs10 wählen, müssen Sie auch die Knotenversion in "engines" von package.json ändern.)
  4. Bereitstellen: gcloud app deploy --project [yourprojectid]

Wenn die Bereitstellung erfolgreich war, öffnen Sie Ihren Browser unter https:// [yourprojectid] .appspot.com, und Ihr Web-Hook ist unter https:// [yourprojectid] .appspot.com / dialogflow verfügbar.

Ordnen Sie Ihrem package.json erneut ein Bereitstellungsskript zu, damit Sie npm run deploy-ae ausführen können, um es jederzeit bereitzustellen:

"Skripte": {
    ...
    "deploy-ae": "gcloud app deploy --project [yourprojectid]"
  },

Zusammenfassung

Sie sollten jetzt in der Lage sein:

  • Erstellen Sie eine lokale Entwicklungsumgebung für Ihr Web-Hook-Projekt mit Flusen- und Debugging-Funktionen - in Ihrem bevorzugten Browser
  • Stellen Sie Ihre lokale Umgebung mit ngrok als öffentliche https-URL bereit
  • Stellen Sie die Anwendung für Cloud-Funktionen in Firebase UND für Google App Engine bereit

Dieses Projekt begann als Web-Hook für Dialogflow, aber die besprochenen Techniken würden für jedes Web-Hook-Projekt funktionieren.

Sie finden den gesamten Code auf github: webhook-template. Ich verwende dies als Ausgangspunkt für jedes Web-Hook-Projekt - hoffe, Sie finden es auch nützlich.