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

این صفحه توضیح می‌دهد که چگونه ابزاره‌ها و عناصر میانای کاربر را به کارت‌ها اضافه کنید تا کاربران بتوانند با برنامه 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 یا از منبع داده خارجی اضافه کنید. برای استفاده از منابع داده پویا، فیلد data_source_configs را مشخص می‌کنید که آرایه‌ای از 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",
            "data_source_configs": [
              {
                "platformDataSource": {
                  "commonDataSource": "USER"
                },
                "min_characters_trigger": 1
              }
            ]
          }
        }
      ]
    }
  ]
}
پر کردن موارد از منبع داده خارجی

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

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

(قالب) 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"
              }
            ]
          }
        }
      ]
    }
  ]
}

برای کاهش درخواست‌ها به منبع داده پویا، می‌توانید مواردی را که در منو کرکره‌ای قبل‌از تایپ کردن کاربران ظاهر می‌شود اضافه کنید. همچنین می‌توانید منو کرکره‌ای را پیکربندی کنید تا براساس آنچه کاربران تایپ می‌کنند، موارد را با تنظیم min_characters_trigger در DataSourceConfig تکمیل خودکار کند. وقتی کاربر حداقل تعداد نویسه‌های مشخص‌شده در min_characters_trigger را تایپ می‌کند، تابع مشخص‌شده در 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 خود نیاز دارد اضافه کنید.

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

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

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

(قالب) JSON

{
  "sections": [
    {
      "header": "Select contacts",
      "widgets": [
        {
          "selectionInput": {
            "type": "MULTI_SELECT",
            "label": "Selected contacts",
            "name": "contacts",
            "multiSelectMaxSelectedItems": 3,
            "multiSelectMinQueryLength": 1,
            "onChangeAction": {
              "all_widgets_are_required": 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
              }
            ]
          }
        }
      ]
    }
  ]
}
تنظیم کنش all_widgets_are_required در 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":{
              "all_widgets_are_required": 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"
          }
        }
      ]
    }
  ]
}
کنش all_widgets_are_required را در منوِ کرکره‌ای تنظیم کنید

(قالب) JSON

{
  "sections": [
    {
      "header": "Section Header",
      "collapsible": true,
      "uncollapsibleWidgetsCount": 1,
      "widgets": [
        {
          "selectionInput": {
            "name": "location",
            "label": "Select Color",
            "type": "DROPDOWN",
            "onChangeAction": {
              "all_widgets_are_required": 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": {"character_limit":15},
            "onChangeAction":{
              "all_widgets_are_required": 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": {
              "input_type": "EMAIL"
            },
            "onChangeAction": {
              "all_widgets_are_required": true
            }
          }
        },
        {
          "textInput": {
            "name": "validate_integer",
            "label": "Please enter a number",
              "type": "SINGLE_LINE",
            "validation": {
              "input_type": "INTEGER"
            }
          }
        },
        {
          "textInput": {
            "name": "validate_float",
            "label": "Please enter a number with a decimal",
            "type": "SINGLE_LINE",
            "validation": {
              "input_type": "FLOAT"
            }
          }
        }
      ]
    }
  ]
}

عیب‌یابی

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

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

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

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

کد زیر منو چندانتخابی از موارد را از مجموعه مخاطبین خارجی برای کاربر در برنامه «گپ» که برافزا نیست نشان می‌دهد. این منو به‌طور پیش‌فرض یک مخاطب را نمایش می‌دهد و تابع 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
  };
}