Google Chat ব্যবহারকারীদের থেকে তথ্য সংগ্রহ ও প্রসেস করা

কার্ড-ভিত্তিক ইন্টারফেসে ফর্ম ইনপুট তৈরি করে Google Chat অ্যাপ কীভাবে ব্যবহারকারীদের থেকে তথ্য সংগ্রহ ও প্রসেস করতে পারে তা এই নির্দেশিকায় বর্ণনা করা হয়েছে।

বিভিন্ন ধরনের উইজেট সহ একটি ডায়ালগ।
ছবি ১: একটি নমুনা চ্যাট অ্যাপ যা যোগাযোগের তথ্য সংগ্রহ করার জন্য একটি ডায়ালগ খোলে।

Chat অ্যাপ, Chat-এর মধ্যে বা বাইরে অ্যাকশন পারফর্ম করার জন্য ব্যবহারকারীদের থেকে তথ্য চায়, এর মধ্যে নিম্নলিখিত পদ্ধতি অন্তর্ভুক্ত:

  • সেটিংস কনফিগার করুন। যেমন, ব্যবহারকারীদের বিজ্ঞপ্তি সেটিংস কাস্টমাইজ করতে দিতে অথবা এক বা একাধিক স্পেসে Chat অ্যাপ কনফিগার ও যোগ করতে।
  • অন্যান্য Google Workspace অ্যাপ্লিকেশনে তথ্য তৈরি বা আপডেট করা। যেমন, ব্যবহারকারীদের Google Calendar ইভেন্ট তৈরি করতে দিন।
  • অন্যান্য অ্যাপ বা ওয়েব পরিষেবায় ব্যবহারকারীদের রিসোর্স অ্যাক্সেস ও আপডেট করতে দিন। যেমন, Chat অ্যাপ ব্যবহারকারীদের Chat স্পেস থেকে সরাসরি সহায়তা টিকিটের স্ট্যাটাস আপডেট করতে সাহায্য করতে পারে।

পূর্বশর্ত

HTTP

Google Chat অ্যাপ যা ব্যবহারকারীর ইন্টার‍্যাকশন গ্রহণ করে এবং উত্তর দেয়। এটি তৈরি করতে, HTTP কুইকস্টার্ট সম্পূর্ণ করুন।

Apps Script

Google Chat অ্যাপ যা ব্যবহারকারীর ইন্টার‍্যাকশন গ্রহণ করে এবং উত্তর দেয়। এটি তৈরি করতে, অ্যাপ স্ক্রিপ্ট কুইকস্টার্ট সম্পূর্ণ করুন।

কার্ড ব্যবহার করে ফর্ম তৈরি করা

তথ্য সংগ্রহ করতে, Chat অ্যাপ ফর্ম ও তার ইনপুট ডিজাইন করে এবং সেগুলিকে কার্ডে তৈরি করে। ব্যবহারকারীদের কার্ড দেখাতে, Chat অ্যাপ নিম্নলিখিত Chat ইন্টারফেস ব্যবহার করতে পারে:

  • মেসেজ যেগুলিতে এক বা একাধিক কার্ড থাকে।
  • হোমপেজ, এটি হল একটি কার্ড যা Chat অ্যাপের সাথে সরাসরি মেসেজে হোম ট্যাব থেকে দেখা যায়।
  • ডায়ালগ, যা হল কার্ড যা মেসেজ ও হোমপেজ থেকে নতুন উইন্ডোতে খোলে।

চ্যাট অ্যাপ নিম্নলিখিত উইজেট ব্যবহার করে কার্ড তৈরি করতে পারে:

  • ব্যবহারকারীর থেকে তথ্য জানতে চাওয়া ফর্ম ইনপুট উইজেট। বিকল্প হিসেবে, ব্যবহারকারীরা যাতে সঠিকভাবে তথ্য ইনপুট ও ফর্ম্যাট করতে পারেন তা নিশ্চিত করতে, আপনি ফর্ম ইনপুট উইজেটে যাচাইকরণ যোগ করতে পারেন। চ্যাট অ্যাপ নিম্নলিখিত ফর্ম ইনপুট উইজেট ব্যবহার করতে পারে:

  • বোতাম উইজেট যাতে ব্যবহারকারীরা কার্ডে ইনপুট করা ভ্যালু জমা দিতে পারেন। ব্যবহারকারী বোতামে ক্লিক করার পরে, Chat অ্যাপ সেটি যে তথ্য পায় তা প্রসেস করতে পারে।

নিচের উদাহরণে, একটি কার্ড টেক্সট ইনপুট, তারিখ ও সময় বাছাইকারী এবং বাছাই ইনপুট ব্যবহার করে পরিচিতির তথ্য সংগ্রহ করে:

তথ্য সংগ্রহ করার জন্য ব্যবহার করা যায় এমন ইন্টার‍্যাক্টিভ উইজেটের আরও উদাহরণ পেতে, ইন্টার‍্যাক্টিভ কার্ড বা ডায়ালগ ডিজাইন করুন লিঙ্কে দেখুন।

ড্রপ-ডাউন মেনু যোগ করা

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

আপনি নিম্নলিখিত ডেটা সোর্স থেকে ড্রপ-ডাউন মেনুর জন্য আইটেম যোগ করতে পারবেন:

Google Workspace ডেটা সোর্স থেকে আইটেম যোগ করা

Google Workspace ডেটা সোর্স থেকে আইটেম অটো-ফিল করতে, যেমন Google Workspace ব্যবহারকারী, একটি DataSourceConfig অবজেক্টের মধ্যে platformDataSource ফিল্ড নির্দিষ্ট করুন। অন্যান্য বেছে নেওয়ার ইনপুট ধরনের মতো, আপনি বাদ SelectionItem অবজেক্ট দিতে পারবেন না, কারণ এই বেছে নেওয়ার আইটেমগুলি Google Workspace থেকে ডায়নামিক সোর্স করা হয়।

নিচে দেওয়া কোড থেকে Google Workspace ব্যবহারকারীদের ড্রপ-ডাউন মেনু দেখা যায়:

JSON

{
  "sections": [
    {
      "header": "Section Header",
      "widgets": [
        {
          "selectionInput": {
            "name": "contacts",
            "type": "DROPDOWN",
            "label": "Select contact from organization",
            "data_source_configs": [
              {
                "platformDataSource": {
                  "commonDataSource": "USER"
                },
                "min_characters_trigger": 1
              }
            ]
          }
        }
      ]
    }
  ]
}

