Zasięg

Grow

Manage

Automate

Zasięg

Grow

Manage

Automate

Jak używać Flows z Google Vision API i Google Cloud Functions

Kreator przepływów

1 min read

Jak używać Flows z Google Vision API i Google Cloud Functions

Kreator przepływów

1 min read

Jak używać Flows z Google Vision API i Google Cloud Functions

Flows to potężny silnik automatyzacji typu drag-and-drop do tworzenia przepływów komunikacyjnych. Początkowo pomyśleliśmy o nim jako o rozwiązaniu bez kodu, ale odkryliśmy, że wielu użytkowników może uzyskać naprawdę potężne zachowania, pisząc trochę kodu dla konkretnych przypadków użycia. Te fragmenty kodu mogą znajdować się wewnątrz Flow Builder albo być zewnętrznymi funkcjami w chmurze, takimi jak funkcje AWS Lambda lub Google Cloud Functions.

To jest prosta demonstracja używająca GoogleCloud Functions i Flows do rozpoznawania obrazów na zdjęciu wysłanym na Telegramie.

Flows i Beyond

Jako deweloper Flows często zastanawiam się, kim są nasi użytkownicy, dlaczego używają Flows i co muszą zrobić, aby osiągnąć swoje cele; a następnie, które funkcje musimy zaimplementować, aby jak najlepiej służyć tym użytkownikom.

Flows to potężny silnik automatyzacji typu drag-and-drop do tworzenia przepływów komunikacji. Początkowo pomyślany jako rozwiązanie niewymagające kodu, odkryliśmy, że wielu użytkowników potrafi uzyskać naprawdę potężne zachowania, pisząc kod dla specyficznych zastosowań. Te fragmenty kodu mogą znajdować się w Flows lub mogą być funkcjami chmurowymi stron trzecich, takimi jak funkcje AWS Lambda lub Google Cloud Functions.

Interesujący przypadek użycia: rozpoznawanie obrazów 

Dla krótkiego i zabawnego przykładu, pokażę ci, jak zaimplementować aplikację, która rozpoznaje hot dogi. Skonfigurujemy przepływ w Flows, który będzie otrzymywał obrazy od użytkowników i decydował, czy przesłali hot doga, czy nie.

Dla wielu naszych klientów tego rodzaju rozpoznawanie obrazów może być bardzo potężne. Wyobraź sobie, że prowadzisz usługę dostawy i chcesz automatycznie weryfikować udane dostawy. Podobnie jak pokażę, możesz używać danych o lokalizacji, zdjęć paczek, a nawet podpisów odbiorców, aby stworzyć przepływ weryfikacji w Flows.

Plan na sukces

Najpierw skonfigurujemy funkcję chmurową, która otrzymuje żądanie z URL do obrazu, następnie używa API rozpoznawania obrazu do przetwarzania obrazu i odpowiada, czy na obrazie znajduje się hotdog, czy nie.

Następnie zbudujemy przepływ, który otrzymuje wiadomość od użytkownika za pośrednictwem kanału komunikacyjnego (w tym przypadku Telegram), wykonuje powyższą funkcję chmurową i odpowiada użytkownikowi, czy na przesłanym przez niego obrazku znajduje się hotdog.

Najpierw skonfigurujemy funkcję chmurową, która otrzymuje żądanie z URL do obrazu, następnie używa API rozpoznawania obrazu do przetwarzania obrazu i odpowiada, czy na obrazie znajduje się hotdog, czy nie.

Następnie zbudujemy przepływ, który otrzymuje wiadomość od użytkownika za pośrednictwem kanału komunikacyjnego (w tym przypadku Telegram), wykonuje powyższą funkcję chmurową i odpowiada użytkownikowi, czy na przesłanym przez niego obrazku znajduje się hotdog.

Najpierw skonfigurujemy funkcję chmurową, która otrzymuje żądanie z URL do obrazu, następnie używa API rozpoznawania obrazu do przetwarzania obrazu i odpowiada, czy na obrazie znajduje się hotdog, czy nie.

Następnie zbudujemy przepływ, który otrzymuje wiadomość od użytkownika za pośrednictwem kanału komunikacyjnego (w tym przypadku Telegram), wykonuje powyższą funkcję chmurową i odpowiada użytkownikowi, czy na przesłanym przez niego obrazku znajduje się hotdog.

