হ্যান্ডস-অন: গুগলে ডায়ালগফ্লো এবং অ্যাকশন সহ Google সহকারীর জন্য একটি টিভি গাইড অ্যাকশন তৈরি করুন

১. ভূমিকা

আপনি টিভি দেখছেন, কিন্তু রিমোট খুঁজে পাচ্ছেন না, অথবা টিভিতে ভালো কিছু চলছে কিনা তা দেখার জন্য প্রতিটি চ্যানেল ঘুরে দেখতে চান না? চলুন গুগল অ্যাসিস্ট্যান্টকে জিজ্ঞাসা করি টিভিতে কী চলছে! এই ল্যাবে আপনি Dialogflow ব্যবহার করে একটি সহজ অ্যাকশন তৈরি করবেন এবং শিখবেন কীভাবে এটিকে গুগল অ্যাসিস্ট্যান্টের সাথে যুক্ত করতে হয়।

অনুশীলনগুলো এমনভাবে সাজানো হয়েছে যা একজন ক্লাউড ডেভেলপারের সাধারণ অভিজ্ঞতাকে প্রতিফলিত করে:

  1. একটি Dialogflow v2 এজেন্ট তৈরি করুন
  2. একটি কাস্টম সত্তা তৈরি করুন
  3. অভিপ্রায় তৈরি করুন
  4. ফায়ারবেস ফাংশন ব্যবহার করে একটি ওয়েবহুক সেটআপ করুন
  5. চ্যাটবটটি পরীক্ষা করুন
  6. গুগল অ্যাসিস্ট্যান্ট ইন্টিগ্রেশন সক্রিয় করুন

আপনি যা তৈরি করবেন

আমরা গুগল অ্যাসিস্ট্যান্টের জন্য একটি ইন্টারেক্টিভ টিভি গাইড চ্যাটবট এজেন্ট তৈরি করব। আপনি টিভি গাইডকে জিজ্ঞাসা করতে পারবেন যে, কোনো নির্দিষ্ট চ্যানেলে বর্তমানে কী দেখানো হচ্ছে। উদাহরণস্বরূপ; "এমটিভি-তে কী চলছে?" টিভি গাইড অ্যাকশনটি আপনাকে জানিয়ে দেবে যে বর্তমানে কী চলছে এবং এরপর কী দেখানো হবে।

আপনি যা শিখবেন

  • Dialogflow v2 দিয়ে কীভাবে একটি চ্যাটবট তৈরি করবেন
  • Dialogflow দিয়ে কীভাবে কাস্টম এনটিটি তৈরি করবেন
  • Dialogflow দিয়ে কীভাবে রৈখিক কথোপকথন তৈরি করবেন
  • Dialogflow এবং Firebase Functions ব্যবহার করে কীভাবে ওয়েবহুক ফুলফিলমেন্ট সেটআপ করবেন
  • অ্যাকশনস অন গুগল ব্যবহার করে কীভাবে আপনার অ্যাপ্লিকেশনটি গুগল অ্যাসিস্ট্যান্টে নিয়ে আসবেন

পূর্বশর্ত

  • Dialogflow এজেন্ট তৈরি করতে আপনার একটি Google Identity / gmail ঠিকানা প্রয়োজন হবে।
  • জাভাস্ক্রিপ্টের প্রাথমিক জ্ঞান থাকা আবশ্যক নয়, তবে ওয়েবহুক ফুলফিলমেন্ট কোড পরিবর্তন করতে চাইলে তা কাজে আসতে পারে।

২. প্রস্তুতি গ্রহণ

আপনার ব্রাউজারে ওয়েব অ্যাক্টিভিটি সক্রিয় করুন

  1. ক্লিক করুন: http://myaccount.google.com/activitycontrols

  1. ওয়েব ও অ্যাপ অ্যাক্টিভিটি চালু আছে কিনা তা নিশ্চিত করুন:

bf8d16b828d6f79a.png

একটি ডায়ালগফ্লো এজেন্ট তৈরি করুন

  1. খুলুন: https://console.dialogflow.com

  1. বাম দিকের বারে, লোগোর ঠিক নিচে, " নতুন এজেন্ট তৈরি করুন " নির্বাচন করুন। আপনার যদি আগে থেকেই এজেন্ট থাকে, তাহলে প্রথমে ড্রপডাউনটিতে ক্লিক করুন।

