تدريب عملي: إنشاء إجراء في دليل التلفزيون لـ "مساعد Google" باستخدام Dialogflow و"المهام مع مساعد Google"

1. مقدمة

أنت تشاهد التلفزيون، ولكن لا يمكنك العثور على جهاز التحكّم عن بُعد، أو ربما لا تريد زيارة كل قناة تلفزيونية لمعرفة ما إذا كان هناك محتوى جميل على التلفزيون؟ لنسأل "مساعد Google" عن المحتوى الذي يُعرض على التلفزيون. ستنشئ في هذا التمرين المعملي إجراءً بسيطًا باستخدام Dialogflow وستتعلم كيفية دمجه مع مساعد Google.

يتم ترتيب التمارين لتعكس التجربة الشائعة لمطوّر برامج السحابة الإلكترونية:

  1. إنشاء وكيل Dialogflow v2
  2. إنشاء كيان مخصّص
  3. إنشاء الأهداف
  4. إعداد ردّ تلقائي على الويب باستخدام وظائف Firebase
  5. اختبار روبوت الدردشة
  6. تفعيل دمج "مساعد Google"

ما ستقوم بإنشائه

سننشئ وكيل دردشة مبرمجة تفاعلي لـ "مساعد Google". يمكنك الاستفسار من دليل التلفزيون عن المحتوى الذي يتم بثه حاليًا على قناة معيّنة. على سبيل المثال: "ما الذي يتم عرضه على MTV؟" سيخبرك الإجراء "دليل التلفزيون" بالمحتوى الذي يتم تشغيله حاليًا والمحتوى الذي سيُعرَض بعد ذلك.

المعلومات التي ستطّلع عليها

  • كيفية إنشاء روبوت دردشة باستخدام الإصدار 2 من Dialogflow
  • كيفية إنشاء كيانات مخصّصة باستخدام Dialogflow
  • كيفية إنشاء محادثة خطية باستخدام Dialogflow
  • كيفية إعداد عمليات تنفيذ الردّ التلقائي على الويب باستخدام دوال Dialogflow وFirebase
  • كيفية نقل تطبيقك إلى "مساعد Google" باستخدام "المهام مع مساعد Google"

المتطلبات الأساسية

  • ستحتاج إلى عنوان Google Identity أو Gmail لإنشاء وكيل Dialogflow.
  • لست بحاجة إلى المعرفة الأساسية بلغة JavaScript، ولكن يمكن أن تكون مفيدة في حال أردت تغيير رمز تنفيذ الردّ التلقائي على الويب.

2. بدء الإعداد

تفعيل "النشاط على الويب" في المتصفّح

  1. انقر على: http://myaccount.google.com/activitycontrols.

  1. تأكد من أن الويب & تفعيل النشاط على التطبيقات:

bf8d16b828d6f79a.png

إنشاء وكيل Dialogflow

  1. افتح: https://console.dialogflow.com

  1. في الشريط الأيمن، أسفل الشعار مباشرةً، اختَر "إنشاء وكيل جديد". إذا كان لديك موظّفو دعم حاليون، انقر على القائمة المنسدلة أولاً.

1d7c2b56a1ab95b8.png

  1. تحديد اسم وكيل: your-name-tvguide (استخدِم اسمك الخاص)

35237b5c5c539ecc.png

  1. كلغة تلقائية، اختَر: الإنجليزية - en
  2. اختَر المنطقة الزمنية الأقرب إليك كمنطقة زمنية تلقائية.
  3. انقر على إنشاء

ضبط Dialogflow

  1. انقر على رمز الترس في القائمة اليمنى بجانب اسم مشروعك.

1d7c2b56a1ab95b8.png

  1. أدخِل وصف الوكيل التالي: دليل التلفزيون.

26f262d359c49075.png

  1. انتقِل للأسفل إلى Log Settings (إعدادات السجلّ) وبدِّل مفتاحَي التبديل لتسجيل تفاعلات Dialogflow وتسجيل جميع التفاعلات في Google Cloud Stackdriver. سنحتاج إلى هذا الإجراء لاحقًا في حال أردنا تصحيح أخطاء الإجراء.

e80c17acc3cce993.png

  1. انقر على حفظ.

ضبط "المهام مع مساعد Google"

  1. النقر على رابط مساعد Google في القسم التعرّف على طريقة عمله في "مساعد Google" في اللوحة اليسرى

