افزودن عناصر تعاملی واسط کاربر به کارت‌ها

این صفحه توضیح می‌دهد که چگونه ابزاره‌ها و عناصر میانای کاربر را به کارت‌ها اضافه کنید تا کاربران بتوانند با برنامه Google Chat شما تعامل داشته باشند، مثلاً با کلیک کردن روی دکمه یا ارسال اطلاعات.

برنامه‌های Chat می‌توانند از میاناهای Chat زیر برای ساختن کارت‌های تعاملی استفاده کنند:

  • پیام‌هایی که حاوی یک یا چند کارت هستند.
  • صفحه‌های اصلی، که کارتی است که از برگه صفحه اصلی در پیام‌های مستقیم با برنامه Chat ظاهر می‌شود.
  • کادرهای گفتگو که کارت‌هایی هستند که در پنجره جدیدی از پیام‌ها و صفحه‌های اصلی باز می‌شوند.

وقتی کاربران با کارت‌ها تعامل می‌کنند، برنامه‌های Chat می‌توانند از داده‌هایی که دریافت می‌کنند برای پردازش و پاسخ دادن استفاده کنند. برای جزئیات، جمع‌آوری و پردازش اطلاعات از کاربران Google Chat را ببینید.


از «کارت‌ساز» برای طراحی و پیش‌نمایش پیام‌رسانی و میاناهای کاربر برای برنامه‌های Chat استفاده کنید:

باز کردن «کارت‌ساز»

پیش‌نیازها

برنامه Google Chat که برای دریافت و پاسخ دادن به تعاملات کاربر پیکربندی شده است. برای ایجاد برنامه Chat تعاملی، یکی از شروع‌های سریع زیر را براساس معماری برنامه که می‌خواهید استفاده کنید تکمیل کنید:

افزودن دکمه

ابزارک ButtonList مجموعه‌ای از دکمه‌ها را نمایش می‌دهد. دکمه‌ها می‌توانند نوشتار، نماد، یا نوشتار و نماد را نمایش دهند. هر Button از OnClick کنشی پشتیبانی می‌کند که وقتی کاربران روی دکمه کلیک می‌کنند اتفاق می‌افتد. برای مثال:

  • اَبَرپیوندی را با OpenLink باز کنید تا اطلاعات بیشتری به کاربران ارائه دهید.
  • اجرای action که تابع سفارشی را اجرا می‌کند، مثل فراخوانی میانای برنامه‌سازی کاربردی.

برای دسترس‌پذیری، دکمه‌ها از نوشتار جایگزین پشتیبانی می‌کنند.

افزودن دکمه‌ای که تابع سفارشی را اجرا می‌کند

در زیر کارتی متشکل از ابزاره ButtonList با دو دکمه نشان داده شده است. یک دکمه مستندات توسعه‌دهنده Google Chat را در برگه جدیدی باز می‌کند. دکمه دیگر تابع سفارشی‌ای به‌نام goToView() را اجرا می‌کند و پارامتر viewType="BIRD EYE VIEW" را ارسال می‌کند.

افزودن دکمه با سبک Material Design

در زیر مجموعه‌ای از دکمه‌ها در سبک‌های مختلف دکمه «طراحی مواد» نمایش داده شده است.

برای اعمال سبک «طراحی مواد»، مشخصه «رنگ» را اضافه نکنید.

افزودن دکمه با رنگ سفارشی و دکمه غیرفعال‌شده

با تنظیم "disabled": "true" می‌توانید از کلیک کردن کاربران روی دکمه جلوگیری کنید.

در زیر کارتی متشکل از ابزارک ButtonList با دو دکمه نمایش داده شده است. یک دکمه از فیلد Color برای سفارشی‌سازی رنگ پس‌زمینه دکمه استفاده می‌کند. دکمه دیگر با فیلد Disabled غیرفعال می‌شود که مانع از کلیک کردن کاربر روی دکمه و اجرای عملکرد می‌شود.

افزودن دکمه با نماد

در زیر کارتی متشکل از یک ابزارک ButtonList با دو ابزارک نماد Button نمایش داده شده است. یک دکمه از فیلد knownIcon برای نمایش نماد ایمیل داخلی Google Chat استفاده می‌کند. دکمه دیگر از فیلد iconUrl برای نمایش ابزاره نماد سفارشی استفاده می‌کند.