এক্সটার্নাল ডেটা সোর্স থেকে আইটেম যোগ করা

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

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

নিচে দেওয়া কোডে একটি ড্রপ-ডাউন মেনু দেখানো হয়েছে যা এক্সটার্নাল ডেটা সোর্স থেকে আইটেম কোয়েরি ও পপুলেট করে:

JSON

{
  "sections": [
    {
      "header": "Section Header",
      "widgets": [
        {
          "selectionInput": {
            "name": "crm_leads",
            "type": "DROPDOWN",
            "label": "Select CRM Lead",
            "data_source_configs": [
              {
                "remoteDataSource": {
                  "function": "getCrmLeads"
                },
                "min_characters_trigger": 2
              }
            ],
            "items": [
              {
                "text": "Suggested Lead 1",
                "value": "lead-1"
              }
            ]
          }
        }
      ]
    }
  ]
}

সাজেস্ট করা আইটেম কীভাবে ফেরত দিতে হয় তা দেখানোর জন্য সম্পূর্ণ উদাহরণ পেতে, বেছে নেওয়ার আইটেম সাজেস্ট করুন বিভাগটি দেখুন।

একাধিক বিকল্প বেছে নেওয়ার মেনু যোগ করা

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

আপনি নিম্নলিখিত ডেটা সোর্স থেকে মাল্টি-সিলেক্ট মেনুর জন্য আইটেম পপুলেট করতে পারবেন:

  • Google Workspace ডেটা, যার মধ্যে ব্যবহারকারী বা ব্যবহারকারী মেম্বার এমন Chat স্পেস অন্তর্ভুক্ত। মেনুতে শুধু একই Google Workspace সংস্থা থেকে আইটেম যোগ করা হয়।
  • এক্সটার্নাল ডেটা সোর্স, যেমন রিলেশনাল ডেটাবেস। যেমন, আপনি গ্রাহক সম্পর্ক ম্যানেজমেন্ট (CRM) সিস্টেম থেকে পাওয়া সেলস লিডের তালিকা থেকে কোনও একটি বেছে নিতে ব্যবহারকারীকে সাহায্য করার জন্য মাল্টি-সিলেক্ট মেনু ব্যবহার করতে পারেন।

Google Workspace ডেটা সোর্স থেকে আইটেম যোগ করা

Google Workspace ডেটা সোর্স ব্যবহার করতে, SelectionInput উইজেটে platformDataSource ফিল্ড নির্দিষ্ট করুন। অন্যান্য বেছে নেওয়ার ইনপুট ধরনের মতো, আপনি বাদ SelectionItem অবজেক্ট দিতে পারবেন না, কারণ এই বেছে নেওয়ার আইটেমগুলি Google Workspace থেকে ডায়নামিক সোর্স করা হয়।

নিম্নলিখিত কোডটি Google Workspace ব্যবহারকারীদের একটি মাল্টি-সিলেক্ট মেনু দেখায়। ব্যবহারকারীদের পপুলেট করতে, বেছে নেওয়ার ইনপুট commonDataSource থেকে USER সেট করে:

JSON

{
  "selectionInput": {
    "name": "contacts",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 5,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "commonDataSource": "USER"
    }
  }
}

নিচের কোডে Chat স্পেসের একটি মাল্টি-সিলেক্ট মেনু দেখানো হয়েছে। স্পেস পূরণ করতে, বেছে নেওয়া ইনপুট hostAppDataSource ফিল্ড নির্দিষ্ট করে। এছাড়াও, মাল্টি-সিলেক্ট মেনু defaultToCurrentSpace-কে true হিসেবে সেট করে, যা মেনুতে বর্তমান স্পেসকে ডিফল্ট সিলেকশন হিসেবে সেট করে:

JSON

{
  "selectionInput": {
    "name": "spaces",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 3,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "hostAppDataSource": {
        "chatDataSource": {
          "spaceDataSource": {
            "defaultToCurrentSpace": true
          }
        }
      }
    }
  }
}

এক্সটার্নাল ডেটা সোর্স থেকে আইটেম যোগ করা

এছাড়াও, মাল্টি-সিলেক্ট মেনু থার্ড-পার্টি বা এক্সটার্নাল ডেটা সোর্স থেকে আইটেম পূরণ করতে পারে। এক্সটার্নাল ডেটা সোর্স ব্যবহার করতে, আপনি SelectionInput উইজেটে externalDataSource ফিল্ড নির্দিষ্ট করেন, এতে এমন ফাংশন থাকে যা ডেটা সোর্স থেকে কোয়েরি করে এবং আইটেম রিটার্ন করে।

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

নিচে দেওয়া কোড স্যাম্পেল একটি মাল্টি-সিলেক্ট মেনু দেখায় যা এক্সটার্নাল ডেটা সোর্স থেকে কোয়েরি করে এবং আইটেম পপুলেট করে:

Node.js

node/chat/selection-input/index.js
selectionInput: {
  name: "contacts",
  type: "MULTI_SELECT",
  label: "Selected contacts",
  multiSelectMaxSelectedItems: 3,
  multiSelectMinQueryLength: 1,
  externalDataSource: { function: FUNCTION_URL },
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  items: [getSuggestedContact("3")]
}

FUNCTION_URL-এর পরিবর্তে HTTP এন্ডপয়েন্ট লিখুন যা এক্সটার্নাল ডেটা সোর্স কোয়েরি করে।

Python

python/chat/selection-input/main.py
'selectionInput': {
  'name': "contacts",
  'type': "MULTI_SELECT",
  'label': "Selected contacts",
  'multiSelectMaxSelectedItems': 3,
  'multiSelectMinQueryLength': 1,
  'externalDataSource': { 'function': FUNCTION_URL },
  # Suggested items loaded by default.
  # The list is static here but it could be dynamic.
  'items': [get_suggested_contact("3")]
}

FUNCTION_URL-এর পরিবর্তে HTTP এন্ডপয়েন্ট লিখুন যা এক্সটার্নাল ডেটা সোর্স কোয়েরি করে।

Java