5a4940338fc351e3.png

سيؤدي هذا الإجراء إلى فتح: http://console.actions.google.com

عندما تكون مستخدمًا جديدًا لبرنامج "المهام مع مساعد Google"، عليك ملء هذا النموذج أولاً:

3fd4e594fa169072.png

  1. حاول فتح الإجراء في المحاكي**، من خلال النقر على اسم المشروع.**
  2. اختَر اختبار في شريط القوائم.

6adb83ffb7adeb78.png

  1. تأكَّد من ضبط المحاكي على الإنجليزية وانقر على التحدث إلى التطبيق التجريبي.

سيتم الترحيب بك باستخدام الهدف التلقائي الأساسي من Dialogflow. وهذا يعني أنّ عملية إعداد عملية الدمج مع "المهام مع مساعد Google" قد نجحت.

3- الكيانات المخصصة

الكيانات هي الكائنات التي يتخذ تطبيقك أو جهازك إجراءات بشأنها. اعتبرها كمعاملات / متغيرات. سنسألك في دليل التلفزيون: "ماذا يُعرض على MTV". يمثل MTV الكيان والمتغير. يمكنني طلب قنوات أخرى أيضًا، مثل "ناشيونال جيوغرافيك" أو "Comedy Central". سيتم استخدام الكيان الذي تم جمعه كمعلمة في طلبي إلى خدمة الويب لـ TV Guide API.

إليك مزيد من المعلومات حول كيانات Dialogflow.

إنشاء كيان القناة

  1. انقر على وحدة تحكُّم Dialogflow داخل عنصر القائمة: الكيانات.
  2. انقر على إنشاء كيان.
  3. اسم الكيان: channel (يُرجى التأكد من أن كل أحرفه صغيرة)
  4. إدخال اسم القناة (تحتاج بعض القنوات إلى مرادف إذا كان "مساعد Google" يفهم شيئًا آخر). يمكنك استخدام علامة التبويب وإدخال المفاتيح أثناء الكتابة. يُرجى إدخال رقم القناة كقيمة مرجع. وتكون أسماء القنوات كمرادفات، مثل:
  • 1 - 1, Net 1, Net Station 1

ee4e4955aa77232d.png

5**.** بدِّل إلى وضع **التعديل الأولي** من خلال النقر على زر القائمة إلى جانب زر الحفظ الأزرق.

e294b49b123e034f.png

  1. نسخ & الصق الكيانات الأخرى بتنسيق CSV:
"2","2","Net 2, Net Station 2"
"3","3","Net 3, Net Station 3"
"4","4","RTL 4"
"5","5","Movie Channel"
"6","6","Sports Channel"
"7","7","Comedy Central"
"8","8","Cartoon Network"
"9","9","National Geographic"
"10","10","MTV"

ed78514afd5badef.png

  1. انقر على حفظ.

4. مكان ووقت الاستماع إلى الموسيقى

تستخدم منصة Dialogflow ميزة intents لتصنيف نوايا المستخدم. تتضمّن الأهداف عبارات تدريب، وهي أمثلة على ما قد يقوله المستخدم لوكيلك. على سبيل المثال، إذا أراد المستخدم معرفة المحتوى المعروض على التلفزيون، قد يسأله مثلاً "ما هو المحتوى المعروض على التلفزيون اليوم؟". "ما الذي يتم تشغيله حاليًا؟" أو يمكنك ببساطة قول "دليل التلفزيون".

عندما يكتب مستخدم طلبًا أو يقوله، يُشار إليه باسم تعبير المستخدم، يطابق Dialogflow تعبير المستخدم مع أفضل نيّة في الوكيل. تُعرف مطابقة النية أيضًا باسم تصنيف القصد.

إليك مزيد من المعلومات حول عناصر Dialogflow.

تعديل هدف الترحيب التلقائي

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

  1. انقر على هدف الترحيب التلقائي.

في حالة استخدام "مساعد Google"، سيبدأ تلقائيًا بهدف الترحيب التلقائي. ويرجع ذلك إلى أنّ Dialogflow يستمع إلى الحدث الترحيبي. ومع ذلك، يمكنك أيضًا استدعاء الغرض من خلال قول إحدى عبارات التدريب التي تم إدخالها.

6beee64e8910b85d.png

في ما يلي رسالة الترحيب لهدف الترحيب التلقائي:

المستخدم

موظّف دعم