افزودن دکمه با نماد و نوشتار

در زیر کارتی متشکل از ابزارک ButtonList نمایش داده شده است که از کاربر درخواست می‌کند ایمیل ارسال کند. دکمه اول نماد ایمیل را نمایش می‌دهد و دکمه دوم نوشتار را نمایش می‌دهد. کاربر می‌تواند روی نماد یا دکمه نوشتاری کلیک کند تا عملکرد sendEmail اجرا شود.

سفارشی‌سازی دکمه برای بخش جمع‌شدنی

دکمه کنترلی را که بخش‌های درون کارت را جمع و باز می‌کند سفارشی‌سازی کنید. از میان طیفی از نمادها یا تصاویر انتخاب کنید تا محتوای بخش را به‌صورت دیداری نمایش دهید و درک و تعامل با اطلاعات را برای کاربران آسان‌تر کنید.

افزودن منوِ سرریز

Overflow menu می‌تواند در کارت‌های Chat برای ارائه گزینه‌ها و کنش‌های بیشتر استفاده شود. این عنصر به شما امکان می‌دهد گزینه‌های بیشتری را بدون شلوغ کردن میانای کارت اضافه کنید و طراحی تمیز و منظمی را تضمین می‌کند.

افزودن فهرست تراشه‌ها

ابزاره ChipList روشی همه‌کاره و ازنظر بصری جذاب برای نمایش اطلاعات ارائه می‌دهد. از فهرست‌های تراشه‌ای برای نمایش برچسب‌ها، دسته‌ها، یا سایر داده‌های مرتبط استفاده کنید تا پیمایش و تعامل با محتوایتان برای کاربران آسان‌تر شود.

جمع‌آوری اطلاعات از کاربران

این بخش توضیح می‌دهد که چگونه می‌توانید ابزارهایی را اضافه کنید که اطلاعاتی مانند نوشتار یا انتخاب‌ها را جمع‌آوری می‌کنند.

برای آشنایی با نحوه پردازش ورودی‌های کاربران، به جمع‌آوری و پردازش اطلاعات از کاربران Google Chat مراجعه کنید.

جمع‌آوری نوشتار

ابزاره TextInput فیلدی ارائه می‌دهد که کاربران می‌توانند در آن نوشتار وارد کنند. ابزاره از پیشنهادها پشتیبانی می‌کند که به کاربران کمک می‌کند داده‌های یکنواخت وارد کنند، و از کنش‌های هنگام تغییر پشتیبانی می‌کند که Actions هستند که وقتی تغییری در فیلد ورودی نوشتار رخ می‌دهد، مثلاً وقتی کاربر نوشتاری را اضافه یا حذف می‌کند، اجرا می‌شوند.

وقتی لازم است داده‌های انتزاعی یا ناشناخته از کاربران جمع‌آوری کنید، از این ابزاره TextInput استفاده کنید. برای جمع‌آوری داده‌های تعریف‌شده از کاربران، از ابزاره SelectionInput استفاده کنید.

در زیر کارتی متشکل از ابزاره TextInput آمده است:

جمع‌آوری تاریخ یا زمان

ابزارک DateTimePicker به کاربران اجازه می‌دهد تاریخ، زمان، یا هم تاریخ و هم زمان را وارد کنند. یا کاربران می‌توانند از انتخاب‌گر برای انتخاب تاریخ و زمان استفاده کنند. اگر کاربران تاریخ یا زمان نامعتبری وارد کنند، انتخابگر خطایی نشان می‌دهد که از کاربران می‌خواهد اطلاعات را به‌درستی وارد کنند.

در زیر کارتی متشکل از سه نوع مختلف DateTimePicker ابزارک نمایش داده شده است:

به کاربران اجازه دهید موارد را انتخاب کنند

ابزاره SelectionInput مجموعه‌ای از موارد قابل‌انتخاب، مانند چارگوش‌های انتخاب، دکمه‌های رادیویی، کلیدها، یا منوِ کرکره‌ای را ارائه می‌دهد. می‌توانید از این ابزاره برای جمع‌آوری داده‌های تعریف‌شده و استانداردشده از کاربران استفاده کنید. برای جمع‌آوری داده‌های تعریف‌نشده از کاربران، به‌جای آن از ابزاره TextInput استفاده کنید.