1d7c2b56a1ab95b8.png

  1. একজন এজেন্টের নাম নির্দিষ্ট করুন: your-name-tvguide (আপনার নিজের নাম ব্যবহার করুন)

35237b5c5c539ecc.png

  1. ডিফল্ট ভাষা হিসেবে বেছে নিন: ইংরেজি - en
  2. ডিফল্ট টাইম জোন হিসেবে, আপনার সবচেয়ে কাছের টাইম জোনটি বেছে নিন।
  3. তৈরি করতে ক্লিক করুন

ডায়ালগফ্লো কনফিগার করুন

  1. আপনার প্রোজেক্টের নামের পাশে, বাম দিকের মেনুতে থাকা গিয়ার আইকনটিতে ক্লিক করুন।

1d7c2b56a1ab95b8.png

  1. নিম্নলিখিত এজেন্ট বিবরণটি লিখুন: আমার টিভি গাইড

26f262d359c49075.png

  1. নিচে স্ক্রল করে লগ সেটিংস -এ যান এবং Dialogflow-এর ইন্টারঅ্যাকশনগুলো লগ করতে ও Google Cloud Stackdriver-এর সমস্ত ইন্টারঅ্যাকশন লগ করতে উভয় সুইচ চালু করুন। আমাদের অ্যাকশন ডিবাগ করার প্রয়োজনে পরে এটি কাজে লাগবে।

e80c17acc3cce993.png

  1. সংরক্ষণ করুন ক্লিক করুন

Google-এ অ্যাকশন কনফিগার করুন

  1. ডানদিকের প্যানেলে থাকা ‘গুগল অ্যাসিস্ট্যান্ট কীভাবে কাজ করে’ অংশে থাকা ‘গুগল অ্যাসিস্ট্যান্ট ’ লিঙ্কে ক্লিক করুন।

5a4940338fc351e3.png

এটি খুলবে: http://console.actions.google.com

আপনি যদি Actions on Google-এ নতুন হন, তাহলে আপনাকে প্রথমে এই ফর্মটি পূরণ করতে হবে:

3fd4e594fa169072.png

  1. প্রজেক্টের নামে ক্লিক করে সিমুলেটরে আপনার অ্যাকশনটি খোলার চেষ্টা করুন।
  2. মেনু বারে টেস্ট নির্বাচন করুন

6adb83ffb7adeb78.png

  1. নিশ্চিত করুন যে সিমুলেটরটি ইংরেজিতে সেট করা আছে এবং 'Talk to my test-app'- এ ক্লিক করুন।

অ্যাকশনটি আপনাকে Dialogflow-এর সাধারণ ডিফল্ট ইন্টেন্ট দিয়ে স্বাগত জানাবে। তার মানে, Action on Google-এর সাথে ইন্টিগ্রেশন সেটআপ করা সফল হয়েছে!

৩. কাস্টম সত্তা

এনটিটি হলো এমন অবজেক্ট যার উপর ভিত্তি করে আপনার অ্যাপ বা ডিভাইস বিভিন্ন কাজ করে। এটিকে প্যারামিটার বা ভেরিয়েবল হিসেবে ভাবুন। আমাদের টিভি গাইডে আমরা জিজ্ঞাসা করব: " এমটিভি- তে কী চলছে?"। এমটিভি হলো এনটিটি এবং ভেরিয়েবল। আমি অন্যান্য চ্যানেলের জন্যও জিজ্ঞাসা করতে পারতাম, যেমন: "ন্যাশনাল জিওগ্রাফিক" বা "কমেডি সেন্ট্রাল"। সংগৃহীত এনটিটিটিটি টিভি গাইড এপিআই ওয়েব-সার্ভিসে আমার অনুরোধে একটি প্যারামিটার হিসেবে ব্যবহৃত হবে।

Dialogflow Entities সম্পর্কে আরও তথ্য এখানে দেওয়া হলো

