Comment utiliser Flows avec Google Vision API et Google Cloud Functions

Constructeur de flux

1 min read

Comment utiliser Flows avec Google Vision API et Google Cloud Functions

Constructeur de flux

1 min read

Comment utiliser Flows avec Google Vision API et Google Cloud Functions

Flows est un puissant moteur d’automatisation par glisser-déposer pour créer des flux de communication. Nous l’avons initialement conçu comme une solution sans code, mais nous avons constaté que de nombreux utilisateurs pouvaient obtenir un comportement très puissant en écrivant un peu de code pour des cas d'utilisation spécifiques. Ces morceaux de code peuvent être à l'intérieur de Flow Builder, ou ils peuvent être des fonctions cloud tierces comme les fonctions AWS Lambda ou les fonctions Google Cloud.

Ceci est une simple démonstration utilisant GoogleCloud Functions et Flows pour faire de la reconnaissance d'image sur une image envoyée sur Telegram.

Flows et au-delà

En tant que développeur de Flows, je me demande souvent qui sont nos utilisateurs, pourquoi ils utilisent Flows, et ce dont ils ont besoin pour atteindre leurs objectifs ; et ensuite, quelles fonctionnalités nous devons mettre en œuvre pour mieux servir ces utilisateurs.




Flows est un puissant moteur d'automatisation par glisser-déposer pour créer des flux de communication. Nous l'avons initialement conçu comme une solution sans code, mais nous avons constaté que de nombreux utilisateurs pouvaient obtenir un comportement vraiment puissant en écrivant du code pour des cas d'utilisation spécifiques. Ces morceaux de code peuvent être à l'intérieur de Flows, ou ils peuvent être des fonctions cloud tierces comme les fonctions AWS Lambda ou les Google Cloud Functions.




Un cas d'utilisation intéressant : la reconnaissance d'images 

Pour un exemple court et amusant, je vais vous montrer comment mettre en œuvre une application qui reconnaît les hot dogs. Nous allons configurer un flux dans Flows, qui recevra des images des utilisateurs et décidera si elles ont envoyé un hot dog ou non.




Pour bon nombre de nos clients, ce type de reconnaissance d'images peut être très puissant. Imaginez que vous dirigez un service de livraison et que vous vouliez vérifier automatiquement les livraisons réussies. Comme ce que je vais vous montrer, vous pourriez utiliser des données de localisation, des photos de colis, et même des signatures de destinataires pour créer un flux de vérification dans Flows.

Un plan pour le succès

Tout d'abord, nous allons configurer une fonction cloud, qui reçoit une requête avec une URL vers une image, puis elle utilise une API de reconnaissance d'images pour traiter l'image, et répond si l'image contient un hotdog ou non.




Ensuite, nous allons créer un flux, qui reçoit un message d'un utilisateur via un canal de messagerie (Telegram dans ce cas), exécute la fonction cloud ci-dessus, et répond à l'utilisateur si l'image qu'il a envoyée contient un hotdog.

Tout d'abord, nous allons configurer une fonction cloud, qui reçoit une requête avec une URL vers une image, puis elle utilise une API de reconnaissance d'images pour traiter l'image, et répond si l'image contient un hotdog ou non.




Ensuite, nous allons créer un flux, qui reçoit un message d'un utilisateur via un canal de messagerie (Telegram dans ce cas), exécute la fonction cloud ci-dessus, et répond à l'utilisateur si l'image qu'il a envoyée contient un hotdog.

Tout d'abord, nous allons configurer une fonction cloud, qui reçoit une requête avec une URL vers une image, puis elle utilise une API de reconnaissance d'images pour traiter l'image, et répond si l'image contient un hotdog ou non.




Ensuite, nous allons créer un flux, qui reçoit un message d'un utilisateur via un canal de messagerie (Telegram dans ce cas), exécute la fonction cloud ci-dessus, et répond à l'utilisateur si l'image qu'il a envoyée contient un hotdog.

Configuration de la Google Cloud Function

Tout d'abord,  nous devrons configurer une fonction cloud. Pour démarrer rapidement, créez une fonction cloud en utilisant ce tutoriel : https://cloud.google.com/functions/docs/quickstart-console. En tant que ‘Trigger’, choisissez le déclencheur HTTP, environnement d'exécution : Node.js 10, et insérez le code dans le champ source. C’est un code simple, qui vérifie si la requête contient du code JSON et répond par oui ou non. 