ابزاره SelectionInput از پیشنهادها پشتیبانی می‌کند که به کاربران کمک می‌کند داده‌های یکسان وارد کنند، و از کنش‌های هنگام تغییر پشتیبانی می‌کند که Actions هستند و وقتی تغییری در فیلد ورودی انتخاب رخ می‌دهد، مثلاً وقتی کاربر موردی را انتخاب یا لغو انتخاب می‌کند، اجرا می‌شوند.

برنامه‌های گپ می‌توانند مقدار موارد انتخاب‌شده را دریافت و پردازش کنند. برای جزئیات درباره کار با ورودی‌های فرم، به پردازش اطلاعات واردشده توسط کاربران مراجعه کنید.

این بخش نمونه‌هایی از کارت‌هایی را ارائه می‌دهد که از ابزاره SelectionInput استفاده می‌کنند. نمونه‌ها از انواع مختلف ورودی بخش استفاده می‌کنند:

افزودن چارگوش انتخاب

در زیر کارتی نمایش داده می‌شود که از کاربر می‌خواهد مشخص کند مخاطب حرفه‌ای، شخصی، یا هر دو است، با ابزاره SelectionInput که از چارگوش‌های انتخاب استفاده می‌کند:

افزودن دکمه رادیویی

در زیر کارتی نمایش داده می‌شود که از کاربر می‌خواهد بااستفاده از ابزاره SelectionInput که از دکمه‌های رادیویی استفاده می‌کند، مشخص کند مخاطب حرفه‌ای است یا شخصی:

افزودن کلید

در زیر کارتی نمایش داده می‌شود که از کاربر می‌خواهد بااستفاده از ابزاره SelectionInput که از کلید استفاده می‌کند، مشخص کند مخاطب حرفه‌ای، شخصی، یا هر دو است:

در زیر کارتی نمایش داده شده است که از کاربر می‌خواهد بااستفاده از ابزاره SelectionInput که از منوِ کرکره‌ای استفاده می‌کند، مشخص کند مخاطب حرفه‌ای است یا شخصی:

منوهای کرکره‌ای را به‌طور پویا پر کنید

برای برنامه‌های Google Chat دردسترس است.

می‌توانید موارد منوِ کرکره‌ای را به‌طور پویا از منابع داده در Google Workspace یا از منبع داده خارجی پر کنید. برای استفاده از منابع داده پویا، فیلد dataSourceConfigs را مشخص می‌کنید که آرایه‌ای از اشیاء DataSourceConfig است. هر DataSourceConfig می‌تواند حاوی platformDataSource یا remoteDataSource باشد. درحال‌حاضر فقط یک DataSourceConfig پشتیبانی می‌شود.

موارد را از Google Workspace پر می‌کند

برای پر کردن موارد از منابع داده Google Workspace، مثل کاربران Google Workspace، فیلد platformDataSource را در DataSourceConfig مشخص می‌کنید. برخلاف استفاده از items ایستا، شما اشیای SelectionItem را حذف می‌کنید، زیرا این موارد انتخاب به‌طور پویا از Google Workspace تأمین می‌شوند.

کد زیر منوِ کرکره‌ای را نشان می‌دهد که کاربران Google Workspace را پر می‌کند:

(قالب) JSON

{
  "sections": [
    {
      "header": "Section Header",
      "widgets": [
        {
          "selectionInput": {
            "name": "contacts",
            "type": "DROPDOWN",
            "label": "Select contact from organization",
            "dataSourceConfigs": [
              {
                "platformDataSource": {
                  "commonDataSource": "USER"
                },
                "minCharactersTrigger": 1
              }
            ]
          }
        }
      ]
    }
  ]
}
پر کردن موارد از منبع داده خارجی

برای پر کردن موارد از منبع داده خارجی یا طرف سوم، مانند سیستم مدیریت ارتباط با مشتری (CRM)، از فیلد remoteDataSource در DataSourceConfig برای مشخص کردن تابعی استفاده می‌کنید که موارد را از منبع داده برمی‌گرداند.