java/chat/selection-input/src/main/java/com/google/chat/selectionInput/App.java
.setSelectionInput(new GoogleAppsCardV1SelectionInput()
  .setName("contacts")
  .setType("MULTI_SELECT")
  .setLabel("Selected contacts")
  .setMultiSelectMaxSelectedItems(3)
  .setMultiSelectMinQueryLength(1)
  .setExternalDataSource(new GoogleAppsCardV1Action().setFunction(FUNCTION_URL))
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  .setItems(List.of(getSuggestedContact("3")))))))))));

FUNCTION_URL-এর পরিবর্তে HTTP এন্ডপয়েন্ট লিখুন যা এক্সটার্নাল ডেটা সোর্স কোয়েরি করে।

Apps Script

এই উদাহরণটি কার্ড JSON রিটার্ন করে একটি কার্ড মেসেজ পাঠায়। এছাড়াও, আপনি Apps স্ক্রিপ্ট কার্ড পরিষেবা ব্যবহার করতে পারবেন।

apps-script/chat/selection-input/selection-input.gs
selectionInput: {
  name: "contacts",
  type: "MULTI_SELECT",
  label: "Selected contacts",
  multiSelectMaxSelectedItems: 3,
  multiSelectMinQueryLength: 1,
  externalDataSource: { function: "queryContacts" },
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  items: [getSuggestedContact("3")]
}

সাজেস্ট করা আইটেম কীভাবে ফেরত দিতে হয় তা দেখানোর জন্য সম্পূর্ণ উদাহরণ পেতে, বেছে নেওয়ার আইটেম সাজেস্ট করুন বিভাগটি দেখুন।

ইন্টার‌্যাক্টিভ উইজেট থেকে ডেটা পাওয়া

ব্যবহারকারীরা কোনও বোতামে ক্লিক করলে, ইন্ট্যার‍্যাকশন সম্পর্কিত তথ্য সহ সেটির Chat অ্যাপ অ্যাকশন ট্রিগার হয়। ইভেন্ট পেলোডের commonEventObject মধ্যে, formInputs অবজেক্টে ব্যবহারকারীর ইনপুট করা যেকোনও ভ্যালু থাকে।

আপনি অবজেক্ট event.commonEventObject.formInputs.WIDGET_NAME থেকে ভ্যালু রিট্রিভ করতে পারবেন, যেখানে WIDGET_NAME হল name ফিল্ড যা আপনি উইজেটের জন্য নির্দিষ্ট করেছেন। উইজেটের জন্য নির্দিষ্ট ডেটার ধরন হিসেবে ভ্যালু রিটার্ন করা হয়।

নিচে ইভেন্ট অবজেক্টের একটি অংশ দেখানো হয়েছে যেখানে ব্যবহারকারী প্রতিটি উইজেটের জন্য ভ্যালু এন্টার করেছেন:

{
  "commonEventObject": { "formInputs": {
    "contactName": { "stringInputs": {
      "value": ["Kai 0"]
    }},
    "contactBirthdate": { "dateInput": {
      "msSinceEpoch": 1000425600000
    }},
    "contactType": { "stringInputs": {
      "value": ["Personal"]
    }}
  }}
}

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

ফর্ম ইনপুট উইজেট ইনপুট ডেটার ধরন ইভেন্ট অবজেক্ট থেকে ইনপুট ভ্যালু উদাহরণ ভ্যালু
textInput stringInputs event.commonEventObject.formInputs.contactName.stringInputs.value[0] Kai O
selectionInput stringInputs প্রথম বা একমাত্র ভ্যালু পেতে, event.commonEventObject.formInputs.contactType.stringInputs.value[0] Personal
dateTimePicker যা শুধুমাত্র তারিখ গ্রহণ করে। dateInput event.commonEventObject.formInputs.contactBirthdate.dateInput.msSinceEpoch। 1000425600000

Chat অ্যাপ ডেটা পাওয়ার পরে, এটি নিম্নলিখিত যেকোনও কাজ করতে পারে:

বেছে নেওয়ার আইটেম সাজেস্ট করা

কোনও কার্ডে যদি একটি মাল্টি-সিলেক্ট মেনু বা ড্রপ-ডাউন মেনু থাকে যা এক্সটার্নাল ডেটা সোর্স থেকে আইটেম পূরণ করে, তাহলে Chat অ্যাপ, মেনুতে ব্যবহারকারীরা যা টাইপ করেন তার উপর ভিত্তি করে সাজেস্ট করা আইটেম দেখাতে পারে। যেমন, কোনও ব্যবহারকারী যদি Atl মেনুর জন্য টাইপ করা শুরু করেন যা মার্কিন যুক্তরাষ্ট্রের শহরগুলির নাম দেখায়, তাহলে ব্যবহারকারী টাইপ করা শেষ করার আগেই আপনার Chat অ্যাপ Atlanta অটো-সাজেস্ট করতে পারে। Chat অ্যাপ সর্বাধিক ১০০টি আইটেম সাজেস্ট করতে পারে।

বেছে নেওয়ার ইনপুটে আইটেম সাজেস্ট ও ডাইনামিক পপুলেট করতে, কার্ডের SelectionInput উইজেটে এমন ফাংশন নির্দিষ্ট করতে হবে যা এক্সটার্নাল ডেটা সোর্স কোয়েরি করে। মাল্টি-সিলেক্ট মেনুর জন্য, আপনাকে externalDataSource ফিল্ড নির্দিষ্ট করতে হবে। ড্রপ-ডাউন মেনুর জন্য, আপনাকে remoteDataSource ফিল্ডের মধ্যে DataSourceConfig অবজেক্ট নির্দিষ্ট করতে হবে।

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

সাজেস্ট করা আইটেম ফেরত দিতে, ফাংশনকে নিম্নলিখিত কাজগুলি করতে হবে:

  1. ব্যবহারকারীরা মেনুতে টাইপ করলে Chat অ্যাপ যে ইভেন্ট অবজেক্ট পায়, সেটি ম্যানেজ করুন।
  2. ইভেন্ট অবজেক্ট থেকে, ব্যবহারকারী যে ভ্যালু টাইপ করেন সেটি পান, যা event.commonEventObject.parameters["autocomplete_widget_query"] ফিল্ডে দেখানো হয়।
  3. ব্যবহারকারীকে সাজেস্ট করার জন্য এক বা একাধিক SelectionItems পেতে ব্যবহারকারীর ইনপুট ভ্যালু ব্যবহার করে ডেটা সোর্স কোয়েরি করুন।
  4. modifyCard অবজেক্টের সাথে অ্যাকশন RenderActions রিটার্ন করে সাজেস্ট করা আইটেম রিটার্ন করুন।

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