"Ok Google، أريد التحدّث إلى دليل التلفزيون"

"مرحبًا، أنا موظف دليل البرامج التلفزيونية. يمكنني إطلاعك على المحتوى الذي يتم بثه حاليًا على قناة تلفزيونية. مثلاً، يمكنكَ أن تسألني: ماذا يُعرض على MTV."

  1. انتقِل للأسفل إلى الردود.
  2. محو كل الردود النصية.
  3. أنشئ ردًا نصيًا جديدًا، يحتوي على رسالة الترحيب التالية:

Welcome, I am the TV Guide agent. I can tell you what's currently playing on a TV channel. For example, you can ask me: What's on MTV?

84a1110a7f7edba2.png

  1. انقر على حفظ.

إنشاء هدف تجريبي مؤقت

لأغراض الاختبار، سننشئ نية اختبار مؤقتة، حتى نتمكّن من اختبار الردّ التلقائي على الويب لاحقًا.

  1. انقر على عنصر قائمة Intents مرة أخرى.
  2. انقر على إنشاء هدف.
  3. أدخِل اسم Intent: Test Intent (تأكد من استخدام حرف T كبير وحرف I كبير. - إذا كتبت الغرض بطريقة مختلفة، لن تعمل خدمة الواجهة الخلفية.)

925e02caa4de6b99.png

  1. انقر على إضافة عبارات تدريب.
  • Test my agent
  • Test intent

2e44ddb2fae3c841.png

  1. انقر على التوصيل >. تفعيل توصيل الطلبات

7eb73ba04d76140e.png

هذه المرة لن يتم إجراء ترميز ثابت للاستجابة. ستأتي الإجابة من دالة سحابية!

  1. غيِّر مفتاح التبديل تفعيل ميزة الرد التلقائي على الويب لهذا الغرض.

748a82d9b4d7d253.png

  1. انقر على حفظ.

إنشاء هدف القناة

سيتضمّن هدف القناة هذا الجزء من المحادثة:

المستخدم

موظّف دعم

"ما الذي يتم عرضه على Simply Central؟"

"حاليًا على قناة "Comedy Central" من الساعة 6 مساءً، يتم بث فيلم The Simpsons. بعد ذلك، سيبدأ فتى العائلة في الساعة 7 مساءً."

  1. انقر على عنصر قائمة Intents مرة أخرى.
  2. انقر على إنشاء هدف.
  3. أدخِل اسم Intent: Channel Intent (تأكّد من استخدام حرف T كبير وحرف I كبير. - إذا كتبت الغرض بطريقة مختلفة، لن تعمل خدمة الواجهة الخلفية.)
  4. انقر على إضافة عبارات تدريب وأضِف ما يلي:
  • What's on MTV?
  • What's playing on Comedy Central?
  • What show will start at 8 PM on National Geographic?
  • What is currently on TV?
  • What is airing now.
  • Anything airing on Net Station 1 right now?
  • What can I watch at 7 PM?
  • What's on channel MTV?
  • What's on TV?
  • Please give me the tv guide.
  • Tell me what is on television.
  • What's on Comedy Central from 10 AM?
  • What will be on tv at noon?
  • Anything on National Geographic?
  • TV Guide

6eee02db02831397.png

  1. انتقِل إلى الإجراء والمَعلمات في أسفل الصفحة

b7e917026760218a.png

يُرجى الانتباه إلى ما يلي: @channel كيانات @sys.time المعروفة باسم Dialogflow. وفي وقت لاحق من الردّ التلقائي على الويب، سيتم إرسال اسم المَعلمة وقيمة المَعلمة إلى خدمة الويب لديك. على سبيل المثال:

channel=8

time=2020-01-29T19:00:00+01:00

  1. وضع علامة على القناة كمطلوبة

عند إجراء محادثة مع موظّف دعم "دليل التلفزيون"، عليك دائمًا ملء اسم مَعلمة الخانة channel. إذا لم يتم ذكر اسم القناة في بداية المحادثة، سيطرح Dialogflow المزيد من الأسئلة إلى أن يملأ كل خانات المَعلمات. 6f36973fd789c182.png

كطلب، أدخِل ما يلي:

  • For which TV channel do you want to hear the tv guide information?
  • In which TV channel are you interested?

cdb5601ead9423f8.png

  1. لا تضبط مَعلمة الوقت على أنّها مطلوبة.