کد زیر منوِ کرکره‌ای را نشان می‌دهد که با اجرای تابع getCrmLeads، موارد را از مجموعه خارجی مخاطبین پر می‌کند:

(قالب) JSON

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

برای کاهش درخواست‌ها به منبع داده پویا، می‌توانید موارد پیشنهادی را که قبل‌از تایپ کردن کاربران در منوِ کرکره‌ای ظاهر می‌شوند اضافه کنید. همچنین می‌توانید منو کرکره‌ای را پیکربندی کنید تا موارد را براساس آنچه کاربران تایپ می‌کنند تکمیل خودکار کند. برای این کار، minCharactersTrigger را در DataSourceConfig تنظیم کنید. وقتی کاربر حداقل تعداد نویسه‌های مشخص‌شده در minCharactersTrigger را تایپ می‌کند، تابع مشخص‌شده در remoteDataSource راه‌اندازی می‌شود. شیء رویداد منتقل‌شده به تابع شما شامل ورودی کاربر در کلید autocomplete_widget_query است.

افزودن منو چندانتخابی

در زیر، کارتی نمایش داده شده است که از کاربر می‌خواهد مخاطبین را از منو چندانتخابی انتخاب کند:

می‌توانید موارد منو چندانتخابی را از منابع داده زیر در Google Workspace پر کنید:

  • کاربران Google Workspace: فقط می‌توانید کاربران را در همان سازمان Google Workspace اضافه کنید.
  • فضاهای Chat: کاربری که موارد را در منو چندانتخابی وارد می‌کند فقط می‌تواند فضاهایی را که به آن‌ها تعلق دارد در سازمان Google Workspace خود مشاهده و انتخاب کند.

برای استفاده از منابع داده Google Workspace، فیلد 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
          }
        }
      }
    }
  }
}

منوهای چندانتخابی همچنین می‌توانند موارد را از منبع داده خارجی یا طرف سوم پر کنند. برای مثال، می‌توانید از منوهای چندانتخابی استفاده کنید تا به کاربر کمک کنید از فهرست مشتریان بالقوه در سیستم مدیریت ارتباط با مشتری (CRM) انتخاب کند.

برای استفاده از منبع داده خارجی، از فیلد 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/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 Script استفاده کنید.

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")]
}

پر کردن موارد پیشنهادی از منبع داده پویا

برای منابع داده خارجی، همچنین می‌توانید مواردی را که کاربران شروع به تایپ کردن در منو چندانتخابی یا منو کرکره‌ای می‌کنند تکمیل خودکار کنید و پیشنهاد دهید. برای مثال، اگر کاربر شروع به تایپ کردن Atl برای منویی کند که شهرهای ایالات متحده را نشان می‌دهد، برنامه Chat شما می‌تواند قبل‌از اینکه کاربر تایپ کردن را تمام کند، Atlanta را به‌طور خودکار پیشنهاد دهد. می‌توانید حداکثر ۱۰۰ مورد پیشنهاد دهید.

برای برگرداندن موارد پیشنهادی، تابعی که منبع داده خارجی را پُرسمان می‌کند باید کارهای زیر را انجام دهد:

  1. یک شیء رویداد را مدیریت کنید، که برنامه Chat هنگام تایپ کردن کاربران در منو دریافت می‌کند.
  2. از شیء رویداد، مقداری را که کاربر تایپ می‌کند دریافت کنید، که در فیلد event.commonEventObject.parameters["autocomplete_widget_query"] نشان داده می‌شود.
  3. بااستفاده از مقدار ورودی کاربر، منبع داده را پُرسمان کنید تا یک یا چند SelectionItems برای پیشنهاد به کاربر دریافت کنید.
  4. موارد پیشنهادی را با برگرداندن کنش RenderActions با شیء modifyCard برگردانید.

نمونه کد زیر نشان می‌دهد که چگونه یک برنامه Chat به‌طور پویا موارد را در منوی چندانتخابی روی کارت پیشنهاد می‌کند. وقتی کاربر در منو تایپ می‌کند، تابع یا نقطه پایانی ارائه‌شده در فیلد 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/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 Script استفاده کنید.

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