Node.js

node/chat/selection-input/index.js
/**
 * Web app that responds to events sent from a Google Chat space.
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
app.post('/', async (req, res) => {
  // Stores the Google Chat event
  const chatEvent = req.body.chat;

  // Handle user interaction with multiselect.
  if(chatEvent.widgetUpdatedPayload) {
    return res.json(queryContacts(req.body));
  }

  // Replies with a card that contains the multiselect menu.
  return res.json({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: FUNCTION_URL },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact("3")]
        }
      }]}]}
    }]
  }}}}});
});

/**
 * Get contact suggestions based on text typed by users.
 *
 * @param {Object} event the event object that contains the user's query
 * @return {Object} suggestions
 */
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
 * Generate a suggested contact given an ID.
 *
 * @param {String} id The ID of the contact to return.
 * @return {Object} The contact formatted as a selection item in the menu.
 */
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

FUNCTION_URL-এর পরিবর্তে HTTP এন্ডপয়েন্ট লিখুন যা এক্সটার্নাল ডেটা সোর্স কোয়েরি করে।

Python

python/chat/selection-input/main.py
@app.route('/', methods=['POST'])
def post() -> Mapping[str, Any]:
  """Handle requests from Google Chat

  Returns:
      Mapping[str, Any]: The response
  """
  # Stores the Google Chat event
  chatEvent = request.get_json().get('chat')

  # Handle user interaction with multiselect.
  if chatEvent.get('widgetUpdatedPayload') is not None:
    return json.jsonify(query_contacts(request.get_json()))

  # Replies with a card that contains the multiselect menu.
  return json.jsonify({ 'hostAppDataAction': { 'chatDataAction': { 'createMessageAction': {
    'message': { 'cardsV2': [{
      'cardId': "contactSelector",
      'card': { 'sections':[{ 'widgets': [{
        'selectionInput': {
          'name': "contacts",
          'type': "MULTI_SELECT",
          'label': "Selected contacts",
          'multiSelectMaxSelectedItems': 3,
          'multiSelectMinQueryLength': 1,
          'externalDataSource': { 'function': FUNCTION_URL },
          # Suggested items loaded by default.
          # The list is static here but it could be dynamic.
          'items': [get_suggested_contact("3")]
        }
      }]}]}
    }]}
  }}}})


def query_contacts(event: dict) -> dict:
  """Get contact suggestions based on text typed by users.

  Args:
      event (Mapping[str, Any]): The event object that contains the user's query

  Returns:
      Mapping[str, Any]: The response with contact suggestions.
  """
  query = event.get("commonEventObject").get("parameters").get("autocomplete_widget_query")
  return { 'action': { 'modifyOperations': [{ 'updateWidget': { 'selectionInputWidgetSuggestions': { 'suggestions': list(
    filter(lambda e: query is None or query in e["text"], [
      # The list is static here but it could be dynamic.
      get_suggested_contact("1"), get_suggested_contact("2"), get_suggested_contact("3"), get_suggested_contact("4"), get_suggested_contact("5")
    # Only return items based on the query from the user
    ])
  )}}}]}}


def get_suggested_contact(id: str) -> dict:
  """Generate a suggested contact given an ID.

  Args:
      id (str): The ID of the contact to return.

  Returns:
      Mapping[str, Any]: The contact formatted as a selection item in the menu.
  """
  return {
    'value': id,
    'startIconUri': "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    'text': "Contact " + id
  }

FUNCTION_URL-এর পরিবর্তে HTTP এন্ডপয়েন্ট লিখুন যা এক্সটার্নাল ডেটা সোর্স কোয়েরি করে।

Java

java/chat/selection-input/src/main/java/com/google/chat/selectionInput/App.java
@SpringBootApplication
@RestController
// Web app that responds to events sent from a Google Chat space.
public class App {
  private static final String FUNCTION_URL = "your-function-url";

  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }

  /**
   * Handle requests from Google Chat
   * 
   * @param event the event object sent by Google Chat
   * @return The response to be sent back to Google Chat
   */
  @PostMapping("/")
  @ResponseBody
  public GenericJson onEvent(@RequestBody JsonNode event) throws Exception {
    // Stores the Google Chat event
    JsonNode chatEvent = event.at("/chat");

    // Handle user interaction with multiselect.
    if (!chatEvent.at("/widgetUpdatedPayload").isEmpty()) {
      return queryContacts(event);
    }

    // Replies with a card that contains the multiselect menu.
    Message message = new Message().setCardsV2(List.of(new CardWithId()
      .setCardId("contactSelector")
      .setCard(new GoogleAppsCardV1Card()
        .setSections(List.of(new GoogleAppsCardV1Section().setWidgets(List.of(new GoogleAppsCardV1Widget()
          .setSelectionInput(new GoogleAppsCardV1SelectionInput()
            .setName("contacts")
            .setType("MULTI_SELECT")
            .setLabel("Selected contacts")
            .setMultiSelectMaxSelectedItems(3)
            .setMultiSelectMinQueryLength(1)
            .setExternalDataSource(new GoogleAppsCardV1Action().setFunction(FUNCTION_URL))
            // Suggested items loaded by default.
            // The list is static here but it could be dynamic.
            .setItems(List.of(getSuggestedContact("3")))))))))));

    return new GenericJson() {{
      put("hostAppDataAction", new GenericJson() {{
        put("chatDataAction", new GenericJson() {{
          put("createMessageAction", new GenericJson() {{
            put("message", message);
          }});
        }});
      }});
    }};
  }

  /**
   * Get contact suggestions based on text typed by users.
   *
   * @param event the event object that contains the user's query.
   * @return The response with contact suggestions.
   */
  GenericJson queryContacts(JsonNode event) throws Exception {
    String query = event.at("/commonEventObject/parameters/autocomplete_widget_query").asText();
    List<GoogleAppsCardV1SelectionItem> suggestions = List.of(
      // The list is static here but it could be dynamic.
      getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
    // Only return items based on the query from the user
    ).stream().filter(e -> query == null || e.getText().indexOf(query) > -1).toList();

    return new GenericJson() {{
      put("action", new GenericJson() {{
        put("modifyOperations", List.of(new GenericJson() {{
          put("updateWidget", new GenericJson() {{
            put("selectionInputWidgetSuggestions", new GenericJson() {{
              put("suggestions", suggestions);
            }});
          }});
        }}));
      }});
    }};
  }

  /**
   * Generate a suggested contact given an ID.
   * 
   * @param id The ID of the contact to return.
   * @return The contact formatted as a selection item in the menu.
   */
  GoogleAppsCardV1SelectionItem getSuggestedContact(String id) {
    return new GoogleAppsCardV1SelectionItem()
      .setValue(id)
      .setStartIconUri("https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png")
      .setText("Contact " + id);
  }
}