Konfigurowanie Google Cloud Function

Najpierw musimy skonfigurować funkcję chmurową. Aby szybko rozpocząć, stwórz funkcję chmurową korzystając z tego samouczka: https://cloud.google.com/functions/docs/quickstart-console. Jako „Wyzwalacz” wybierz wyzwalacz HTTP, środowisko wykonawcze: Node.js 10, i w polu kod źródłowy wstaw fragment kodu. To prosty kod, który sprawdza, czy żądanie zawiera kod JSON i odpowiada tak lub nie. 

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


Następnie będziesz musiał wdrożyć tę funkcję. Aby przetestować ją w Google Cloud Platform, postępuj według kroków z samouczka. 

Aby przetestować z przeglądarki, przejdź do następującego adresu URL, wstawiając konkretny adres swojej funkcji:

https://your-function-address.cloudfunctions.net/HotDogOrNot/?url=hello powinno zwrócić {“isHotDog”: true}, a adres https://your-function-address.cloudfunctions.net/HotDogOrNot powinien zwrócić {“isHotDog”: false}.

Świetna robota! Skonfigurowałeś funkcję chmurową Google. Teraz musimy sprawić, by nasza funkcja chmurowa była mądrzejsza.

Konfigurowanie Google Vision API

Aby uczynić ją inteligentniejszą, dodajmy rozpoznawanie obrazów. Do tego celu użyjemy Google Vision API. Aby rozpocząć, wykonaj kroki 1-4 tego samouczka: https://cloud.google.com/vision/docs/quickstart-client-libraries. W samouczku aktywujesz Vision API i tworzysz konto serwisowe, aby z niego korzystać.

Teraz wróć do utworzonej funkcji w chmurze. Przełącz „Zmienne środowiskowe, sieciowe, limity czasu i inne” i w pliku „Konto usługi” wybierz konto VisionAPI, które właśnie utworzyłeś. Teraz możemy uzyskać dostęp do Vision API wewnątrz naszej funkcji.

Advanced options interface of a cloud service configuration.


Teraz zmieńmy kod. W zakładce „Package.json” wstaw ten kod. Doda on bibliotekę Google Vision API jako zależność do twojej funkcji.

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


W zakładce "Index.js" zaktualizuj istniejący kod za pomocą poniższego fragmentu kodu.

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


Jaka jest różnica w porównaniu do poprzedniej wersji? Dodaliśmy zapytanie do VisionAPI, które zwraca ‘etykiety’, jakie znalazł na obrazie.  Następnie filtrujemy te etykiety według opisu: czy zawiera „hot dog” i czy ma większą niż 60% pewność w tej etykiecie. Jeśli po filtracji pozostanie co najmniej 1 etykieta, oznacza to, że znaleźliśmy hot doga na obrazie.

Aby zrozumieć, jak działa Google VisionAPI i jak wygląda odpowiedź, sprawdź ich dokumentację, https://cloud.google.com/vision/docs

Po tym wdroż nową wersję naszej funkcji. Aby przetestować to z przeglądarki, znajdź dowolny obraz hot doga i zapisz jego URL. Teraz przejdź do adresu URL swojej funkcji (wpisując odpowiedni adres dla swojej funkcji) https://your-function-address.cloudfunctions.net/HotDogOrNot?url=url_to_image i zamień  „url_to_image” na URL znalezionego obrazu. Jeśli zdjęcie zawiera hot doga, strona zwróci {“isHotDog”: true}.

Teraz połączmy tę funkcję z Flow Builder.

Tworzenie flow w Flows

Zaloguj się do Bird Dashboard lub zarejestruj się, aby uzyskać konto, jeśli jeszcze go nie masz.

Jeśli jesteś nowy w Flows i nie masz żadnych skonfigurowanych kanałów, będziesz musiał przejść do strony konfiguracji kanału i wybrać konfigurację kanału Telegram. Dla tego demo wybrałem Telegram, ponieważ jest łatwy i szybki do skonfigurowania.

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


Teraz masz kanał, którego możemy użyć w Flows. Przejdź do strony Flows, utwórz nowy niestandardowy przepływ i wybierz wyzwalacz kanału „Telegram”.

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