سيكون الوقت اختياريًا. عند عدم تحديد وقت، ستعرض خدمة الويب الوقت الحالي.

  1. انقر على توصيل الطلب.

هذه المرة لن يتم إجراء ترميز ثابت للاستجابة. سيأتي الرد من دالة السحابة! وبالتالي، بدِّل مفتاح تفعيل طلب الردّ التلقائي على الويب لهذا الغرض.

  1. انقر على حفظ.

5- تنفيذ الرد التلقائي على الويب

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

  1. انقر على توصيل الطلبات في القائمة الرئيسية.
  2. تفعيل مفتاح تبديل المحرِّر المضمّن

cc84351f0d03ab6f.png

لإجراء اختبار تلقائي للردّ التلقائي على الويب وتنفيذه، يمكنك استخدام المحرِّر المضمّن. وتستفيد هذه الخدمة من وظائف السحابة الإلكترونية لبرنامج Firebase بدون خادم.

  1. انقر على علامة التبويب index.js في المحرِّر وانسخ هذا الجزء من JavaScript والصقه في رمز Node.js:
'use strict';

process.env.DEBUG = 'dialogflow:debug';

const {
  dialogflow,
  BasicCard,
  Button,
  Image,
  List
 } = require('actions-on-google');

const functions = require('firebase-functions');
const moment = require('moment');
const TVGUIDE_WEBSERVICE = 'https://tvguide-e4s5ds5dsa-ew.a.run.app/channel';
const { WebhookClient } = require('dialogflow-fulfillment');
var spokenText = '';
var results = null;


/* When the Test Intent gets invoked. */
function testHandler(agent) {
    let spokenText = 'This is a test message, when you see this, it means your webhook fulfillment worked!';

    if (agent.requestSource === agent.ACTIONS_ON_GOOGLE) {
        let conv = agent.conv();
        conv.ask(spokenText);
        conv.ask(new BasicCard({
            title: `Test Message`,
            subTitle: `Dialogflow Test`,
            image: new Image({
                url: 'https://dummyimage.com/600x400/000/fff',
                alt: 'Image alternate text',
            }),
            text: spokenText,
            buttons: new Button({
                title: 'This is a button',
                url: 'https://assistant.google.com/',
            }),
        }));
        // Add Actions on Google library responses to your agent's response
        agent.add(conv);
    } else {
        agent.add(spokenText);
    }
}

/* When the Channel Intent gets invoked. */
function channelHandler(agent) {
    var jsonResponse = `{"ID":10,"Listings":[{"Title":"Catfish Marathon","Date":"2018-07-13","Time":"11:00:00"},{"Title":"Videoclips","Date":"2018-07-13","Time":"12:00:00"},{"Title":"Pimp my ride","Date":"2018-07-13","Time":"12:30:00"},{"Title":"Jersey Shore","Date":"2018-07-13","Time":"13:00:00"},{"Title":"Jersey Shore","Date":"2018-07-13","Time":"13:30:00"},{"Title":"Daria","Date":"2018-07-13","Time":"13:45:00"},{"Title":"The Real World","Date":"2018-07-13","Time":"14:00:00"},{"Title":"The Osbournes","Date":"2018-07-13","Time":"15:00:00"},{"Title":"Teenwolf","Date":"2018-07-13","Time":"16:00:00"},{"Title":"MTV Unplugged","Date":"2018-07-13","Time":"16:30:00"},{"Title":"Rupauls Drag Race","Date":"2018-07-13","Time":"17:30:00"},{"Title":"Ridiculousness","Date":"2018-07-13","Time":"18:00:00"},{"Title":"Punk'd","Date":"2018-07-13","Time":"19:00:00"},{"Title":"Jersey Shore","Date":"2018-07-13","Time":"20:00:00"},{"Title":"MTV Awards","Date":"2018-07-13","Time":"20:30:00"},{"Title":"Beavis & Butthead","Date":"2018-07-13","Time":"22:00:00"}],"Name":"MTV"}`;
    var results = JSON.parse(jsonResponse);
    var listItems = {};
    spokenText = getSpeech(results);

    for (var i = 0; i < results['Listings'].length; i++) {
        listItems[`SELECT_${i}`] = {
            title: `${getSpokenTime(results['Listings'][i]['Time'])} - ${results['Listings'][i]['Title']}`,
            description: `Channel: ${results['Name']}`
        }
    }
    if (agent.requestSource === agent.ACTIONS_ON_GOOGLE) {
        let conv = agent.conv();
        conv.ask(spokenText);
        conv.ask(new List({
            title: 'TV Guide',
            items: listItems
        }));
        // Add Actions on Google library responses to your agent's response
        agent.add(conv);
    } else {
        agent.add(spokenText);
    }
}