FUNCTION_URL-এর পরিবর্তে HTTP এন্ডপয়েন্ট লিখুন যা এক্সটার্নাল ডেটা সোর্স কোয়েরি করে।

Apps Script

এই উদাহরণটি কার্ড JSON রিটার্ন করে একটি কার্ড মেসেজ পাঠায়। এছাড়াও, আপনি Apps স্ক্রিপ্ট কার্ড পরিষেবা ব্যবহার করতে পারবেন।

apps-script/chat/selection-input/selection-input.gs
/**
* Responds to a Message trigger in Google Chat.
*
* @param {Object} event the event object from Google Chat
* @return {Object} Response from the Chat app.
*/
function onMessage(event) {
  // Replies with a card that contains the multiselect menu.
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: "queryContacts" },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact("3")]
        }
      }]}]}
    }]
  }}}}};
}

/**
* Get contact suggestions based on text typed by users.
*
* @param {Object} event the event object that contains the user's query
* @return {Object} suggestions
*/
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
* Generate a suggested contact given an ID.
*
* @param {String} id The ID of the contact to return.
* @return {Object} The contact formatted as a selection item in the menu.
*/
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

অন্য কার্ডে ডেটা ট্রান্সফার করা

কোনও ব্যবহারকারী কার্ড থেকে তথ্য জমা দেওয়ার পরে, নিম্নলিখিত যেকোনও একটি কাজ করতে আপনাকে হয়ত অতিরিক্ত কার্ড ফেরত দিতে হবে:

  • আলাদা আলাদা বিভাগ তৈরি করে ব্যবহারকারীদের আরও বড় ফর্ম পূরণ করতে সাহায্য করুন।
  • ব্যবহারকারীদের প্রাথমিক কার্ড থেকে তথ্য প্রিভিউ করতে ও কনফার্ম করতে দিন, যাতে তারা জমা দেওয়ার আগে উত্তর পর্যালোচনা করতে পারেন।
  • ফর্মের বাকি অংশ ডায়নামিক পূরণ করুন। যেমন, ব্যবহারকারীদের অ্যাপয়েন্টমেন্ট তৈরি করার জন্য প্রম্পট করতে, Chat অ্যাপ একটি প্রাথমিক কার্ড দেখাতে পারে যা অ্যাপয়েন্টমেন্টের কারণ জানতে চায় এবং তারপরে অ্যাপয়েন্টমেন্টের ধরনের উপর ভিত্তি করে উপলভ্য সময় প্রদান করে এমন আরেকটি কার্ড পূরণ করে।

প্রাথমিক কার্ড থেকে ইনপুট করা ডেটা ট্রান্সফার করতে, আপনি button উইজেট তৈরি করতে পারেন, যার মধ্যে actionParameters উইজেটের name এবং ব্যবহারকারীর ইনপুট করা ভ্যালু থাকে, যেমনটি নিচের উদাহরণে দেখানো হয়েছে:

Node.js

node/chat/contact-form-app/index.js
{ buttonList: { buttons: [{
  text: "SUBMIT",
  onClick: { action: {
    function: FUNCTION_URL,
    parameters: [
      { key: "actionName", value: "submitDialog" },
      // Pass input values as parameters for last dialog step (submission)
      { key: "contactName", value: name },
      { key: "contactBirthdate", value: birthdate },
      { key: "contactType", value: type }
    ]
  }}
}]}}

FUNCTION_URL-এর পরিবর্তে HTTP এন্ডপয়েন্ট লিখুন যা বোতামে ক্লিক করার প্রক্রিয়া ম্যানেজ করে।

Python

python/chat/contact-form-app/main.py
{ 'buttonList': { 'buttons': [{
  'text': "SUBMIT",
  'onClick': { 'action': {
    'function': FUNCTION_URL,
    'parameters': [
      { 'key': "actionName", 'value': "submitDialog" },
      # Pass input values as parameters for last dialog step (submission)
      { 'key': "contactName", 'value': name },
      { 'key': "contactBirthdate", 'value': birthdate },
      { 'key': "contactType", 'value': type }
    ]
  }}
}]}}

FUNCTION_URL-এর পরিবর্তে HTTP এন্ডপয়েন্ট লিখুন যা বোতামে ক্লিক করার প্রক্রিয়া ম্যানেজ করে।

Java

java/chat/contact-form-app/src/main/java/com/google/chat/contact/App.java
new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(
  new GoogleAppsCardV1Button()
    .setText("SUBMIT")
    .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
      .setFunction(FUNCTION_URL)
      .setParameters(List.of(
        new GoogleAppsCardV1ActionParameter().setKey("actionName").setValue("submitDialog"),
        // Pass input values as parameters for last dialog step (submission)
        new GoogleAppsCardV1ActionParameter().setKey("contactName").setValue(name),
        new GoogleAppsCardV1ActionParameter().setKey("contactBirthdate").setValue(birthdate),
        new GoogleAppsCardV1ActionParameter().setKey("contactType").setValue(type))))))))))));

FUNCTION_URL-এর পরিবর্তে HTTP এন্ডপয়েন্ট লিখুন যা বোতামে ক্লিক করার প্রক্রিয়া ম্যানেজ করে।

Apps Script

এই উদাহরণটি কার্ড JSON রিটার্ন করে একটি কার্ড মেসেজ পাঠায়। এছাড়াও, আপনি Apps স্ক্রিপ্ট কার্ড পরিষেবা ব্যবহার করতে পারবেন।