/**
 * Responds to any HTTP request.
 *
 * @param {!express:Request} req HTTP request context.
 * @param {!express:Response} res HTTP response context.
 */
 exports.helloWorld = (req, res) => {
  let message = req.query.url ? "yes" : "no";
  res.setHeader('Content-Type', 'application/json');
  res.status(200).send(JSON.stringify({ isHotDog: message }));
 };







Ensuite, vous devrez déployer cette fonction. Pour la tester dans Google Cloud Platform, suivez les étapes du tutoriel. 

Pour tester depuis votre navigateur, allez à l'URL suivante en insérant l'adresse spécifique de votre fonction :




https://votre-adresse-de-fonction.cloudfunctions.net/HotDogOrNot/?url=hello devrait retourner {“isHotDog”: true} et l'adresse https://votre-adresse-de-fonction.cloudfunctions.net/HotDogOrNot devrait retourner {“isHotDog”: false}.




Bien joué ! Vous avez configuré une fonction cloud Google. Maintenant, nous devons rendre notre fonction cloud plus intelligente.

Configuration de l'API Google Vision

Pour le rendre plus intelligent, ajoutons la reconnaissance d'images. À cette fin, nous utiliserons le Google Vision API. Pour commencer, suivez les étapes 1 à 4 de ce tutoriel : https://cloud.google.com/vision/docs/quickstart-client-libraries. Dans le tutoriel, vous activerez l'API Vision et créerez un compte de service pour l'utiliser.




Maintenant, revenez à la fonction cloud que vous avez créée. Activez « Variables d'environnement, réseaux, délais et plus » et dans le fichier « Compte de service » choisissez le compte de service VisionAPI que vous venez de créer. Nous pouvons maintenant accéder à l'API Vision dans notre fonction.







Modifions maintenant le code. Dans un onglet « Package.json », insérez ce code. Cela ajoutera la bibliothèque Google Vision API comme dépendance à votre fonction.

{
  "name": "sample-http",
  "version": "0.0.1",
  "dependencies": {
  "@google-cloud/vision": "^1.11.0"
  }
 }




Dans l'onglet "Index.js", mettez à jour le code existant avec l'extrait de code suivant.

/**
 * Responds to any HTTP request.
 *
 * @param {!express:Request} req HTTP request context.
 * @param {!express:Response} res HTTP response context.
 */
 exports.helloWorld = (request, response) => {
  var url = request.query.url || request.body.url;
  if (url == null || url == "" ) {
  response.status(400).json({ error: "Must include a 'url' query parameter." });
  }
  
  
  getImageLabels(url)
  .then(labels => {
  // You can use 'console.log(labels);' command to check labels you got
  // We filter all labels if they contain "hot dog" in label description
  // And have a score > 0.6, which mean that VisionAPI is at least 60% sure that there is a hotdog on a picture
  labels = labels.filter(function(label) {
  return label.description.toLowerCase().includes("hot dog") && label.score > 0.6;
  });
  
  // If labels array contains at least 1 element, then we found a hot-dog!
  if (labels.length > 0) {
  response.status(200).json({isHotDog: true, error: ""});
  } else {
  response.status(200).json({isHotDog: false, error: ""});
  }
  })
  .catch(err => {
  response.status(500).json({ error: err });
  });
 };
  
 async function getImageLabels(imageUrl) {
  // Imports the Google Cloud client library
  const vision = require('@google-cloud/vision');
  // Creates a client
  const client = new vision.ImageAnnotatorClient();
  // Performs label detection on the image file
  const [result] = await client.labelDetection(imageUrl);
  const labels = result.labelAnnotations;
  return labels
 }










Quelle est la différence par rapport à la version précédente ? Nous avons ajouté une requête à VisionAPI, qui renvoie les ‘labels’ qu'il a trouvés sur l'image. Ensuite, nous filtrons ces étiquettes par description : si elle contient « hot dog » et si elle a plus de 60% de confiance en cette étiquette. S'il reste au moins 1 étiquette après le filtrage, cela signifie que nous avons trouvé un hotdog sur l'image.




Pour comprendre comment fonctionne Google VisionAPI et à quoi ressemble la réponse, consultez leur documentation, https://cloud.google.com/vision/docs