/**
 * Return a text string to be spoken out by the Google Assistant
 * @param {object} JSON tv results
 */
var getSpeech = function(tvresults) {
    let s = "";
    if(tvresults['Listings'][0]) {
        let channelName = tvresults['Name'];
        let currentlyPlayingTime = getSpokenTime(tvresults['Listings'][0]['Time']);
        let laterPlayingTime = getSpokenTime(tvresults['Listings'][1]['Time']);
        s = `On ${channelName} from ${currentlyPlayingTime}, ${tvresults['Listings'][0]['Title']} is playing.
        Afterwards at ${laterPlayingTime}, ${tvresults['Listings'][1]['Title']} will start.`
    }

    return s;
}

/**
 * Return a natural spoken time
 * @param {string} time in 'HH:mm:ss' format
 * @returns {string} spoken time (like 8 30 pm i.s.o. 20:00:00)
 */
var getSpokenTime = function(time){
    let datetime = moment(time, 'HH:mm:ss');
    let min = moment(datetime).format('m');
    let hour = moment(datetime).format('h');
    let partOfTheDay = moment(datetime).format('a');

    if (min == '0') {
        min = '';
    }

    return `${hour} ${min} ${partOfTheDay}`;
};

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
    var agent = new WebhookClient({ request, response });

    console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
    console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
   
    let channelInput = request.body.queryResult.parameters.channel;
    let requestedTime = request.body.queryResult.parameters.time;
    let url = `${TVGUIDE_WEBSERVICE}/${channelInput}`;

    var intentMap = new Map();
    intentMap.set('Test Intent', testHandler);
    intentMap.set('Channel Intent', channelHandler);
    agent.handleRequest(intentMap);
});

cc84351f0d03ab6f.png

  1. انقر على علامة التبويب package.json في المحرِّر وانسخ هذا الجزء من رمز JSON ولصقه:
{
  "name": "tvGuideFulfillment",
  "description": "Requesting TV Guide information from a web service.",
  "version": "1.0.0",
  "private": true,
  "license": "Apache Version 2.0",
  "author": "Google Inc.",
  "engines": {
    "node": "8"
  },
  "scripts": {
    "start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
    "deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
  },
  "dependencies": {
    "actions-on-google": "^2.2.0",
    "firebase-admin": "^5.13.1",
    "firebase-functions": "^2.0.2",
    "request": "^2.85.0",
    "request-promise": "^4.2.5",
    "moment" : "^2.24.0",
    "dialogflow-fulfillment": "^0.6.1"
  }
}

af01460c2a023e68.png

  1. انقر على الزر نشر. سيستغرق الأمر بعض الوقت، لأنها تنشر الدالة بدون خادم. ستظهر نافذة منبثقة أسفل الشاشة تخبرك بحالتك.
  2. لنختبر الردّ التلقائي على الويب لمعرفة ما إذا كان الرمز يعمل أم لا. في المحاكي على الجانب الأيسر، اكتب:

Test my agent.

عندما تكون كل المعلومات صحيحة، من المفترض أن تظهر لك: "هذه رسالة اختبار".

  1. لنختبر هدف القناة، والآن اطرح السؤال التالي:

What's on MTV?

عندما تكون كل المعلومات صحيحة، من المفترض أن يظهر لك ما يلي:

"على MTV بدءًا من الساعة 4:30 بعد الظهر، يتم تشغيل MTV Unplugged. وبعد ذلك، سيبدأ "سباق روبولز للدراغ" عند الساعة 5:30 مساءً".

الخطوات الاختيارية - Firebase

عند اختبار ذلك باستخدام قناة مختلفة، ستلاحظ أنّ نتائج التلفزيون هي نفسها. وذلك لأن الدالة السحابية لا تجلب من خادم ويب حقيقي حتى الآن.

لتحقيق ذلك، سنحتاج إلى إنشاء اتصال شبكة خارجي.

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

  1. انتقِل إلى "وحدة تحكُّم Firebase" : https://console.firebase.google.com

  1. في أسفل الشاشة، اضغط على الزرّ ترقية.

ad38bc6d07462abf.png

