Bereik

Grow

Manage

Automate

Bereik

Grow

Manage

Automate

Hoe Flows te gebruiken met Google Vision API en Google Cloud Functions

Stroom Builder

1 min read

Hoe Flows te gebruiken met Google Vision API en Google Cloud Functions

Stroom Builder

1 min read

Hoe Flows te gebruiken met Google Vision API en Google Cloud Functions

Flows is een krachtige drag-and-drop automatiseringsengine voor het creëren van communicatieflows. We bedachten het aanvankelijk als een no-code oplossing, maar we ontdekten dat veel gebruikers echt krachtige functionaliteiten konden creëren door wat code te schrijven voor specifieke use-cases. Deze stukjes code kunnen binnen Flow Builder zijn, of ze kunnen 3rd party cloudfuncties zijn zoals AWS Lambda functies of Google Cloud Functions.

Dit is een eenvoudige demonstratie met GoogleCloud Functions en Flows om beeldherkenning uit te voeren op een afbeelding die via Telegram is verzonden.

Flows en Beyond

Als ontwikkelaar van Flows denk ik vaak na over wie onze gebruikers zijn, waarom ze Flows gebruiken en wat ze nodig hebben om hun doelen te bereiken; en vervolgens, welke functies we moeten implementeren om die gebruikers het beste te bedienen.

Flows is een krachtige drag-and-drop automatiseringsmotor voor het maken van communicatieflows. We hadden het oorspronkelijk bedacht als een no-code oplossing, maar we ontdekten dat veel gebruikers echt krachtige functionaliteit konden krijgen door wat code te schrijven voor specifieke gebruikssituaties. Deze stukjes code kunnen binnen Flows zijn, of ze kunnen externe cloudfuncties zijn zoals AWS Lambda functies of Google Cloud Functions

Een interessant gebruiksvoorbeeld: Beeldherkenning 

Voor een kort en grappig voorbeeld zal ik je laten zien hoe je een app kunt implementeren die hotdogs herkent. We zullen een flow in Flows instellen, die afbeeldingen van gebruikers ontvangt en bepaalt of ze een hotdog hebben gestuurd of niet.

Voor veel van onze klanten kan dit type beeldherkenning zeer krachtig zijn. Stel je voor dat je een bezorgdienst runt en je automatisch succesvolle leveringen wilde verifiëren. Vergelijkbaar met wat ik ga laten zien, zou je locatiegegevens, foto's van pakketten en zelfs handtekeningen van ontvangers kunnen gebruiken om een verificatiestroom in Flows te creëren. 

Een plan voor succes

Eerst zullen we een cloudfunctie instellen die een verzoek met een URL naar een afbeelding ontvangt. Vervolgens gebruikt het een beeldherkennings-API om de afbeelding te verwerken en reageert het of er een hotdog in de afbeelding is of niet.

Daarna bouwen we een flow die een bericht van een gebruiker via een berichtenkanaal (in dit geval Telegram) ontvangt, de bovenstaande cloudfunctie uitvoert, en aan de gebruiker rapporteert of er een hotdog in de foto zit die hij heeft verzonden.

Eerst zullen we een cloudfunctie instellen die een verzoek met een URL naar een afbeelding ontvangt. Vervolgens gebruikt het een beeldherkennings-API om de afbeelding te verwerken en reageert het of er een hotdog in de afbeelding is of niet.

Daarna bouwen we een flow die een bericht van een gebruiker via een berichtenkanaal (in dit geval Telegram) ontvangt, de bovenstaande cloudfunctie uitvoert, en aan de gebruiker rapporteert of er een hotdog in de foto zit die hij heeft verzonden.

Eerst zullen we een cloudfunctie instellen die een verzoek met een URL naar een afbeelding ontvangt. Vervolgens gebruikt het een beeldherkennings-API om de afbeelding te verwerken en reageert het of er een hotdog in de afbeelding is of niet.

