Ganchos web de Dialogflow: cómo desarrollar localmente e implementar en Cloud Functions

Cuando nuestro equipo comenzó a construir el chatbot de Nila en LINE HACK 2018, sabíamos tanto como Jon Snow sobre cómo construir un enlace web. Algunos de nosotros teníamos experiencia en Firebase y en escribir Cloud Functions, por lo que asumimos que iba a ser bastante fácil, especialmente cuando encontramos el Editor en línea, pero terminamos construyendo la primera versión completamente en Glitch, un entorno en vivo para ejecutar Node .js aplicaciones. Si bien Glitch es excelente para aprender, podríamos habernos facilitado la vida al establecer un entorno de desarrollo local.

Este artículo explica cómo construir un enlace web mediante el desarrollo local y la implementación en la nube. Es un conjunto de consejos y trucos que harán que el desarrollo de enlaces web sea más rápido, práctico y seguro:

  • Más rápido: ejecute localmente, solo implemente cuando lo necesite
  • Práctico: depure su aplicación con solicitudes en vivo desde su enlace web
  • Más seguro: linting y autocompletar desde su editor favorito

1. Comience con una plantilla y ejecútela localmente

Si bien el enfoque es los enlaces web de Dialogflow en este artículo, sospecho que estos pasos son los mismos para desarrollar cualquier enlace web. Si está utilizando Dialogflow, entonces puede comenzar con el Editor en línea para su cumplimiento. Lo primero que debe hacer es tomar ese código y modificarlo para que se ejecute localmente.

En simpleServer.js, tomé el código de cumplimiento de Dialogflow del Editor en línea, eliminé el código específico de Firebase y agregué express para servir el enlace web. Necesitará un package.json con las dependencias para express, dialogflow-cumplimiento y actions-on-google. Ejecute el enlace web por nodo simpleServer.js y luego abra http: // localhost: 8080 / para verificar que esté funcionando.

2. Use ngrok para servir http local a https público

Ngrok es un servicio gratuito que le proporciona una URL https segura y pública a su servidor web local. Puede instalar ngrok globalmente (descargar binario o npm install global), pero mi preferencia es instalar como una dependencia de desarrollo:

npm install ngrok --save-dev

Y luego modifique su package.json:

  ...
  "guiones": {
    "tunnel": "ngrok http 8080"
  },

Ahora, cada vez que desee crear una URL https para su entorno de desarrollo local, simplemente use npm run tunnel. Ngrok se ejecutará y creará una URL https:

Ejecutar ngrok para obtener una URL https pública para su servidor local

Ahora puede copiar la URL https en "Reenvío" (resaltada en rojo) para que sea su enlace web de cumplimiento en Dialogflow:

Configure el cumplimiento de Dialogflow para usar una URL de reenvío ngrok

En este punto, probaría que todo funciona enviando un "hola" en la consola de prueba de Dialogflow:

La razón por la que prefiero instalar como dependencia de desarrollo es que cuando otro desarrollador se une al equipo, no necesitan instalar nada adicional, solo pueden usar npm run tunnel para crear su URL https.

Puede salir de ngrok usando Ctrl-C (y dejará de servir su URL pública). Cada vez que reinicie ngrok, recibirá una nueva URL, lo que significa que deberá actualizar la URL en la consola de Dialogflow. Una forma de evitar esto es actualizar a uno de los planes pagos de ngrok.

3. Recarga (nodemon) y depuración (Código VS)

En este punto, tiene una URL pública que canaliza todo el tráfico a nuestra máquina local que ejecuta una plantilla básica de Dialogflow. Vamos a querer editar el código y ver los cambios al instante en nuestro enlace web (por ejemplo, a través del simulador Dialogflow).

Nodemon es el mejor amigo de Node.js, reinicia el servidor cada vez que detecta cambios. Al igual que ngrok, lo instalo como una dependencia de desarrollo:

npm install nodemon --save-dev