اختَر الخطة Blaze في النافذة المنبثقة.

  1. الآن بعد أن تأكّدنا من أنّ الردّ التلقائي على الويب يعمل، يمكننا المتابعة واستبدال رمز index.js بالرمز التالي. سيضمن هذا الإجراء إمكانية طلب معلومات دليل التلفزيون من خدمة الويب:
'use strict';

process.env.DEBUG = 'dialogflow:debug';

const {
  dialogflow,
  BasicCard,
  Button,
  Image,
  List
 } = require('actions-on-google');

const functions = require('firebase-functions');
const moment = require('moment');
const { WebhookClient } = require('dialogflow-fulfillment');
const rp = require('request-promise');

const TVGUIDE_WEBSERVICE = 'https://tvguide-e4s5ds5dsa-ew.a.run.app/channel';
var spokenText = '';
var results = null;


/* When the Test Intent gets invoked. */
function testHandler(agent) {
    let spokenText = 'This is a test message, when you see this, it means your webhook fulfillment worked!';

    if (agent.requestSource === agent.ACTIONS_ON_GOOGLE) {
        let conv = agent.conv();
        conv.ask(spokenText);
        conv.ask(new BasicCard({
            title: `Test Message`,
            subTitle: `Dialogflow Test`,
            image: new Image({
                url: 'https://dummyimage.com/600x400/000/fff',
                alt: 'Image alternate text',
            }),
            text: spokenText,
            buttons: new Button({
                title: 'This is a button',
                url: 'https://assistant.google.com/',
            }),
        }));
        // Add Actions on Google library responses to your agent's response
        agent.add(conv);
    } else {
        agent.add(spokenText);
    }
}

/* When the Channel Intent gets invoked. */
function channelHandler(agent) {
    var listItems = {};
    spokenText = getSpeech(results);

    for (var i = 0; i < results['Listings'].length; i++) {
        listItems[`SELECT_${i}`] = {
            title: `${getSpokenTime(results['Listings'][i]['Time'])} - ${results['Listings'][i]['Title']}`,
            description: `Channel: ${results['Name']}`

        }
    }
    if (agent.requestSource === agent.ACTIONS_ON_GOOGLE) {
        let conv = agent.conv();
        conv.ask(spokenText);
        conv.ask(new List({
            title: 'TV Guide',
            items: listItems
        }));
        // Add Actions on Google library responses to your agent's response
        agent.add(conv);
    } else {
        agent.add(spokenText);
    }
}

/**
 * Return a text string to be spoken out by the Google Assistant
 * @param {object} JSON tv results
 */
var getSpeech = function(tvresults) {
    let s = "";
    if(tvresults && tvresults['Listings'][0]) {
        let channelName = tvresults['Name'];
        let currentlyPlayingTime = getSpokenTime(tvresults['Listings'][0]['Time']);
        let laterPlayingTime = getSpokenTime(tvresults['Listings'][1]['Time']);
        s = `On ${channelName} from ${currentlyPlayingTime}, ${tvresults['Listings'][0]['Title']} is playing.
        Afterwards at ${laterPlayingTime}, ${tvresults['Listings'][1]['Title']} will start.`
    }

    return s;
}

/**
 * Return a natural spoken time
 * @param {string} time in 'HH:mm:ss' format
 * @returns {string} spoken time (like 8 30 pm i.s.o. 20:00:00)
 */
var getSpokenTime = function(time){
    let datetime = moment(time, 'HH:mm:ss');
    let min = moment(datetime).format('m');
    let hour = moment(datetime).format('h');
    let partOfTheDay = moment(datetime).format('a');

    if (min == '0') {
        min = '';
    }

    return `${hour} ${min} ${partOfTheDay}`;
};

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
    var agent = new WebhookClient({ request, response });

    console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
    console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
   
    let channelInput = request.body.queryResult.parameters.channel;
    let requestedTime = request.body.queryResult.parameters.time;
    let url = `${TVGUIDE_WEBSERVICE}/${channelInput}`;

    if (requestedTime) {
        console.log(requestedTime);
        let offsetMin = moment().utcOffset(requestedTime)._offset;
        console.log(offsetMin);
        let time = moment(requestedTime).utc().add(offsetMin,'m').format('HH:mm:ss');
        url = `${TVGUIDE_WEBSERVICE}/${channelInput}/${time}`;
      }
    
      console.log(url);
  
      var options = {
          uri: encodeURI(url),
          json: true
      };
       
      // request promise calls an URL and returns the JSON response.
      rp(options)
        .then(function(tvresults) {
            console.log(tvresults);
            // the JSON response, will need to be formatted in 'spoken' text strings.
            spokenText = getSpeech(tvresults);
            results = tvresults;
        })
        .catch(function (err) {
            console.error(err);
        })
        .finally(function(){
            // kick start the Dialogflow app
            // based on an intent match, execute
            var intentMap = new Map();
            intentMap.set('Test Intent', testHandler);
            intentMap.set('Channel Intent', channelHandler);
            agent.handleRequest(intentMap);
        });
});