Après cela, déployez la nouvelle version de notre fonction. Pour la tester depuis votre navigateur, trouvez n'importe quelle image de hotdog et enregistrez son URL. Allez maintenant à l'URL de votre fonction (en insérant l'adresse correcte pour votre fonction) https://your-function-address.cloudfunctions.net/HotDogOrNot?url=url_to_image et remplacez « url_to_image » par une URL vers l'image trouvée. S'il y a un hotdog dans l'image, la page retournera {“isHotDog”: true}.




Connectons maintenant cette fonction à Flow Builder.

Créer un flux dans Flows

Connectez-vous au Tableau de bord Bird ou inscrivez-vous pour un compte si vous n'en avez pas.




Si vous êtes nouveau sur Flows et que vous n'avez aucun canal configuré, vous devrez accéder à la page de configuration des canaux et choisir de configurer le canal Telegram. J'ai choisi Telegram pour cette démo car il est facile et rapide à configurer.







Maintenant, vous avez un canal que nous pouvons utiliser dans Flows. Allez à la page Flows, créez un nouveau flux personnalisé et choisissez le déclencheur de canal « Telegram ».







Vous serez redirigé vers une page de flux où vous devrez choisir votre canal Telegram comme déclencheur, dans notre cas il s’agit de « Hotdog ». Veuillez ajouter 2 étapes : « Récupérer des variables » et « Répondre au message du canal ».




À l'intérieur de l'étape « Récupérer des variables », nous appellerons notre fonction cloud et récupérerons la réponse dans la variable « isHotDog » qui contiendra « true » ou « false » en tant que réponse de la fonction GoogleClound. Dans le champ URL, veuillez insérer l'URL de votre fonction https://your-function-address.cloudfunctions.net/HotDogOrNot et remplissez tous les autres champs comme sur l'image du contenu de l'étape « Récupérer la variable ».




Et à l'intérieur de l'étape « Répondre au message du canal », nous répondrons au client avec un message contenant la réponse oui ou non. Pour cela, insérez dans le champ « Répondre avec message » le texte suivant « Hotdog sur l'image? {{isHotDog}}".







Si vous avez des difficultés à créer le flux, vous pouvez utiliser l'extrait suivant :

{
  "id": "",
  "revisionId": "",
  "trigger": "onReceivedConversationMessage",
  "options": {
  "callbacks": [],
  "targets": []
  },
  "metadata": {
  "title": "Image recognition",
  "isDraft": false,
  "triggerIntent": "onReceivedTelegramMessage"
  },
  "steps": [
  {
  "id": "19c3560f-a8d0-4787-8714-37c698108b69",
  "action": "fetchVariables",
  "options": {
  "url": "https://your-function-address.cloudfunctions.net/HotDogOrNot",
  "variableKeys": [
  "isHotDog"
  ],
  "intent": "fetchVariables",
  "label": "Is there a hotdog on the image?",
  "method": "POST",
  "body": "{\"url\":\"{{messageImage}}\"}",
  "contentType": "application/json"
  }
  },
  {
  "id": "ca9314a2-2f9d-489c-b4b1-50fc7a0b2cb6",
  "action": "sendConversationMessage",
  "options": {
  "content": {
  "text": "Hotdog on the image? {{isHotDog}}",
  "image": {
  "url": ""
  },
  "audio": {
  "url": ""
  },
  "video": {
  "url": ""
  },
  "file": {
  "url": ""
  },
  "location": {
  "latitude": "",
  "longitude": ""
  },
  "email": {
  "from": {
  "name": "",
  "address": ""
  },
  "subject": "",
  "content": {},
  "headers": null
  }
  },
  "type": "text",
  "recipients": {
  "conversationIds": [
  "{{conversationId}}"
  ]
  },
  "intent": "replyConversationMessage",
  "highThroughput": false
  }
  }
  ],
  "published": true,
  "createdAt": "2020-08-28T18:25:19.665815708Z",
  "updatedAt": "2020-08-29T01:15:43.669252097Z",
  "revisionCount": 22
 }







Pour le tester, envoyez une image à votre bot Telegram.

Jusqu'à présent, ça a l'air cool ! Nous avons créé un petit chatbot, qui vérifie les images envoyées par les clients. Pour le rendre plus joli, ajoutons quelques étapes supplémentaires comme indiqué ci-dessous: 







Si vous avez des difficultés à créer le flux, vous pouvez utiliser l'extrait suivant :

{
  "id": "",
  "revisionId": "",
  "trigger": "onReceivedConversationMessage",
  "options": {
  "callbacks": [],
  "targets": []
  },
  "metadata": {
  "title": "Image recognition",
  "isDraft": false,
  "triggerIntent": "onReceivedTelegramMessage"
  },
  "steps": [
  {
  "id": "0c3e4f35-0950-44dd-8682-0a21a111de77",
  "action": "switch",
  "options": {
  "cases": [
  {
  "conditions": [
  {
  "variable": "{{messageImage}}",
  "operator": "isEmptyOrNotSet",
  "value": "",
  "options": {
  "intent": "custom"
  }
  }
  ],
  "steps": [
  {
  "id": "ffd13531-a3b9-41de-a2fa-0e515feed2fe",
  "action": "sendConversationMessage",
  "options": {
  "content": {
  "text": "Please send an image.",
  "image": {
  "url": ""
  },
  "audio": {
  "url": ""
  },
  "video": {
  "url": ""
  },
  "file": {
  "url": ""
  },
  "location": {
  "latitude": "",
  "longitude": ""
  },
  "email": {
  "from": {
  "name": "",
  "address": ""
  },
  "subject": "",
  "content": {},
  "headers": null
  }
  },
  "type": "text",
  "recipients": {
  "conversationIds": [
  "{{conversationId}}"
  ]
  },
  "intent": "replyConversationMessage",
  "label": "Ask to send an image",
  "highThroughput": false
  }
  },
  {
  "id": "3d752bc6-cf35-4971-8155-44a2bea4bb49",
  "action": "endFlow",
  "options": {
  "intent": "endFlow"
  }
  }
  ],
  "id": "aa_QVqjIn9"
  }
  ],
  "defaultCase": {
  "steps": [
  {
  "id": "8f3748cf-9059-44fb-a177-bc0dab194e7b",
  "action": "sendConversationMessage",
  "options": {
  "content": {
  "text": "Thank you for the image! We started to detect a hotdog on the image.",
  "image": {
  "url": ""
  },
  "audio": {
  "url": ""
  },
  "video": {
  "url": ""
  },
  "file": {
  "url": ""
  },
  "location": {
  "latitude": "",
  "longitude": ""
  },
  "email": {
  "from": {
  "name": "",
  "address": ""
  },
  "subject": "",
  "content": {},
  "headers": null
  }
  },
  "type": "text",
  "recipients": {
  "conversationIds": [
  "{{conversationId}}"
  ]
  },
  "intent": "replyConversationMessage",
  "label": "Send \"Thanks for the image\"",
  "highThroughput": false
  }
  },
  {
  "id": "808debc0-974d-4b3f-bd4f-ed4efb30a499",
  "action": "fetchVariables",
  "options": {
  "url": "https://your-function-address.cloudfunctions.net/HotDogOrNot",
  "variableKeys": [
  "isHotDog"
  ],
  "intent": "fetchVariables",
  "label": "Send image to VisionAPI",
  "method": "POST",
  "body": "{\"url\":\"{{messageImage}}\"}",
  "contentType": "application/json"
  }
  },
  {
  "id": "c9f771fb-06ff-4362-b783-07e4bd3ff53d",
  "action": "switch",
  "options": {
  "cases": [
  {
  "conditions": [
  {
  "variable": "{{isHotDog}}",
  "operator": "==",
  "value": "true",
  "options": {
  "intent": "custom"
  }
  }
  ],
  "steps": [
  {
  "id": "02629417-e3ac-4bfa-94a9-83047c250d54",
  "action": "sendConversationMessage",
  "options": {
  "content": {
  "text": "There is a hotdog on the image. Thank you!",
  "image": {
  "url": ""
  },
  "audio": {
  "url": ""
  },
  "video": {
  "url": ""
  },
  "file": {
  "url": ""
  },
  "location": {
  "latitude": "",
  "longitude": ""
  },
  "email": {
  "from": {
  "name": "",
  "address": ""
  },
  "subject": "",
  "content": {},
  "headers": null
  }
  },
  "type": "text",
  "recipients": {
  "conversationIds": [
  "{{conversationId}}"
  ]
  },
  "intent": "replyConversationMessage",
  "label": "Send \"we detected a hotdog!\"",
  "highThroughput": false
  }
  }
  ],
  "id": "AWzLv6jksY"
  }
  ],
  "defaultCase": {
  "steps": [
  {
  "id": "b00034ce-db49-4ddf-bf8f-2be006e3fbbd",
  "action": "sendConversationMessage",
  "options": {
  "content": {
  "text": "Sorry, we didn't detect a hotdog on the image. Please try again.",
  "image": {
  "url": ""
  },
  "audio": {
  "url": ""
  },
  "video": {
  "url": ""
  },
  "file": {
  "url": ""
  },
  "location": {
  "latitude": "",
  "longitude": ""
  },
  "email": {
  "from": {
  "name": "",
  "address": ""
  },
  "subject": "",
  "content": {},
  "headers": null
  }
  },
  "type": "text",
  "recipients": {
  "conversationIds": [
  "{{conversationId}}"
  ]
  },
  "intent": "replyConversationMessage",
  "label": "Notify that we didn't detect a hotdog",
  "highThroughput": false
  }
  }
  ],
  "id": "mwk5RoiCo"
  },
  "intent": "smsConditional"
  }
  },
  {
  "id": "8778c563-c045-4aa6-80e5-4c2a29b38b3f",
  "action": "endFlow",
  "options": {
  "intent": "endFlow"
  }
  }
  ],
  "id": "iuFXBNrWTr"
  },
  "intent": "smsConditional",
  "label": "Check if user sent an image"
  }
  }
  ],
  "published": true,
  "createdAt": "2020-08-28T18:25:19.665815708Z",
  "updatedAt": "2020-08-29T01:25:15.614170299Z",
  "revisionCount": 26
 }

Résultats




Bien que ce soit un exemple amusant, nous croyons que ce type de fonctionnalité peut être très utile pour nos utilisateurs. 

Si vous souhaitez plus de fonctionnalités comme celle-ci intégrées dans Flows, écrivez à notre équipe de support pour nous le faire savoir. 

Rejoignez notre Newsletter.

Restez à jour avec Bird grâce aux mises à jour hebdomadaires dans votre boîte de réception.

En soumettant, vous acceptez que Bird puisse vous contacter au sujet de nos produits et services.

Vous pouvez vous désabonner à tout moment. Consultez la Déclaration de confidentialité de Bird pour plus de détails sur le traitement des données.

Rejoignez notre Newsletter.

Restez à jour avec Bird grâce aux mises à jour hebdomadaires dans votre boîte de réception.

En soumettant, vous acceptez que Bird puisse vous contacter au sujet de nos produits et services.

Vous pouvez vous désabonner à tout moment. Consultez la Déclaration de confidentialité de Bird pour plus de détails sur le traitement des données.

Rejoignez notre Newsletter.

Restez à jour avec Bird grâce aux mises à jour hebdomadaires dans votre boîte de réception.

En soumettant, vous acceptez que Bird puisse vous contacter au sujet de nos produits et services.

Vous pouvez vous désabonner à tout moment. Consultez la Déclaration de confidentialité de Bird pour plus de détails sur le traitement des données.

Pinterest logo
Uber logo
Logo Square
Logo Adobe
Meta logo
logo PayPal

Company

Paramètres de confidentialité

Newsletter

Restez à jour avec Bird grâce aux mises à jour hebdomadaires dans votre boîte de réception.

En soumettant, vous acceptez que Bird puisse vous contacter au sujet de nos produits et services.

Vous pouvez vous désabonner à tout moment. Consultez la Déclaration de confidentialité de Bird pour plus de détails sur le traitement des données.

Uber logo
Logo Square
Logo Adobe
Meta logo

Company

Paramètres de confidentialité

Newsletter

Restez à jour avec Bird grâce aux mises à jour hebdomadaires dans votre boîte de réception.

En soumettant, vous acceptez que Bird puisse vous contacter au sujet de nos produits et services.

Vous pouvez vous désabonner à tout moment. Consultez la Déclaration de confidentialité de Bird pour plus de détails sur le traitement des données.

Uber logo
Logo Adobe
Meta logo

Company

Paramètres de confidentialité

Newsletter

Restez à jour avec Bird grâce aux mises à jour hebdomadaires dans votre boîte de réception.

En soumettant, vous acceptez que Bird puisse vous contacter au sujet de nos produits et services.

Vous pouvez vous désabonner à tout moment. Consultez la Déclaration de confidentialité de Bird pour plus de détails sur le traitement des données.