apps-script/chat/contact-form-app/Code.gs
{ buttonList: { buttons: [{
  text: "SUBMIT",
  onClick: { action: {
    function: "submitDialog",
    // Pass input values as parameters for last dialog step (submission)
    parameters: [
      { key: "contactName", value: name },
      { key: "contactBirthdate", value: birthdate },
      { key: "contactType", value: type }
    ]
  }}
}]}}

ব্যবহারকারী বোতামে ক্লিক করলে, আপনার Chat অ্যাপ একটি ইভেন্ট অবজেক্ট পায়, যেখান থেকে আপনি ডেটা পেতে পারেন।

ফর্ম জমা দেওয়ার ব্যাপারে উত্তর দেওয়া

কার্ড মেসেজ বা ডায়ালগ থেকে ডেটা পাওয়ার পরে, Chat অ্যাপ প্রাপ্তি স্বীকার করে অথবা সমস্যা সংক্রান্ত মেসেজ পাঠিয়ে উত্তর দেয়।

নিচের উদাহরণে, একটি চ্যাট অ্যাপ কনফার্ম করার জন্য একটি টেক্সট মেসেজ পাঠায় যে এটি একটি কার্ড মেসেজ থেকে জমা দেওয়া ফর্ম সফলভাবে পেয়েছে।

Node.js

node/chat/contact-form-app/index.js
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
  text: "✅ " + event.commonEventObject.parameters["contactName"] + " has been added to your contacts."
}}}}};

Python

python/chat/contact-form-app/main.py
return { 'hostAppDataAction': { 'chatDataAction': { 'createMessageAction': { 'message': {
  'text': "✅ " + event.get('commonEventObject').get('parameters')["contactName"] + " has been added to your contacts."
}}}}}

Java

java/chat/contact-form-app/src/main/java/com/google/chat/contact/App.java
return new GenericJson() {{
  put("hostAppDataAction", new GenericJson() {{
    put("chatDataAction", new GenericJson() {{
      put("createMessageAction", new GenericJson() {{
        put("message", new Message()
          .setText( "✅ " + event.at("/commonEventObject/parameters/contactName").asText() +
                    " has been added to your contacts."));
      }});
    }});
  }});
}};

Apps Script

এই উদাহরণটি কার্ড JSON রিটার্ন করে একটি কার্ড মেসেজ পাঠায়। এছাড়াও, আপনি Apps স্ক্রিপ্ট কার্ড পরিষেবা ব্যবহার করতে পারবেন।

apps-script/chat/contact-form-app/Code.gs
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
  text: "✅ " + event.commonEventObject.parameters["contactName"] + " has been added to your contacts."
}}}}};

ডায়ালগ প্রসেস ও বন্ধ করতে, আপনাকে একটি RenderActions অবজেক্ট রিটার্ন করতে হবে যা নির্দিষ্ট করে যে আপনি কনফার্মেশন মেসেজ পাঠাতে চান কিনা, আসল মেসেজ বা কার্ড আপডেট করতে চান কিনা অথবা শুধু ডায়ালগটি বন্ধ করতে চান কিনা। ধাপগুলি জানতে, ডায়ালগ বন্ধ করুন দেখুন।

সমস্যার সমাধান করুন

Chat-এ ডায়ালগের সাথে ইন্টার‍্যাক্ট করার সময় নির্দিষ্ট এরর কোড ও রানটাইম বিহেভিয়ার সংক্রান্ত সমস্যার সমাধান করার ধাপ এই বিভাগে দেওয়া আছে।

ডায়ালগ ইন্ট্যার‍্যাকশন "অ্যাড-অন কল করার সময় অনির্দিষ্ট সমস্যা হয়েছে" মেসেজ দেখায়

ডায়ালগের সাথে ইন্টার‍্যাক্ট করার সময়, আপনি যদি "অ্যাড-অন ইনভোক করার সময় অনির্দিষ্ট সমস্যা" মেসেজ ও কোড ১৩ সহ সমস্যার লগ দেখতে পান, তাহলে সাধারণত এটি অভ্যন্তরীণ সমস্যা অথবা Chat অ্যাপের HTTP এন্ডপয়েন্ট অনুরোধ প্রসেস করতে বা সঠিক উত্তর দিতে ব্যর্থ হয়েছে বলে ইঙ্গিত করে।

এই সমস্যার সমাধান করতে:

  • কোনও আনহ্যান্ডেলড ব্যতিক্রম বা ক্র্যাশ হয়েছে কিনা তা জানতে আপনার HTTP এন্ডপয়েন্টের লগ চেক করুন।
  • আপনার এন্ডপয়েন্ট ৩০ সেকেন্ডের মধ্যে অনুরোধের উত্তর দেয় কিনা তা যাচাই করুন। কোনও এন্ডপয়েন্ট রান করতে ৩০ সেকেন্ডের বেশি সময় নিলে, Chat উত্তর প্রসেস করতে পারে না এবং ইন্ট্যার‍্যাকশন ব্যর্থ হয়। বিস্তারিত জানতে রেট লিমিট ও পেশাদার পদ্ধতি দেখুন।
  • আপনার এন্ডপয়েন্ট যেন সঠিক উত্তর দেয় তা নিশ্চিত করুন। ডায়ালগ জমা দেওয়ার জন্য, এন্ডপয়েন্টকে সঠিক JSON ফর্ম্যাটে RenderActions অবজেক্ট রিটার্ন করতে হবে। উত্তরটি ভুল ফর্ম্যাটে থাকলে অথবা প্রয়োজনীয় ফিল্ড না থাকলে, ডায়ালগ ইন্টার‍্যাকশন কাজ নাও করতে পারে।

Google Chat অ্যাপ বা কার্ড কোনও সমস্যার মেসেজ দেখালে, Chat ইন্টারফেস "কিছু সমস্যা হয়েছে" লেখা মেসেজ দেখায়। অথবা "আপনার অনুরোধ প্রসেস করা যায়নি" কখনও কখনও Chat UI কোনও সমস্যার মেসেজ না দেখালেও, Chat অ্যাপ বা কার্ড অপ্রত্যাশিত ফলাফল দেয়; যেমন, কার্ড মেসেজ দেখানো নাও হতে পারে।