Y modifique sus scripts package.json nuevamente:

  "guiones": {
    "dev": "nodemon --inspect simpleServer.js",
    "tunnel": "ngrok http 8080"
  },

Luego, inicie su entorno de desarrollo con npm run dev.

El argumento --inspect habilita el depurador. En VS Code, puede crear una configuración de depuración que funcione con nodemon de la siguiente manera:

  1. En el menú "Depurar", seleccione "Abrir configuraciones" para abrir el archivo launch.json.
  2. Utilice el botón "Agregar configuración ..." para agregar una nueva configuración de depuración "Node.js: Adjuntar". La configuración resultante debería verse así:
"configuraciones": [
  {
    "type": "nodo",
    "request": "adjuntar",
    "nombre": "Adjuntar",
    "puerto": 9229
  }
]

Para probar esto, presione F5 para iniciar la depuración (debería ver el depurador adjunto. En la Terminal). Luego coloque un punto de interrupción en su agente de welcome (). Vaya a la consola de prueba de Dialogflow y diga "hola" nuevamente. El depurador detendrá la ejecución en su punto de interrupción.

4. Estilo de código (opcional)

Mientras estamos configurando VS Code, podría ser un buen momento para configurar un linter. Me gusta usar el estilo estándar de JavaScript porque es simple: no me gustan el 100% de las reglas, pero está lo suficientemente cerca y me encanta el hecho de que es un estilo fijo, por lo que no hay que discutir / perder tiempo ajustando ESLint opciones. También es fácil de instalar:

npm install standard --save-dev

Agregue un comando lint a su package.json:

"guiones": {
    ...
    "pelusa": "estándar"
  },

Luego puede verificar su código con npm run lint o corregir todos los errores con npm run lint - --fix.

Sin embargo, probablemente desee la función de corrección en su editor. VS Code tiene una extensión para Standard. Después de instalar esto, agregue {"key": "cmd + l", "command": "standard.executeAutofix"} a keybindings.json, cambiando cmd + l por el método abreviado de teclado que desee utilizar. Ahora puede presionar ese acceso directo para mantener su código en el estilo Estándar. :)

5. (a) Implementación en las funciones de la nube para Firebase

Después de despedirnos de Cloud Functions eliminándolas en el paso 1, es hora de que regresemos a la implementación. Recuerde que nuestro código original de Cloud Functions se veía así:

exportaciones.dialogflowFirebaseFulfillment =
    functions.https.onRequest ((solicitud, respuesta) => {...})

Resulta que una aplicación express también es una función que toma una solicitud / respuesta, por lo que satisface los requisitos de Cloud Functions para (solicitud, respuesta) => {...}.

Por lo tanto, podemos dividir nuestro simpleServer.js existente en server.js y app.js. El archivo app.js contiene nuestra aplicación que puede ejecutarse en Node.js o Cloud Functions.

Ejecutar una aplicación express a través de Cloud Functions

Esta arquitectura nos da la capacidad de ejecutar localmente con ngrok y nodo cuando estamos desarrollando e implementar en Cloud Functions para producción.

El resultado:

No olvides instalar las dependencias para Firebase: npm install firebase-functions firebase-admin --save.

A continuación, el despliegue ...

Si no está familiarizado con la implementación de Cloud Functions, puede consultar la documentación de Firebase.

Pasos básicos:

  1. Instale Firebase CLI: npm install -g firebase-tools @ latest
  2. Cree firebase.json que contenga:
    {"funciones": {"fuente": ".", "predeploy": ["npm run lint"]}}
  3. Ejecute el uso de Firebase: agregue dentro de la carpeta de su proyecto para seleccionar su proyecto de Firebase y asignar un alias.
  4. Edite su package.json para apuntar el script "principal" a "cloudFuncs.js":
    "main": "cloudFuncs.js",
  5. Si desea usar el Nodo 8 (¡probablemente lo haga!), También agregue esto a package.json:
    "motores": {"nodo": "8"},
  6. Intente implementar: implementación de firebase: solo funciones