6- تنفيذ المهام في "مساعد Google"

المهام مع مساعد Google هي منصة تطوير لخدمة "مساعد Google". تتيح تطوير "الإجراءات" التابعة لجهات خارجية، وهي تطبيقات صغيرة لخدمة "مساعد Google" توفّر وظائف موسّعة.

ستحتاج إلى استدعاء إجراء من خلال Google من خلال مطالبة Google بفتح تطبيق أو التحدث إليه.

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

اختبار الحركة في محاكي "مساعد Google"

لنختبر المحادثة التالية:

المستخدم

مساعد Google

"Ok Google، أريد التحدّث إلى your-name-tv-guide"

"بالتأكيد. دعني أطلب منك your-name-tv-guide".

المستخدم

موظّف دعم في برنامج المساعدة على التلفزيون

-

"مرحبًا، أنا دليل التلفزيون...."

اختبار وكيلي

"هذه رسالة اختبار. عندما ترى ذلك، يعني ذلك أنّ تنفيذ الرد التلقائي على الويب قد تمت بنجاح".

ما الذي يتم عرضه على MTV؟

سيبدأ عرض قناة MTV Unplugged على قناة MTV بدءًا من الساعة 4:30 بعد الظهر. وبعد ذلك، سيبدأ سباق "الدراغ" لروبولز عند الساعة 5:30 مساءً.

  1. التبديل إلى محاكي "مساعد Google"

افتح: https://console.actions.google.com

  1. انقر على رمز الميكروفون واسأل نفسك ما يلي:

c3b200803c7ba95e.png

  • Talk to my test agent
  • Test my agent

يجب أن يستجيب "مساعد Google" بما يلي:

5d93c6d037c8c8eb.png

  1. الآن، دعنا نسأل:
  • What's on Comedy Central?

من المفترض أن يؤدي هذا الإجراء إلى:

يبدأ مسلسل The Simpsons من الساعة 6 مساءً من الساعة 6 مساءً بتوقيت المنطقة الزمنية الوسطى. وبعد ذلك الساعة 7 مساءً، سيبدأ رجل العائلة.

7. تهانينا

أحسنت، لقد أنشأت أول إجراء لك على "مساعد Google" باستخدام Dialogflow.

كما لاحظت، كان الإجراء قيد التنفيذ في وضع الاختبار المرتبط بحسابك على Google. يُرجى تسجيل الدخول باستخدام الحساب نفسه على جهاز Nest أو تطبيق "مساعد Google" على هاتف iOS أو Android. يمكنك اختبار الإجراء أيضًا.

الآن هذا عرض توضيحي لورشة العمل. ولكن عندما تكون بصدد إنشاء طلبات لـ "مساعد Google"، يمكنك إرسال الإجراء لتتم الموافقة عليه. اطّلِع على هذا الدليل للحصول على مزيد من المعلومات.

النقاط التي تناولناها

  • كيفية إنشاء روبوت دردشة باستخدام الإصدار 2 من Dialogflow
  • كيفية إنشاء كيانات مخصّصة باستخدام Dialogflow
  • كيفية إنشاء محادثة خطية باستخدام Dialogflow
  • كيفية إعداد عمليات تنفيذ الردّ التلقائي على الويب باستخدام دوال Dialogflow وFirebase
  • كيفية نقل تطبيقك إلى "مساعد Google" باستخدام "المهام مع مساعد Google"

الخطوات التالية

هل استمتعت بهذا الدرس التطبيقي حول الترميز؟ ألقِ نظرة على هذه المختبرات الرائعة!

يمكنك مواصلة هذه الميزة الاختبارية حول الترميز من خلال دمجها في Google Chat:

إنشاء دليل التلفزيون في Google Chat باستخدام G Suite وDialogflow