Daarna bouwen we een flow die een bericht van een gebruiker via een berichtenkanaal (in dit geval Telegram) ontvangt, de bovenstaande cloudfunctie uitvoert, en aan de gebruiker rapporteert of er een hotdog in de foto zit die hij heeft verzonden.

Het instellen van de Google Cloud Function

Eerst moeten we een cloudfunctie instellen. Om snel aan de slag te gaan, maak je een cloudfunctie met behulp van deze tutorial: https://cloud.google.com/functions/docs/quickstart-console. Kies als 'Trigger' een HTTP-trigger, uitvoeringsomgeving: Node.js 10, en plaats de codefragment in het broncodeveld. Het is een eenvoudige code, die controleert of het verzoek JSON-code bevat en antwoordt ja of nee. 

/**
 * 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 }));
 };


Google Cloud Console interface with options for creating a new Cloud Function.


Vervolgens moet je deze functie implementeren. Volg de stappen uit de tutorial om deze binnen Google Cloud Platform te testen. 

Om vanuit je browser te testen, ga naar de volgende URL en vul het specifieke adres voor je functie in:

https://your-function-address.cloudfunctions.net/HotDogOrNot/?url=hello zou {“isHotDog”: true} moeten teruggeven en het adres https://your-function-address.cloudfunctions.net/HotDogOrNot zou {“isHotDog”: false} moeten teruggeven.

Goed gedaan! Je hebt een google cloudfunctie ingesteld. Nu moeten we onze cloudfunctie slimmer maken.

Het instellen van de Google Vision API

Om het slimmer te maken, laten we beeldherkenning toevoegen. Hiervoor zullen we de Google Vision API gebruiken. Om aan de slag te gaan, volg stappen 1-4 van deze tutorial: https://cloud.google.com/vision/docs/quickstart-client-libraries. In de tutorial activeer je de Vision API en maak je een serviceaccount om het te gebruiken.

Keer nu terug naar de cloudfunctie die je hebt gemaakt. Schakel "Omgevingsvariabelen, netwerken, time-outs en meer" in en kies in het bestand "Serviceaccount" het VisionAPI-serviceaccount dat je zojuist hebt aangemaakt. Nu kunnen we toegang krijgen tot de Vision API binnen onze functie.

Advanced options interface of a cloud service configuration.


Nu gaan we de code wijzigen. Op een "Package.json" tab, voeg deze code in. Het zal de Google Vision API-bibliotheek toevoegen als een afhankelijkheid aan je functie.

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


Op het "Index.js" tabblad, werk de bestaande code bij met de volgende codefragment.

/**
 * 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
 }



Development environment displaying the code for a package.json file.


Wat is het verschil vergeleken met de vorige versie? We hebben een verzoek aan VisionAPI toegevoegd, die de ‘labels’ teruggeeft die het heeft gevonden op de afbeelding. Vervolgens filteren we deze labels op beschrijving: als het "hot dog" bevat en als het meer dan 60% vertrouwen heeft in dat label. Als er na het filteren ten minste 1 label overblijft, betekent dit dat we een hotdog op de afbeelding hebben gevonden.

Om te begrijpen hoe Google VisionAPI werkt en hoe de respons eruitziet, bekijk hun documentatie, https://cloud.google.com/vision/docs

Daarna, implementeer de nieuwe versie van onze functie. Om het vanuit je browser te testen, zoek een afbeelding van een hotdog en sla de URL ervan op. Ga nu naar de URL van je functie (door het juiste adres voor je functie in te voeren) https://your-function-address.cloudfunctions.net/HotDogOrNot?url=url_to_image en vervang het "url_to_image" met een URL naar de gevonden afbeelding. Als er een hotdog op de afbeelding staat, zal de pagina {“isHotDog”: true} teruggeven.

Laten we deze functie nu verbinden met Flow Builder.

Een flow maken in Flows

Meld je aan bij het Bird-dashboard of registreer je voor een account als je er nog geen hebt.

Als je nieuw bent bij Flows en nog geen kanalen hebt ingesteld, moet je naar de Kanaalinstellingen-pagina gaan en ervoor kiezen om het Telegram-kanaal in te stellen. Ik heb voor dit demo gekozen voor Telegram omdat het eenvoudig en snel in te stellen is.

Interface titled "Channel setup" with options to integrate communication platforms such as Telegram, Messenger, LINE, WeChat, SMS, WhatsApp, Email, and Instagram.


Nu heb je een kanaal dat we in Flows kunnen gebruiken. Ga naar de Flows-pagina, maak een nieuwe aangepaste flow en kies de “Telegram”-kanaaltrigger.

User interface for selecting a communication channel trigger, showing options such as Telegram, Facebook Messenger, Email, Incoming Order Activity, and Shopify Order.


Je wordt doorgestuurd naar een flowpagina, waar je je Telegram-kanaal als trigger moet kiezen, in ons geval is dat “Hotdog”. Voeg 2 stappen toe: “Fetch variables” en “Reply to channel message”.

In de stap “Fetch variables” zullen we onze cloudfunctie aanroepen en de reactie ophalen in de variabele “isHotDog” die “true” of “false” zal bevatten als een antwoord van de GoogleClound-functie. In het URL-veld graag de URL van jouw functie invoegen https://your-function-address.cloudfunctions.net/HotDogOrNot en vul alle andere velden in zoals op de "Fetch variable step content" afbeelding.

En in de stap “Reply to channel message” zullen we antwoorden aan de klant met een bericht waarin de ja of nee reactie staat. Hiervoor in het veld "Reply with message" de volgende tekst invoegen "Hotdog op de afbeelding? {{isHotDog}}".

User interface with a form featuring fields like URL, Method, and Headers, along with options for body content and a section for setting header type, all related to configuring a web request in a cloud function environment.


Interface showing a message type selection dropdown, and options for status reports.

Als je problemen hebt met het opbouwen van de flow, kun je de volgende snippet gebruiken:

{
  "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
 }


Flowchart illustrating an image recognition process.


Om het te testen, stuur een afbeelding naar je Telegram-bot.

Tot nu toe ziet het er gaaf uit! We hebben een kleine chatbot gemaakt, die de door klanten verzonden afbeeldingen controleert. Om het mooier te maken, laten we enkele stappen toevoegen zoals hieronder getoond: 


A flowchart diagram illustrating an image recognition process using Telegram Bot and Vision API.


Als je problemen hebt met het opbouwen van de flow, kun je de volgende snippet gebruiken:

{
  "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
 }

Resultaten

A chat interface shows a humorous exchange about detecting a hotdog in an image.A mobile chat interface shows an AI chatbot identifying a photo of a hot dog.


Hoewel dit een leuk voorbeeld is, denken we dat dit soort functionaliteit zeer nuttig kan zijn voor onze gebruikers. 

Als u meer functies zoals deze ingebouwd in Flows wilt, schrijf dan naar ons ondersteuningsteam om ons dit te laten weten. 

Laten we je in contact brengen met een Bird-expert.
Bekijk de volledige kracht van de Bird in 30 minuten.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.

Nieuwsbrief

Blijf op de hoogte met Bird via wekelijkse updates in je inbox.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.

Laten we je in contact brengen met een Bird-expert.
Bekijk de volledige kracht van de Bird in 30 minuten.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.

Nieuwsbrief

Blijf op de hoogte met Bird via wekelijkse updates in je inbox.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.

Laten we je in contact brengen met een Bird-expert.
Bekijk de volledige kracht van de Bird in 30 minuten.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.

R

Bereik

G

Grow

M

Manage

A

Automate

Nieuwsbrief

Blijf op de hoogte met Bird via wekelijkse updates in je inbox.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.