Implemente un enlace web en Cloud Functions en Firebase

Si la implementación se completa con éxito, puede abrir el punto final de prueba en su navegador en: https: // us-central1- [yourprojectid] .cloudfunctions.net / app / (nota, la barra inclinada final / es necesaria para la coincidencia de ruta express).

Y la URL del enlace web es https: // us-central1- [yourprojectid] .cloudfunctions.net / app / dialogflow.

Finalmente, agregue un script de implementación a su package.json, de modo que pueda ejecutar npm run deploy-cf para implementar en Firebase en cualquier momento:

  "guiones": {
    ...
    "deploy-cf": "firebase deploy - solo funciones"
  },

Funciones locales de Node.js vs Cloud

  • Las variables de entorno deben establecerse mediante el comando firebase. Ejemplo:
    funciones de firebase: config: set apiKey = "LA CLAVE API"
  • Automatice la obtención y configuración de las variables de entorno con un script siguiendo los consejos de Allan Hasegawa.
  • Las variables globales no se comportarán como esperabas:
    "No hay garantía de que se mantenga el estado de una función en la nube para futuras invocaciones". Https://cloud.google.com/functions/docs/bestpractices/tips

5. (b) Implementación en Google App Engine (¡bonificación!)

Google agregó recientemente funciones de escalado más flexibles a App Engine y soporte para el Nodo 10. La diferencia entre ejecutar su enlace web en App Engine y Cloud Functions es bastante sutil. Por lo que entiendo, Firebase está ejecutando potencialmente muchas funciones de nube juntas en muchas instancias y gestiona cuáles se desactivan cuando no se usan. App Engine, por otro lado, ejecuta su aplicación en una o más instancias dedicadas que se pueden escalar automáticamente según la demanda.

Cuando la demanda es cero, App Engine puede escalar a cero instancias; este es el valor predeterminado que es bueno para administrar los costos cuando está experimentando. App Engine tiene cuotas gratuitas (28 horas de instancia por día), lo que significa que es posible que no incurra en costos por una sola instancia (¡pero no me cite en eso!).

Descubrí que la implementación en App Engine es mucho más fácil que Cloud Functions.

  1. Instale la herramienta de línea de comandos gcloud: consulte la documentación
  2. Habilite la API Cloud Build para su proyecto en la página API y servicios de Google Cloud Platform.
  3. Cree un archivo llamado app.yaml en la raíz de su proyecto, que contenga:
    tiempo de ejecución: nodejs8
    o alternativamente para lo último que Node.js tiene para ofrecer:
    tiempo de ejecución: nodejs10
    (Si elige nodejs10, entonces también debe modificar la versión del nodo en "motores" de package.json).
  4. Implementación: implementación de la aplicación gcloud --project [yourprojectid]

Si la implementación fue exitosa, abra su navegador en https: // [yourprojectid] .appspot.com y su enlace web estará disponible en https: // [yourprojectid] .appspot.com / dialogflow.

Una vez más, ordene con un script de implementación en su package.json para que pueda ejecutar npm ejecute deploy-ae para implementar en cualquier momento:

"guiones": {
    ...
    "deploy-ae": "implementación de la aplicación gcloud --project [yourprojectid]"
  },

Resumen

Ahora debería poder:

  • Cree un entorno de desarrollo local para su proyecto de enlace web, con capacidades de enlace y depuración, en su navegador favorito
  • Sirva su entorno local como URL https pública usando ngrok
  • Implemente la aplicación en Cloud Functions en Firebase Y en Google App Engine

Este proyecto comenzó como un enlace web para Dialogflow, pero las técnicas discutidas funcionarían para cualquier proyecto de enlace web.

Puedes encontrar todo el código en github: webhook-template. Lo uso como punto de partida para cualquier proyecto de enlace web; espero que también lo encuentre útil.