চ্যানেল সত্তা তৈরি করা

  1. Dialogflow Console-এ Entities মেনু আইটেমটিতে ক্লিক করুন।
  2. সত্তা তৈরি করতে ক্লিক করুন
  3. সত্তার নাম: channel (নিশ্চিত করুন যে এটি সম্পূর্ণ ছোট হাতের অক্ষরে লেখা)
  4. একটি চ্যানেলের নাম দিন। (কিছু চ্যানেলের জন্য একটি প্রতিশব্দের প্রয়োজন হবে, যদি গুগল অ্যাসিস্ট্যান্ট অন্য কিছু বোঝে)। টাইপ করার সময় আপনি ট্যাব এবং এন্টার কী ব্যবহার করতে পারেন। রেফারেন্স ভ্যালু হিসেবে চ্যানেল নম্বরটি লিখুন। এবং চ্যানেলের নামগুলো প্রতিশব্দ হিসেবে লিখুন, যেমন:
  • 1 - 1, Net 1, Net Station 1

ee4e4955aa77232d.png

৫. নীল সেভ বাটনের পাশের মেনু বাটনে ক্লিক করে **র এডিট** মোডে যান।

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. সংরক্ষণ করুন

৪. অভিপ্রায়

Dialogflow ব্যবহারকারীর উদ্দেশ্যকে শ্রেণীবদ্ধ করতে ইন্টেন্ট ব্যবহার করে। ইন্টেন্টগুলোর ট্রেনিং ফ্রেজ থাকে, যা ব্যবহারকারী আপনার এজেন্টকে কী বলতে পারে তার উদাহরণ। উদাহরণস্বরূপ, একজন ব্যবহারকারী যিনি জানতে চান টিভিতে কী চলছে, তিনি জিজ্ঞাসা করতে পারেন, "আজ টিভিতে কী চলছে?", "বর্তমানে কী চলছে?", অথবা শুধু "টিভিগাইড" বলতে পারেন।

When a user writes or says something, referred to as a user expression , Dialogflow matches the user expression to the best intent in your agent. Matching an intent is also known as intent classification .

Dialogflow Intents সম্পর্কে এখানে আরও তথ্য দেওয়া হলো

ডিফল্ট ওয়েলকাম ইনটেন্ট পরিবর্তন করা

যখন আপনি একটি নতুন Dialogflow এজেন্ট তৈরি করেন, তখন দুটি ডিফল্ট ইন্টেন্ট স্বয়ংক্রিয়ভাবে তৈরি হয়ে যায়। ডিফল্ট ওয়েলকাম ইন্টেন্ট হলো সেই প্রথম ফ্লো, যেখানে আপনি এজেন্টের সাথে কথোপকথন শুরু করার সময় পৌঁছান। ডিফল্ট ফলব্যাক ইন্টেন্ট হলো সেই ফ্লো, যা আপনি তখন পাবেন যখন এজেন্ট আপনার কথা বুঝতে পারে না অথবা আপনার বলা কথার সাথে কোনো ইন্টেন্ট মেলাতে পারে না।

  1. ডিফল্ট ওয়েলকাম ইনটেন্টে ক্লিক করুন

In the case of the Google Assistant, it will auto-start with the Default Welcome Intent. This is because Dialogflow is listening to the Welcome event . However, you can also invoke the intent by saying one of the entered training phrases.

6beee64e8910b85d.png

ডিফল্ট ওয়েলকাম ইনটেন্ট-এর স্বাগত বার্তাটি হলো:

ব্যবহারকারী

এজেন্ট

ওকে গুগল, তোমার-নাম-টিভিগাইডের সাথে কথা বলো।

স্বাগতম, আমি টিভি গাইডের প্রতিনিধি। আমি আপনাকে বলতে পারি একটি টিভি চ্যানেলে এখন কী চলছে। উদাহরণস্বরূপ, আপনি আমাকে জিজ্ঞাসা করতে পারেন: এমটিভি-তে কী চলছে?

  1. Responses পর্যন্ত নিচে স্ক্রোল করুন।
  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. ইনটেন্টস মেনু আইটেমটিতে আবার ক্লিক করুন।
  2. ক্রিয়েট ইনটেন্ট-এ ক্লিক করুন
  3. ইনটেন্টের নাম লিখুন: Test Intent (নিশ্চিত করুন যে আপনি একটি বড় হাতের T এবং একটি বড় হাতের I ব্যবহার করছেন। - যদি আপনি ইনটেন্টের বানানটি ভিন্নভাবে লেখেন, তাহলে ব্যাক-এন্ড পরিষেবাটি কাজ করবে না!)

925e02caa4de6b99.png

  1. প্রশিক্ষণ বাক্যাংশ যোগ করতে ক্লিক করুন
  • Test my agent
  • Test intent