Zostaniesz przekierowany na stronę przepływu, gdzie powinieneś wybrać swój kanał Telegram jako wyzwalacz, w naszym przypadku to „Hotdog”. Proszę dodać 2 kroki: „Fetch variables” i „Reply to channel message”.

W kroku „Fetch variables” wywołamy naszą funkcję w chmurze i pobierzemy odpowiedź do zmiennej „isHotDog”, która będzie zawierać odpowiedzi „true” lub „false” uzyskane z funkcji GoogleClound. W polu URL wstaw URL do swojej funkcji https://your-function-address.cloudfunctions.net/HotDogOrNot i wypełnij wszystkie inne pola zgodnie z obrazem „Fetch variable step content”.

A w kroku „Reply to channel message” odpowiemy klientowi wiadomością zawierającą odpowiedź tak lub nie. W tym celu wstaw w polu "Reply with message" następujący tekst „Hotdog na obrazie? {{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.

Jeśli masz jakiekolwiek problemy z tworzeniem przepływu, możesz użyć poniższego fragmentu:

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


Aby to przetestować, wyślij obraz do swojego bota Telegram.

Jak dotąd wygląda fajnie! Stworzyliśmy małego chat bota, który sprawdza obrazy przesłane przez klientów. Aby uczynić go ładniejszym, dodajmy kilka więcej kroków, jak pokazano poniżej: 


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


Jeśli masz jakiekolwiek problemy z tworzeniem przepływu, możesz użyć poniższego fragmentu:

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

Wyniki

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.


Chociaż jest to zabawny przykład, wierzymy, że tego typu funkcja może być bardzo przydatna dla naszych użytkowników. 

Jeśli chcesz, aby w Flows było więcej takich funkcji wbudowanych, napisz do naszego zespołu wsparcia, aby dać nam znać. 

Połączmy Cię z ekspertem Bird.
Zobacz pełną moc Bird w 30 minut.

Przesyłając, zgadzasz się, że Bird może kontaktować się z Tobą w sprawie naszych produktów i usług.

Możesz zrezygnować z subskrypcji w dowolnym momencie. Zobacz Privacy Statement firmy Bird, aby uzyskać szczegóły dotyczące przetwarzania danych.

Company

Biuletyn

Bądź na bieżąco z Bird dzięki cotygodniowym aktualizacjom do Twojej skrzynki odbiorczej.

Przesyłając, zgadzasz się, że Bird może kontaktować się z Tobą w sprawie naszych produktów i usług.

Możesz zrezygnować z subskrypcji w dowolnym momencie. Zobacz Privacy Statement firmy Bird, aby uzyskać szczegóły dotyczące przetwarzania danych.

Połączmy Cię z ekspertem Bird.
Zobacz pełną moc Bird w 30 minut.

Przesyłając, zgadzasz się, że Bird może kontaktować się z Tobą w sprawie naszych produktów i usług.

Możesz zrezygnować z subskrypcji w dowolnym momencie. Zobacz Privacy Statement firmy Bird, aby uzyskać szczegóły dotyczące przetwarzania danych.

Company

Biuletyn

Bądź na bieżąco z Bird dzięki cotygodniowym aktualizacjom do Twojej skrzynki odbiorczej.

Przesyłając, zgadzasz się, że Bird może kontaktować się z Tobą w sprawie naszych produktów i usług.

Możesz zrezygnować z subskrypcji w dowolnym momencie. Zobacz Privacy Statement firmy Bird, aby uzyskać szczegóły dotyczące przetwarzania danych.

Połączmy Cię z ekspertem Bird.
Zobacz pełną moc Bird w 30 minut.

Przesyłając, zgadzasz się, że Bird może kontaktować się z Tobą w sprawie naszych produktów i usług.

Możesz zrezygnować z subskrypcji w dowolnym momencie. Zobacz Privacy Statement firmy Bird, aby uzyskać szczegóły dotyczące przetwarzania danych.

R

Reach

G

Grow

M

Manage

A

Automate

Company

Biuletyn

Bądź na bieżąco z Bird dzięki cotygodniowym aktualizacjom do Twojej skrzynki odbiorczej.

Przesyłając, zgadzasz się, że Bird może kontaktować się z Tobą w sprawie naszych produktów i usług.

Możesz zrezygnować z subskrypcji w dowolnym momencie. Zobacz Privacy Statement firmy Bird, aby uzyskać szczegóły dotyczące przetwarzania danych.