اعتبارسنجی داده‌های واردشده به کارت‌ها

این صفحه نحوه اعتبارسنجی داده‌های واردشده به action و ابزاره‌های کارت را توضیح می‌دهد. برای مثال، می‌توانید اعتبار سنجی کنید که فیلد ورودی نوشتار دارای نوشتار واردشده توسط کاربر است یا تعداد مشخصی نویسه دارد.

تنظیم ابزاره‌های لازم برای کنش‌ها

به‌عنوان بخشی از action کارت، نام ابزارهایی را که کنش به آن‌ها نیاز دارد به فهرست requiredWidgets آن اضافه کنید.

اگر هرکدام از ابزارهایی که در اینجا فهرست شده‌اند هنگام فراخوانی این کنش مقداری نداشته باشند، ارسال کنش فرم لغو می‌شود.

وقتی "allWidgetsAreRequired": true برای کنشی تنظیم شده باشد، همه ابزاره‌های کارت برای این کنش لازم است.

تنظیم کنش allWidgetsAreRequired در چندانتخابی

(قالب) JSON

{
  "sections": [
    {
      "header": "Select contacts",
      "widgets": [
        {
          "selectionInput": {
            "type": "MULTI_SELECT",
            "label": "Selected contacts",
            "name": "contacts",
            "multiSelectMaxSelectedItems": 3,
            "multiSelectMinQueryLength": 1,
            "onChangeAction": {
              "allWidgetsAreRequired": true
            },
            "items": [
              {
                "value": "contact-1",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 1",
                "bottomText": "Contact one description",
                "selected": false
              },
              {
                "value": "contact-2",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 2",
                "bottomText": "Contact two description",
                "selected": false
              },
              {
                "value": "contact-3",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 3",
                "bottomText": "Contact three description",
                "selected": false
              },
              {
                "value": "contact-4",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 4",
                "bottomText": "Contact four description",
                "selected": false
              },
              {
                "value": "contact-5",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 5",
                "bottomText": "Contact five description",
                "selected": false
              }
            ]
          }
        }
      ]
    }
  ]
}
تنظیم کنش allWidgetsAreRequired در dateTimePicker

(قالب) JSON

{
  "sections": [
    {
      "widgets": [
        {
          "textParagraph": {
            "text": "A datetime picker widget with both date and time:"
          }
        },
        {
          "divider": {}
        },
        {
          "dateTimePicker": {
            "name": "date_time_picker_date_and_time",
            "label": "meeting",
            "type": "DATE_AND_TIME"
          }
        },
        {
          "textParagraph": {
            "text": "A datetime picker widget with just date:"
          }
        },
        {
          "divider": {}
        },
        {
          "dateTimePicker": {
            "name": "date_time_picker_date_only",
            "label": "Choose a date",
            "type": "DATE_ONLY",
            "onChangeAction":{
              "allWidgetsAreRequired": true
            }
          }
        },
        {
          "textParagraph": {
            "text": "A datetime picker widget with just time:"
          }
        },
        {
          "divider": {}
        },
        {
          "dateTimePicker": {
            "name": "date_time_picker_time_only",
            "label": "Select a time",
            "type": "TIME_ONLY"
          }
        }
      ]
    }
  ]
}
تنظیم کنش allWidgetsAreRequired در منوِ کرکره‌ای

(قالب) JSON

{
  "sections": [
    {
      "header": "Section Header",
      "collapsible": true,
      "uncollapsibleWidgetsCount": 1,
      "widgets": [
        {
          "selectionInput": {
            "name": "location",
            "label": "Select Color",
            "type": "DROPDOWN",
            "onChangeAction": {
              "allWidgetsAreRequired": true
            },
            "items": [
              {
                "text": "Red",
                "value": "red",
                "selected": false
              },
              {
                "text": "Green",
                "value": "green",
                "selected": false
              },
              {
                "text": "White",
                "value": "white",
                "selected": false
              },
              {
                "text": "Blue",
                "value": "blue",
                "selected": false
              },
              {
                "text": "Black",
                "value": "black",
                "selected": false
              }
            ]
          }
        }
      ]
    }
  ]
}