2e44ddb2fae3c841.png

  1. ফুলফিলমেন্ট-এ ক্লিক করুন > ফুলফিলমেন্ট সক্ষম করুন

7eb73ba04d76140e.png

এবার আমরা কোনো রেসপন্স হার্ডকোড করছি না। রেসপন্সটি একটি ক্লাউড ফাংশন থেকে আসবে!

  1. এই ইন্টেন্টের জন্য ওয়েবহুক কল সক্ষম করার সুইচটি চালু করুন।

748a82d9b4d7d253.png

  1. সংরক্ষণ করুন

চ্যানেল ইনটেন্ট তৈরি করুন

চ্যানেল ইনটেন্টে কথোপকথনের এই অংশটি থাকবে:

ব্যবহারকারী

এজেন্ট

কমেডি সেন্ট্রালে কী চলছে?

বর্তমানে কমেডি সেন্ট্রালে সন্ধ্যা ৬টা থেকে ‘দ্য সিম্পসনস’ চলছে। এরপর সন্ধ্যা ৭টায় ‘ফ্যামিলি গাই’ শুরু হবে।

  1. ইনটেন্টস মেনু আইটেমটিতে আবার ক্লিক করুন।
  2. ক্রিয়েট ইনটেন্ট-এ ক্লিক করুন
  3. Enter the Intent Name: Channel Intent (make sure you use a capital T and a capital I. - If you spell the intent differently, the back-end service won't work!)
  4. Add Training phrases-এ ক্লিক করুন এবং নিম্নলিখিতগুলি যোগ করুন:
  • 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. প্রয়োজন অনুযায়ী চ্যানেল চিহ্নিত করুন

টিভি গাইড এজেন্টের সাথে কথা বলার সময়, আপনাকে সর্বদা 'চ্যানেল' নামক স্লট প্যারামিটারটি পূরণ করতে হবে। কথোপকথনের শুরুতে যদি চ্যানেলের নাম উল্লেখ না করা হয়, তাহলে 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. ক্লিক ফুলফিলমেন্ট

এবার আমরা কোনো রেসপন্স হার্ডকোড করছি না। রেসপন্সটি ক্লাউড ফাংশন থেকে আসবে! তাই এই ইন্টেন্টের জন্য ‘Enable Webhook call’ সুইচটি চালু করুন।

  1. সংরক্ষণ করুন

৫. ওয়েবহুক ফুলফিলমেন্ট

আপনার এজেন্টের যদি স্ট্যাটিক ইনটেন্ট রেসপন্সের চেয়ে বেশি কিছুর প্রয়োজন হয়, তবে আপনার ওয়েব সার্ভিসকে এজেন্টের সাথে সংযুক্ত করতে ফুলফিলমেন্ট ব্যবহার করতে হবে। আপনার ওয়েব সার্ভিস সংযুক্ত করার মাধ্যমে আপনি ব্যবহারকারীর এক্সপ্রেশনের উপর ভিত্তি করে অ্যাকশন নিতে পারেন এবং ব্যবহারকারীকে ডাইনামিক রেসপন্স ফেরত পাঠাতে পারেন। উদাহরণস্বরূপ, যদি কোনো ব্যবহারকারী MTV-এর টিভি শিডিউল পেতে চান, তবে আপনার ওয়েব সার্ভিস ডাটাবেসে তা চেক করে ব্যবহারকারীকে MTV-এর শিডিউলটি জানিয়ে রেসপন্স করতে পারে।

  1. প্রধান মেনুতে Fulfillment- এ ক্লিক করুন
  2. ইনলাইন এডিটর সুইচটি সক্রিয় করুন

cc84351f0d03ab6f.png

সহজ ওয়েবহুক টেস্টিং ও বাস্তবায়নের জন্য আপনি ইনলাইন এডিটর ব্যবহার করতে পারেন। এটি ফায়ারবেসের জন্য সার্ভারলেস ক্লাউড ফাংশন ব্যবহার করে।

  1. এডিটরের index.js ট্যাবে ক্লিক করুন এবং 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 কোডটি কপি করে পেস্ট করুন, যা সমস্ত Node.js প্যাকেজ ম্যানেজার (NPM) লাইব্রেরি ইম্পোর্ট করে:
{
  "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. Deploy বাটনটিতে ক্লিক করুন। এতে কিছুক্ষণ সময় লাগবে, কারণ এটি আপনার সার্ভারলেস ফাংশনটি ডেপ্লয় করছে। স্ক্রিনের নিচে একটি পপআপ আসবে, যেখানে আপনার স্ট্যাটাস জানানো হবে।
  2. কোডটি কাজ করছে কিনা তা দেখতে ওয়েবহুকটি পরীক্ষা করা যাক। ডানদিকের সিমুলেটরে টাইপ করুন:

Test my agent.

সবকিছু সঠিক থাকলে, আপনি দেখতে পাবেন: "এটি একটি পরীক্ষামূলক বার্তা"।

  1. চলুন চ্যানেল ইনটেন্টটি পরীক্ষা করা যাক, এবার প্রশ্নটি করুন:

What's on MTV?

যখন সবকিছু সঠিক থাকবে, তখন আপনি দেখতে পাবেন:

বিকাল ৪:৩০টা থেকে এমটিভি-তে 'এমটিভি আনপ্লাগড' দেখানো হবে। এরপর বিকাল ৫:৩০টায় 'রুপলস ড্র্যাগ রেস' শুরু হবে।

ঐচ্ছিক পদক্ষেপ - ফায়ারবেস

আপনি যখন এটি একটি ভিন্ন চ্যানেলে পরীক্ষা করবেন, তখন লক্ষ্য করবেন যে টিভির ফলাফল একই থাকছে। এর কারণ হলো, ক্লাউড ফাংশনটি এখনও কোনো প্রকৃত ওয়েব সার্ভার থেকে ডেটা সংগ্রহ করছে না।

এটি করার জন্য, আমাদের একটি বহির্গামী নেটওয়ার্ক সংযোগ স্থাপন করতে হবে।

যদি আপনি এই অ্যাপ্লিকেশনটি একটি ওয়েব সার্ভিসের সাথে পরীক্ষা করতে চান, তাহলে আপনার Firebase প্ল্যানটি Blaze- এ আপগ্রেড করুন। দ্রষ্টব্য: এই ধাপগুলো ঐচ্ছিক। আপনি Actions on Google- এ আপনার অ্যাপ্লিকেশনটির পরীক্ষা চালিয়ে যাওয়ার জন্য এই ল্যাবের পরবর্তী ধাপগুলোতেও যেতে পারেন।

  1. ফায়ারবেস কনসোলে যান: https://console.firebase.google.com

  1. স্ক্রিনের নিচে থাকা আপগ্রেড বাটনটি চাপুন।

ad38bc6d07462abf.png

পপআপ থেকে ব্লেজ প্ল্যানটি নির্বাচন করুন।

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

৬. গুগলে পদক্ষেপ

অ্যাকশনস অন গুগল হলো গুগল অ্যাসিস্ট্যান্টের জন্য একটি ডেভেলপমেন্ট প্ল্যাটফর্ম। এটি তৃতীয় পক্ষকে 'অ্যাকশন'—অর্থাৎ গুগল অ্যাসিস্ট্যান্টের জন্য এমন অ্যাপলেট—ডেভেলপ করার সুযোগ দেয়, যা বর্ধিত কার্যকারিতা প্রদান করে।

আপনাকে একটি গুগল অ্যাকশন চালু করতে হবে, যার জন্য গুগলকে কোনো অ্যাপ খুলতে বা সেটির সাথে যোগাযোগ করতে বলতে হবে।

এটি আপনার অ্যাকশনটি খুলবে, কণ্ঠস্বর পরিবর্তন করবে এবং আপনি 'নেটিভ' গুগল অ্যাসিস্ট্যান্টের পরিধি থেকে বেরিয়ে আসবেন। এর মানে হলো, এই পর্যায় থেকে আপনি আপনার এজেন্টকে যা কিছু জিজ্ঞাসা করবেন, তা আপনাকেই তৈরি করতে হবে। আপনি যদি গুগল অ্যাসিস্ট্যান্টের কাছে আবহাওয়ার তথ্য জানতে চান, তবে হঠাৎ করে তা জিজ্ঞাসা করতে পারবেন না; এর জন্য প্রথমে আপনার অ্যাকশনের (আপনার অ্যাপের) পরিধি থেকে বেরিয়ে আসতে (বন্ধ করতে) হবে।

গুগল অ্যাসিস্ট্যান্ট সিমুলেটরে আপনার কার্যকলাপ পরীক্ষা করা হচ্ছে

চলুন নিম্নলিখিত কথোপকথনটি পরীক্ষা করে দেখি:

ব্যবহারকারী

গুগল অ্যাসিস্ট্যান্ট

হে গুগল, তোমার-নাম-টিভি-গাইড -এর সাথে কথা বলো।

অবশ্যই। আমি আপনার-নাম-টিভি-গাইডটা নিয়ে আসছি।

ব্যবহারকারী

আপনার-নাম-টিভি-গাইড এজেন্ট

-

স্বাগতম, আমি টিভি গাইড...

আমার এজেন্টকে পরীক্ষা করুন

এটি একটি পরীক্ষামূলক বার্তা, আপনি যখন এটি দেখবেন, তার মানে আপনার ওয়েবহুক ফুলফিলমেন্ট সফল হয়েছে!

এমটিভি-তে কী চলছে?

এমটিভি-তে বিকেল ৪:৩০টা থেকে এমটিভি আনপ্লাগড দেখানো হবে। এরপর বিকেল ৫:৩০টায় রুপল'স ড্র্যাগ রেস শুরু হবে।

  1. গুগল অ্যাসিস্ট্যান্ট সিমুলেটরে ফিরে যান

খুলুন: https://console.actions.google.com

  1. মাইক্রোফোন আইকনে ক্লিক করুন এবং নিম্নলিখিত প্রশ্নগুলো করুন:

c3b200803c7ba95e.png

  • Talk to my test agent
  • Test my agent

গুগল অ্যাসিস্ট্যান্টের উত্তর হবে:

5d93c6d037c8c8eb.png

  1. এখন জিজ্ঞাসা করা যাক:
  • What's on Comedy Central?

এর ফলে যা ফেরত আসা উচিত:

বর্তমানে কমেডি সেন্ট্রালে সন্ধ্যা ৬টা থেকে ‘দ্য সিম্পসনস’ দেখানো হচ্ছে। এরপর সন্ধ্যা ৭টা থেকে ‘ফ্যামিলি গাই’ শুরু হবে।

৭. অভিনন্দন

আপনি Dialogflow ব্যবহার করে আপনার প্রথম Google Assistant অ্যাকশন তৈরি করেছেন, খুব ভালো!

আপনি হয়তো লক্ষ্য করেছেন, আপনার কাজটি টেস্ট-মোডে চলছিল, যা আপনার গুগল অ্যাকাউন্টের সাথে সংযুক্ত। আপনি যদি একই অ্যাকাউন্ট দিয়ে আপনার নেস্ট ডিভাইসে অথবা আপনার আইওএস বা অ্যান্ড্রয়েড ফোনের গুগল অ্যাসিস্ট্যান্ট অ্যাপে লগইন করেন, তাহলে আপনিও আপনার কাজটি পরীক্ষা করে দেখতে পারবেন।

এটি এখন একটি ওয়ার্কশপ ডেমো। কিন্তু যখন আপনি বাস্তবে গুগল অ্যাসিস্ট্যান্টের জন্য অ্যাপ্লিকেশন তৈরি করবেন, তখন অনুমোদনের জন্য আপনার অ্যাকশনটি জমা দিতে পারেন। আরও তথ্যের জন্য এই নির্দেশিকাটি পড়ুন।

আমরা যা আলোচনা করেছি

  • Dialogflow v2 দিয়ে কীভাবে একটি চ্যাটবট তৈরি করবেন
  • Dialogflow দিয়ে কীভাবে কাস্টম এনটিটি তৈরি করবেন
  • Dialogflow দিয়ে কীভাবে রৈখিক কথোপকথন তৈরি করবেন
  • Dialogflow এবং Firebase Functions ব্যবহার করে কীভাবে ওয়েবহুক ফুলফিলমেন্ট সেটআপ করবেন
  • অ্যাকশনস অন গুগল ব্যবহার করে কীভাবে আপনার অ্যাপ্লিকেশনটি গুগল অ্যাসিস্ট্যান্টে নিয়ে আসবেন

এরপর কী?

এই কোড ল্যাবটি কি আপনার ভালো লেগেছে? তাহলে এই চমৎকার ল্যাবগুলোও দেখে নিন!

এই কোড ল্যাবটি গুগল চ্যাটের জন্য ইন্টিগ্রেট করে চালিয়ে যান:

G Suite এবং Dialogflow ব্যবহার করে একটি টিভি গাইড ও গুগল চ্যাট তৈরি করুন