যদিও Chat UI-তে কোনও সমস্যার মেসেজ নাও দেখাতে পারে, Chat অ্যাপের জন্য সমস্যা লগ করার সুবিধা চালু করা থাকলে, সমস্যার বিবরণ সহ মেসেজ ও লগ ডেটা আপনাকে সমস্যা সমাধান করতে সাহায্য করার জন্য উপলভ্য থাকে। দেখতে, ডিবাগ করতে এবং সমস্যার সমাধান করতে সাহায্য পেতে, Google Chat সংক্রান্ত সমস্যার সমাধান ও তা ঠিক করা দেখুন।

অ্যাড-অন নয় এমন চ্যাট অ্যাপ: কার্ডে ব্যবহারকারীর ইনপুট করা ফর্ম ডেটা পড়া

Google Workspace অ্যাড-অন নয় এমন Chat অ্যাপের ক্ষেত্রে নিম্নলিখিত ডকুমেন্টেশন প্রযোজ্য। অ্যাড-অন নয় এমন Chat অ্যাপ মাইগ্রেট করতে, Google Chat অ্যাপকে Google Workspace অ্যাড-অনে কনভার্ট করুন দেখুন।

কার্ড ব্যবহার করে ফর্ম তৈরি করা

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

Node.js

node/contact-form-app/index.js
/**
 * The section of the contact card that contains the form input widgets. Used in a dialog and card message.
 * To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
 */
const CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": false
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": false
        }
      ]
    }
  }
];

Python

python/contact-form-app/main.py
# The section of the contact card that contains the form input widgets. Used in a dialog and card message.
# To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": False
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": False
        }
      ]
    }
  }
]

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
// The section of the contact card that contains the form input widgets. Used in a dialog and card message.
// To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
final static private List<GoogleAppsCardV1Widget> CONTACT_FORM_WIDGETS = List.of(
  new GoogleAppsCardV1Widget().setTextInput(new GoogleAppsCardV1TextInput()
    .setName("contactName")
    .setLabel("First and last name")
    .setType("SINGLE_LINE")),
  new GoogleAppsCardV1Widget().setDateTimePicker(new GoogleAppsCardV1DateTimePicker()
    .setName("contactBirthdate")
    .setLabel("Birthdate")
    .setType("DATE_ONLY")),
  new GoogleAppsCardV1Widget().setSelectionInput(new GoogleAppsCardV1SelectionInput()
    .setName("contactType")
    .setLabel("Contact type")
    .setType("RADIO_BUTTON")
    .setItems(List.of(
      new GoogleAppsCardV1SelectionItem()
        .setText("Work")
        .setValue("Work")
        .setSelected(false),
      new GoogleAppsCardV1SelectionItem()
        .setText("Personal")
        .setValue("Personal")
        .setSelected(false)))));

Apps Script

apps-script/contact-form-app/contactForm.gs
/**
 * The section of the contact card that contains the form input widgets. Used in a dialog and card message.
 * To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
 */
const CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": false
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": false
        }
      ]
    }
  }
];

ইন্টার‌্যাক্টিভ উইজেট থেকে ডেটা পাওয়া

ব্যবহারকারীরা যখনই কোনও বোতামে ক্লিক করেন, তখন অ্যাড-অন নয় এমন চ্যাট অ্যাপগুলি বোতামের লোকেশনের উপর নির্ভর করে ইন্টার‍্যাকশন ইভেন্ট পায়:

  • বোতামটি কোনও মেসেজ বা ডায়ালগে থাকলে, অ্যাড-অন নয় এমন Chat অ্যাপ একটি CARD_CLICKED ইন্ট্যার‍্যাকশন ইভেন্ট পায় যার মধ্যে ইন্ট্যার‍্যাকশন সম্পর্কিত তথ্য থাকে। CARD_CLICKED ইন্ট্যার‍্যাকশন ইভেন্টের পেলোডে common.formInputs অবজেক্ট (event.common.formInputs) থাকে যার মধ্যে ব্যবহারকারীর ইনপুট করা যেকোনও ভ্যালু থাকে।

    আপনি object common.formInputs.WIDGET_NAME থেকে ভ্যালু রিট্রিভ করতে পারবেন, যেখানে WIDGET_NAME হল name ফিল্ড যা আপনি উইজেটের জন্য নির্দিষ্ট করেছেন। মানগুলি উইজেটের জন্য নির্দিষ্ট ডেটা টাইপ হিসেবে রিটার্ন করা হয় (Inputs অবজেক্ট হিসেবে দেখানো হয়)।

    নিচে CARD_CLICKED ইন্ট্যার‍্যাকশন ইভেন্টের একটি অংশ দেখানো হয়েছে যেখানে ব্যবহারকারী প্রতিটি উইজেটের জন্য ভ্যালু ইনপুট করেছেন:

    HTTP

    {
      "type": "CARD_CLICKED",
      "common": { "formInputs": {
        "contactName": { "stringInputs": {
          "value": ["Kai 0"]
        }},
        "contactBirthdate": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }},
        "contactType": { "stringInputs": {
          "value": ["Personal"]
        }}
      }}
    }
    

    Apps Script

    {
      "type": "CARD_CLICKED",
      "common": { "formInputs": {
        "contactName": { "": { "stringInputs": {
          "value": ["Kai 0"]
        }}},
        "contactBirthdate": { "": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }}},
          "contactType": { "": { "stringInputs": {
          "value": ["Personal"]
        }}}
      }}
    }
    
  • বোতামটি হোমপেজে থাকলে, অ্যাড-অন নয় এমন চ্যাট অ্যাপ একটি SUBMIT_FORM ইন্ট্যার‍্যাকশন ইভেন্ট পায়। ইন্ট্যার‍্যাকশন ইভেন্টের পেলোডে একটি commonEventObject.formInputs অবজেক্ট (event.commonEventObject.formInputs) থাকে যার মধ্যে ব্যবহারকারীর ইনপুট করা যেকোনও ভ্যালু থাকে।

    আপনি অবজেক্ট commonEventObject.formInputs.WIDGET_NAME থেকে ভ্যালু রিট্রিভ করতে পারবেন, যেখানে WIDGET_NAME হল name ফিল্ড যা আপনি উইজেটের জন্য নির্দিষ্ট করেছেন। মানগুলি উইজেটের জন্য নির্দিষ্ট ডেটা টাইপ হিসেবে রিটার্ন করা হয় (Inputs অবজেক্ট হিসেবে দেখানো হয়)।

    নিচে SUBMIT_FORM ইন্ট্যার‍্যাকশন ইভেন্টের একটি অংশ দেখানো হয়েছে যেখানে ব্যবহারকারী প্রতিটি উইজেটের জন্য ভ্যালু ইনপুট করেছেন:

    HTTP

    {
      "type": "SUBMIT_FORM",
      "commonEventObject": { "formInputs": {
        "contactName": { "stringInputs": {
          "value": ["Kai 0"]
        }},
        "contactBirthdate": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }},
        "contactType": { "stringInputs": {
          "value": ["Personal"]
        }}
      }}
    }
    

    Apps Script

    {
      "type": "SUBMIT_FORM",
      "commonEventObject": { "formInputs": {
        "contactName": { "": { "stringInputs": {
          "value": ["Kai 0"]
        }}},
        "contactBirthdate": { "": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }}},
          "contactType": { "": { "stringInputs": {
          "value": ["Personal"]
        }}}
      }}
    }
    

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