تنظیم کردن اعتبارسنجی برای ابزاره ورودی نوشتار

در فیلد اعتبارسنجی ابزاره textInput، می‌توان حد نویسه و نوع ورودی را برای این ابزاره ورودی نوشتار مشخص کرد.

تنظیم حد نویسه برای ابزاره ورودی نوشتار

(قالب) JSON

{
  "sections": [
    {
      "header": "Tell us about yourself",
      "collapsible": true,
      "uncollapsibleWidgetsCount": 2,
      "widgets": [
        {
          "textInput": {
            "name": "favoriteColor",
            "label": "Favorite color",
            "type": "SINGLE_LINE",
            "validation": {"characterLimit": 15},
            "onChangeAction":{
              "allWidgetsAreRequired": true
            }
          }
        }
      ]
    }
  ]
}
تنظیم نوع ورودی برای ابزاره ورودی نوشتاری

(قالب) JSON

{
  "sections": [
    {
      "header": "Validate text inputs by input types",
      "collapsible": true,
      "uncollapsibleWidgetsCount": 2,
      "widgets": [
        {
          "textInput": {
            "name": "mailing_address",
            "label": "Please enter a valid email address",
            "type": "SINGLE_LINE",
            "validation": {
              "inputType": "EMAIL"
            },
            "onChangeAction": {
              "allWidgetsAreRequired": true
            }
          }
        },
        {
          "textInput": {
            "name": "validate_integer",
            "label": "Please enter a number",
              "type": "SINGLE_LINE",
            "validation": {
              "inputType": "INTEGER"
            }
          }
        },
        {
          "textInput": {
            "name": "validate_float",
            "label": "Please enter a number with a decimal",
            "type": "SINGLE_LINE",
            "validation": {
              "inputType": "FLOAT"
            }
          }
        }
      ]
    }
  ]
}

عیب‌یابی

وقتی برنامه Google Chat یا کارت خطایی را برمی‌گرداند، میانای Chat پیامی با این مضمون نشان می‌دهد: «مشکلی پیش آمد.» یا «نمی‌توانیم درخواستتان را پردازش کنیم.» گاهی اوقات میانای کاربری Chat هیچ پیام خطایی نمایش نمی‌دهد، اما برنامه Chat یا کارت نتیجه غیرمنتظره‌ای تولید می‌کند؛ برای مثال، ممکن است پیام کارت ظاهر نشود.

اگرچه ممکن است پیام خطا در میانای کاربر Chat نمایش داده نشود، پیام‌های خطای توصیفی و داده‌های گزارش برای کمک به شما در رفع خطاها هنگامی که ثبت خطا برای برنامه‌های Chat روشن است، دردسترس هستند. برای دریافت راهنمایی درباره مشاهده، اشکال‌زدایی، و رفع خطاها، به عیب‌یابی و رفع خطاهای Google Chat مراجعه کنید.

برنامه‌های گپ که برافزا نیستند: طراحی کارت‌ها و کادرهای گفتگوی تعاملی

اسناد زیر برای برنامه‌های Chat که برافزاهای Google Workspace نیستند اعمال می‌شود. برای انتقال برنامه Chat که برافزا نیست، به تبدیل برنامه Google Chat به برافزای Google Workspace مراجعه کنید.

کد زیر منو چندانتخابی از موارد را از مجموعه خارجی مخاطبین برای کاربر در برنامه Chat که برافزا نیست نشان می‌دهد. منو به‌طور پیش‌فرض یک مخاطب را نمایش می‌دهد و تابع getContacts را برای بازیابی و پر کردن موارد از منبع داده خارجی اجرا می‌کند:

Node.js

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

Python

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

جاوا

java/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("getContacts"))
  .setItems(List.of(getContact("3")))))))))));

Apps Script

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

