كيف تستخدم Flows مع Google Vision API و Google Cloud Functions

منشئ التدفق

1 min read

كيف تستخدم Flows مع Google Vision API و Google Cloud Functions

منشئ التدفق

1 min read

كيف تستخدم Flows مع Google Vision API و Google Cloud Functions

تُعتبر Flows محرك أتمتة قوي يسمح بالسحب والإفلات لإنشاء تدفقات اتصالات. في البداية قمنا بتصميمه كحل بدون كود، لكننا وجدنا أن العديد من المستخدمين يمكنهم الحصول على سلوك قوي للغاية من خلال كتابة بعض الأكواد لحالات استخدام محددة. يمكن أن تكون هذه الأكواد داخل Flow Builder، أو يمكن أن تكون وظائف سحابية من جهات خارجية مثل وظائف AWS Lambda أو وظائف Google Cloud.

هذه مجرد مظاهرة بسيطة باستخدام GoogleCloud Functions وFlows للقيام بالتعرف على الصور للصورة المرسلة على Telegram.

التدفقات وما بعدها

بصفتي مطورًا لمخططات Flows، أفكر غالبًا في من هم مستخدمونا، ولماذا يستخدمون Flows، وما الذي يحتاجونه لتحقيق أهدافهم؛ ثم، ما هي الميزات التي نحتاج إلى تنفيذها لخدمة هؤلاء المستخدمين بأفضل شكل.




Flows هو محرك أتمتة قوي يعتمد على السحب والإفلات لإنشاء تدفقات التواصل. في البداية قمنا بتصميمه كحل بدون كود، لكننا وجدنا أن العديد من المستخدمين يمكنهم الحصول على سلوك قوي جدًا بكتابة بعض الأكواد لحالات الاستخدام الخاصة.   يمكن أن تكون هذه الأكواد داخل Flows، أو يمكن أن تكون وظائف سحابية من أطراف ثالثة مثل وظائف AWS Lambda أو Google Cloud Functions




حالة استخدام مثيرة للاهتمام: التعرف على الصور 

لكمثال قصير ومضحك، سأريك كيفية تنفيذ تطبيق يعرف النقانق. سنقوم بإعداد سير في Flows، والذي سيستقبل الصور من المستخدمين ويقرر ما إذا كانوا أرسلوا صورة نقانق أم لا.




بالنسبة للعديد من عملائنا، يمكن أن يكون هذا النوع من التعرف على الصور قويًا جدًا. تخيل أنك تدير خدمة توصيل وترغب في التحقق من إتمام التسليم تلقائيًا. مشابه لما سأعرضه، يمكنك استخدام بيانات الموقع، وصور الطرود، وحتى توقيعات المستلمين لإنشاء تدفق تحقق في Flows. 

خطة للنجاح

أولاً، سنقوم بإعداد وظيفة سحابية تستقبل طلبًا برابط لصورة، ثم تستخدم واجهة برمجة تطبيقات التعرف على الصور لمعالجة الصورة، وتستجيب ما إذا كان هناك هوت دوج في الصورة أم لا.




ثم سنقوم ببناء تدفق يتلقى رسالة من مستخدم عبر قناة رسائل (Telegram في هذه الحالة)، وينفذ الوظيفة السحابية أعلاه، ويستجيب للمستخدم ما إذا كان هناك هوت دوج في الصورة التي أرسلها.

أولاً، سنقوم بإعداد وظيفة سحابية تستقبل طلبًا برابط لصورة، ثم تستخدم واجهة برمجة تطبيقات التعرف على الصور لمعالجة الصورة، وتستجيب ما إذا كان هناك هوت دوج في الصورة أم لا.




ثم سنقوم ببناء تدفق يتلقى رسالة من مستخدم عبر قناة رسائل (Telegram في هذه الحالة)، وينفذ الوظيفة السحابية أعلاه، ويستجيب للمستخدم ما إذا كان هناك هوت دوج في الصورة التي أرسلها.

أولاً، سنقوم بإعداد وظيفة سحابية تستقبل طلبًا برابط لصورة، ثم تستخدم واجهة برمجة تطبيقات التعرف على الصور لمعالجة الصورة، وتستجيب ما إذا كان هناك هوت دوج في الصورة أم لا.




ثم سنقوم ببناء تدفق يتلقى رسالة من مستخدم عبر قناة رسائل (Telegram في هذه الحالة)، وينفذ الوظيفة السحابية أعلاه، ويستجيب للمستخدم ما إذا كان هناك هوت دوج في الصورة التي أرسلها.