ফর্ম ইনপুট উইজেট ইনপুট ডেটার ধরন ইন্টার‍্যাকশন ইভেন্ট থেকে ইনপুট ভ্যালু উদাহরণ ভ্যালু
textInput stringInputs event.common.formInputs.contactName.stringInputs.value[0] Kai O
selectionInput stringInputs প্রথম বা একমাত্র ভ্যালু পেতে, event.common.formInputs.contactType.stringInputs.value[0] Personal
dateTimePicker যা শুধুমাত্র তারিখ গ্রহণ করে। dateInput event.common.formInputs.contactBirthdate.dateInput.msSinceEpoch। 1000425600000

অন্য কার্ডে ডেটা ট্রান্সফার করা

অ্যাড-অন নয় এমন Chat অ্যাপে প্রাথমিক কার্ড থেকে ইনপুট করা ডেটা ট্রান্সফার করতে, button উইজেট তৈরি করুন যার মধ্যে actionParameters উইজেটের name এবং ব্যবহারকারীর ইনপুট করা ভ্যালু থাকবে, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

Node.js

node/contact-form-app/index.js
buttonList: { buttons: [{
  text: "Submit",
  onClick: { action: {
    function: "submitForm",
    parameters: [{
      key: "contactName", value: name }, {
      key: "contactBirthdate", value: birthdate }, {
      key: "contactType", value: type
    }]
  }}
}]}

Python

python/contact-form-app/main.py
'buttonList': { 'buttons': [{
  'text': "Submit",
  'onClick': { 'action': {
    'function': "submitForm",
    'parameters': [{
      'key': "contactName", 'value': name }, {
      'key': "contactBirthdate", 'value': birthdate }, {
      'key': "contactType", 'value': type
    }]
  }}
}]}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
  .setText("Submit")
  .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
    .setFunction("submitForm")
    .setParameters(List.of(
      new GoogleAppsCardV1ActionParameter().setKey("contactName").setValue(name),
      new GoogleAppsCardV1ActionParameter().setKey("contactBirthdate").setValue(birthdate),
      new GoogleAppsCardV1ActionParameter().setKey("contactType").setValue(type))))))))));

Apps Script

apps-script/contact-form-app/main.gs
buttonList: { buttons: [{
  text: "Submit",
  onClick: { action: {
    function: "submitForm",
    parameters: [{
      key: "contactName", value: name }, {
      key: "contactBirthdate", value: birthdate }, {
      key: "contactType", value: type
    }]
  }}
}]}

ব্যবহারকারী বোতামে ক্লিক করলে, যে Chat অ্যাপটি অ্যাড-অন নয় সেটি CARD_CLICKED ইন্ট্যার‍্যাকশন ইভেন্ট পায় যেখান থেকে আপনি ডেটা পেতে পারেন।

ফর্ম জমা দেওয়ার ব্যাপারে উত্তর দেওয়া

নিচের উদাহরণে, কোনও অ্যাড-অন নয় এমন একটি Chat অ্যাপ কনফার্ম করার জন্য একটি টেক্সট মেসেজ পাঠায় যে এটি কোনও ডায়ালগ বা কার্ড মেসেজ থেকে জমা দেওয়া ফর্ম সফলভাবে পেয়েছে:

Node.js

node/contact-form-app/index.js
const contactName = event.common.parameters["contactName"];
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
const errorMessage = "Don't forget to name your new contact!";
if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { actionStatus: {
      statusCode: "INVALID_ARGUMENT",
      userFacingMessage: errorMessage
    }}
  }};
}

Python

python/contact-form-app/main.py
contact_name = event.get('common').get('parameters')["contactName"]
# Checks to make sure the user entered a contact name.
# If no name value detected, returns an error message.
error_message = "Don't forget to name your new contact!"
if contact_name == "" and "SUBMIT_DIALOG" == event.get('dialogEventType'):
  return { 'actionResponse': {
    'type': "DIALOG",
    'dialogAction': { 'actionStatus': {
      'statusCode': "INVALID_ARGUMENT",
      'userFacingMessage': error_message
    }}
  }}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
String contactName = event.at("/common/parameters/contactName").asText();
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
String errorMessage = "Don't forget to name your new contact!";
if (contactName.isEmpty() && event.at("/dialogEventType") != null && "SUBMIT_DIALOG".equals(event.at("/dialogEventType").asText())) {
  return new Message().setActionResponse(new ActionResponse()
    .setType("DIALOG")
    .setDialogAction(new DialogAction().setActionStatus(new ActionStatus()
      .setStatusCode("INVALID_ARGUMENT")
      .setUserFacingMessage(errorMessage))));
}

Apps Script

apps-script/contact-form-app/main.gs
const contactName = event.common.parameters["contactName"];
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
const errorMessage = "Don't forget to name your new contact!";
if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { actionStatus: {
      statusCode: "INVALID_ARGUMENT",
      userFacingMessage: errorMessage
    }}
  }};
}

অ্যাড-অন নয় এমন Chat অ্যাপে ডায়ালগ প্রসেস ও বন্ধ করতে, ActionResponse অবজেক্ট রিটার্ন করুন যা নির্দিষ্ট করে যে আপনি কনফার্মেশন মেসেজ পাঠাতে, আসল মেসেজ বা কার্ড আপডেট করতে চান নাকি শুধু ডায়ালগ বন্ধ করতে চান। ধাপগুলি জানতে, ডায়ালগ বন্ধ করুন দেখুন।