برای تکمیل خودکار موارد در برنامه Chat که برافزا نیست، تابعی ایجاد کنید که از منبع داده خارجی پُرسمان کند و هروقت کاربر در منو چندانتخابی تایپ می‌کند، موارد را برگرداند. تابع باید موارد زیر را انجام دهد:

  • شیء رویدادی را که نشان‌دهنده تعامل کاربر با منو است ارسال کنید.
  • بررسی کنید که مقدار invokedFunction رویداد تعامل با تابع فیلد externalDataSource مطابقت داشته باشد.
  • وقتی توابع مطابقت داشته باشند، موارد پیشنهادی را از منبع داده خارجی برمی‌گرداند. برای پیشنهاد دادن موارد براساس آنچه کاربر تایپ می‌کند، مقدار کلید autocomplete_widget_query را دریافت کنید. این مقدار نشان‌دهنده چیزی است که کاربر در منو تایپ می‌کند.

کد زیر موارد را از منبع داده خارجی تکمیل خودکار می‌کند. بااستفاده از مثال قبلی، برنامه Chat که برافزا نیست، موارد را براساس زمان راه‌اندازی تابع getContacts پیشنهاد می‌کند:

Node.js

node/selection-input/index.js
/**
 * Responds to a WIDGET_UPDATE event in Google Chat.
 *
 * @param {Object} event The event object from Chat API.
 * @return {Object} Response from the Chat app.
 */
function onWidgetUpdate(event) {
  if (event.common["invokedFunction"] === "getContacts") {
    const query = event.common.parameters["autocomplete_widget_query"];
    return { actionResponse: {
      type: "UPDATE_WIDGET",
      updatedWidget: { suggestions: { items: [
        // The list is static here but it could be dynamic.
        getContact("1"), getContact("2"), getContact("3"), getContact("4"), getContact("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 suggested item for selectors.
 */
function getContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

Python

python/selection-input/main.py
def on_widget_update(event: dict) -> dict:
  """Responds to a WIDGET_UPDATE event in Google Chat."""
  if "getContacts" == event.get("common").get("invokedFunction"):
    query = event.get("common").get("parameters").get("autocomplete_widget_query")
    return { 'actionResponse': {
      'type': "UPDATE_WIDGET",
      'updatedWidget': { 'suggestions': { 'items': list(filter(lambda e: query is None or query in e["text"], [
        # The list is static here but it could be dynamic.
        get_contact("1"), get_contact("2"), get_contact("3"), get_contact("4"), get_contact("5")
      # Only return items based on the query from the user
      ]))}}
    }}


def get_contact(id: str) -> dict:
  """Generate a suggested contact given an ID."""
  return {
    'value': id,
    'startIconUri': "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    'text': "Contact " + id
  }

جاوا

java/selection-input/src/main/java/com/google/chat/selectionInput/App.java
// Responds to a WIDGET_UPDATE event in Google Chat.
Message onWidgetUpdate(JsonNode event) {
  if ("getContacts".equals(event.at("/invokedFunction").asText())) {
    String query = event.at("/common/parameters/autocomplete_widget_query").asText();
    return new Message().setActionResponse(new ActionResponse()
      .setType("UPDATE_WIDGET")
      .setUpdatedWidget(new UpdatedWidget()
        .setSuggestions(new SelectionItems().setItems(List.of(
          // The list is static here but it could be dynamic.
          getContact("1"), getContact("2"), getContact("3"), getContact("4"), getContact("5")
        // Only return items based on the query from the user
        ).stream().filter(e -> query == null || e.getText().indexOf(query) > -1).toList()))));
  }
  return null;
}

// Generate a suggested contact given an ID.
GoogleAppsCardV1SelectionItem getContact(String id) {
  return new GoogleAppsCardV1SelectionItem()
    .setValue(id)
    .setStartIconUri("https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png")
    .setText("Contact " + id);
}

Apps Script

apps-script/selection-input/selection-input.gs
/**
 * Responds to a WIDGET_UPDATE event in Google Chat.
 *
 * @param {Object} event The event object from Chat API.
 * @return {Object} Response from the Chat app.
 */
function onWidgetUpdate(event) {
  if (event.common["invokedFunction"] === "getContacts") {
    const query = event.common.parameters["autocomplete_widget_query"];
    return { actionResponse: {
      type: "UPDATE_WIDGET",
      updatedWidget: { suggestions: { items: [
        // The list is static here but it could be dynamic.
        getContact("1"), getContact("2"), getContact("3"), getContact("4"), getContact("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 suggested item for selectors.
 */
function getContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}