إعداد وظيفة Google Cloud

أولاً، نحتاج إلى إعداد وظيفة سحابية. للبدء بسرعة، قم بإنشاء وظيفة سحابية باستخدام هذا الدليل: https://cloud.google.com/functions/docs/quickstart-console. كـ ‘Trigger’ اختر HTTP trigger، بيئة التنفيذ: Node.js 10، وفي حقل الشيفرة المصدرية أدخل قطعة الشيفرة. إنها شيفرة بسيطة، تتحقق مما إذا كان الطلب يحتوي على شيفرة JSON وتجيب بنعم أو لا. 




/**
 * 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، اتبع الخطوات من الدليل. 

لاختبارها من متصفحك، اذهب إلى عنوان URL التالي بإدخال العنوان المحدد لوظيفتك:




https://your-function-address.cloudfunctions.net/HotDogOrNot/?url=hello يجب أن يُرجع {“isHotDog”: true} والعنوان https://your-function-address.cloudfunctions.net/HotDogOrNot يجب أن يُرجع {“isHotDog”: false}.




عمل جيد! لقد قمت بإعداد وظيفة سحابية من Google. الآن نحتاج لجعل وظيفتنا السحابية أكثر ذكاءً.

إعداد واجهة برمجة تطبيقات Google Vision

لنجعله أكثر ذكاءً، دعونا نضيف التعرف على الصور. لهذا الغرض، سنستخدم Google Vision API. للبدء، اتبع الخطوات من 1-4 في هذا الدليل: https://cloud.google.com/vision/docs/quickstart-client-libraries. في الدليل، ستقوم بتفعيل Vision API وإنشاء حساب خدمة لاستخدامه.




الآن عد إلى الوظيفة السحابية التي أنشأتها. حرك "بيئة المتغيرات، الشبكات، المهلات والمزيد" وفي ملف "حساب الخدمة" اختر حساب خدمة VisionAPI الذي قمت بإنشائه للتو. الآن يمكننا الوصول إلى Vision API داخل وظيفتنا.







الآن دعونا نغير الكود. في علامة تبويب "Package.json"، أدخل هذا الكود. سيضيف مكتبة Google Vision API كاعتماد لوظيفتك.

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




في علامة التبويب "Index.js" قم بتحديث الكود الموجود بالمقتطف التالي.

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










ما الفرق مقارنة بالإصدار السابق؟ لقد أضفنا طلب إلى VisionAPI، والذي يعيد ‘التسميات’ التي وجدها على الصورة.  ثم نقوم بتصفية هذه التسميات حسب الوصف: إذا كان يتضمن "هوت دوغ" وإذا كان لديه أكثر من 60% من الثقة في تلك التسمية. إذا كان هناك على الأقل تسمية واحدة متبقية بعد التصفية، فهذا يعني أننا وجدنا هوت دوغ على الصورة.




لفهم كيفية عمل Google VisionAPI وكيف يبدو الاستجابة، راجع توثيقهم، https://cloud.google.com/vision/docs




بعد ذلك، قم بنشر الإصدار الجديد من وظيفتنا. لاختباره من متصفحك، ابحث عن أي صورة لهوت دوغ واحفظ عنوان URL الخاص بها. الآن اذهب إلى URL  الخاص بوظيفتك (بإدخال العنوان الصحيح لوظيفتك) https://your-function-address.cloudfunctions.net/HotDogOrNot?url=url_to_image واستبدل   "url_to_image" بعنوان URL للصورة التي وجدتها. إذا كان هناك هوت دوغ في الصورة، ستظهر الصفحة {“isHotDog”: true}.




الآن دعونا نوصل هذه الوظيفة إلى Flow Builder.

إنشاء تدفق في Flows

قم بتسجيل الدخول إلى لوحة التحكم الخاصة بـBird أو اشترك للحصول على حساب إذا لم يكن لديك حساب.




إذا كنت جديداً على Flows وليس لديك أي قنوات معدة، ستحتاج إلى الذهاب إلى صفحة إعداد القناة، واختيار إعداد قناة تليجرام. لقد اخترت تليجرام لهذا العرض لأنه سهل وسريع الإعداد.







الآن لديك قناة يمكننا استخدامها في Flows. انتقل إلى صفحة Flows، وقم بإنشاء تدفق مخصص جديد، واختر قناة "Telegram" كعامل محفز.







سيتم إعادة توجيهك إلى صفحة التدفق، حيث يجب أن تختار قناة تليجرام الخاصة بك كعامل محفز، في حالتنا هي "Hotdog". يرجى إضافة خطوتين: "جلب المتغيرات" و"الرد على رسالة القناة".




داخل خطوة "جلب المتغيرات" سوف نقوم باستدعاء دالة السحابة الخاصة بنا واسترجاع الرد في متغير "isHotDog" الذي سيحتوي على "true" أو "false" كرد من دالة جوجل السحابية. في حقل URL يرجى إدخال URL لوظيفتك https://your-function-address.cloudfunctions.net/HotDogOrNot وملء جميع الحقول الأخرى كما في الصورة "محتوى خطوة جلب المتغير".




وفي داخل خطوة "الرد على رسالة القناة" سوف نرد على العميل برسالة تحتوي على إجابة نعم أو لا. لذلك قم بإدراج في حقل "الرد بالرسالة" النص التالي "هل يوجد Hotdog في الصورة؟ {{isHotDog}}".







إذا واجهت أي مشكلة في بناء التدفق، يمكنك استخدام المقتطف التالي:

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







لاختباره، أرسل صورة إلى البوت الخاص بك على تليجرام.

حتى الآن، يبدو الأمر رائعاً! لقد أنشأنا بوت دردشة صغير يتحقق من الصور التي يرسلها العملاء. لجعلها أجمل، لنضف بعض الخطوات الأخرى كما هو موضح أدناه: 







إذا واجهت أي مشكلة في بناء التدفق، يمكنك استخدام المقتطف التالي:

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

النتائج




بينما يعد هذا مثالاً ممتعًا، نعتقد أن هذا النوع من الوظائف يمكن أن يكون مفيدًا جدًا لمستخدمينا. 

إذا كنت تريد المزيد من الميزات مثل هذه المدمجة في Flows، فاكتب إلى فريق الدعم لدينا لإعلامنا. 

دعنا نوصلك بخبير من Bird.
رؤية القوة الكاملة لـ Bird في 30 دقيقة.

بتقديمك طلبًا، فإنك توافق على أن تقوم Bird بالاتصال بك بشأن منتجاتنا وخدماتنا.

يمكنك إلغاء الاشتراك في أي وقت. انظر بيان الخصوصية الخاص بـ Bird للتفاصيل حول معالجة البيانات.

النشرة الإخبارية

ابقَ على اطلاع مع Bird من خلال التحديثات الأسبوعية إلى بريدك الوارد.

بتقديمك طلبًا، فإنك توافق على أن تقوم Bird بالاتصال بك بشأن منتجاتنا وخدماتنا.

يمكنك إلغاء الاشتراك في أي وقت. انظر بيان الخصوصية الخاص بـ Bird للتفاصيل حول معالجة البيانات.

دعنا نوصلك بخبير من Bird.
رؤية القوة الكاملة لـ Bird في 30 دقيقة.

بتقديمك طلبًا، فإنك توافق على أن تقوم Bird بالاتصال بك بشأن منتجاتنا وخدماتنا.

يمكنك إلغاء الاشتراك في أي وقت. انظر بيان الخصوصية الخاص بـ Bird للتفاصيل حول معالجة البيانات.

النشرة الإخبارية

ابقَ على اطلاع مع Bird من خلال التحديثات الأسبوعية إلى بريدك الوارد.

بتقديمك طلبًا، فإنك توافق على أن تقوم Bird بالاتصال بك بشأن منتجاتنا وخدماتنا.

يمكنك إلغاء الاشتراك في أي وقت. انظر بيان الخصوصية الخاص بـ Bird للتفاصيل حول معالجة البيانات.

دعنا نوصلك بخبير من Bird.
رؤية القوة الكاملة لـ Bird في 30 دقيقة.

بتقديمك طلبًا، فإنك توافق على أن تقوم Bird بالاتصال بك بشأن منتجاتنا وخدماتنا.

يمكنك إلغاء الاشتراك في أي وقت. انظر بيان الخصوصية الخاص بـ Bird للتفاصيل حول معالجة البيانات.

R

وصول

G

نمو

م

إدارة

A

أتمتة

النشرة الإخبارية

ابقَ على اطلاع مع Bird من خلال التحديثات الأسبوعية إلى بريدك الوارد.

بتقديمك طلبًا، فإنك توافق على أن تقوم Bird بالاتصال بك بشأن منتجاتنا وخدماتنا.

يمكنك إلغاء الاشتراك في أي وقت. انظر بيان الخصوصية الخاص بـ Bird للتفاصيل حول معالجة البيانات.