Как собирать и управлять контактами в Google Chat

В этом руководстве рассказывается, как создать приложение Google Chat, которое поможет пользователям Google Chat управлять личными и рабочими контактами. Чтобы собрать информацию, приложение Chat предлагает пользователям заполнить форму обратной связи в сообщениях-карточках и диалоговых окнах.

Посмотрите, как работает приложение Chat:

  • Форма обратной связи, открытая с помощью слеш-команды.
    Рисунок 1. Приложение Chat отвечает на слеш-команду /about текстовым сообщением и кнопкой, которая открывает форму обратной связи.
  • Форма обратной связи в диалоговом окне.
    Рисунок 2. В приложении Chat откроется диалоговое окно, в котором пользователи могут ввести информацию о контакте.
  • Диалоговое окно подтверждения и проверки.
    Рисунок 3. Приложение Chat возвращает диалоговое окно с подтверждением, чтобы пользователи могли проверить и подтвердить информацию перед отправкой.
  • Текстовое сообщение с подтверждением добавления нового контакта.
    Рисунок 4. После того как пользователь отправит форму, приложение Chat отправит ему личное текстовое сообщение с подтверждением.
  • Форма обратной связи из сообщения на карточке.
    Рисунок 5. Приложение Chat также предлагает пользователям добавить контакт из карточки в сообщении.

Требования

Цели

Архитектура

Приложение Chat создано на основе Google Apps Script (как дополнение Google Workspace, расширяющее возможности Google Chat) и реагирует на действия пользователей (onMessage, onAppCommand и нажатия кнопок, которые вызывают openInitialDialog, openConfirmationDialog и submitForm), чтобы обрабатывать запросы пользователей Chat и отвечать на них.

Ниже описано, как пользователь обычно взаимодействует с приложением Chat.

  1. Пользователь открывает прямую переписку с приложением Chat или добавляет приложение Chat в существующую чат-группу.

  2. Приложение Chat предлагает пользователю добавить контакт, создавая и отображая форму контакта в виде объекта card. Чтобы показать форму обратной связи, приложение Chat отвечает пользователям следующим образом:

    • Отвечает на @упоминания и прямые переписки (onMessage) сообщением с карточкой, содержащей форму обратной связи.
    • Отвечает на слеш-команду /addContact (onAppCommand), открывая диалоговое окно с формой обратной связи.
    • Отвечает на слеш-команду /about (onAppCommand) текстовым сообщением с кнопкой Добавить контакт, при нажатии на которую вызывается openInitialDialog и открывается диалоговое окно с формой обратной связи.
  3. Когда пользователь видит форму обратной связи, он вводит контактную информацию в следующие поля и виджеты:

    • Имя и фамилия – виджет textInput, в который можно ввести текст.
    • Дата рождения – виджет dateTimePicker, в который можно ввести только дату.
    • Тип контакта – виджет selectionInput с переключателями, позволяющий пользователям выбрать и отправить одно строковое значение (Personal или Work).
    • Кнопка Проверить и отправить: массив buttonList с виджетом button, на который нажимает пользователь, чтобы отправить введенные им значения.
  4. Приложение Google Chat вызывает openConfirmationDialog для обработки введенных пользователем значений и показывает их на карточке подтверждения.

  5. Пользователь проверяет карточку подтверждения и нажимает кнопку Отправить, чтобы вызвать submitForm и завершить ввод контактной информации.

  6. Приложение Google Chat отправит вам личное текстовое сообщение с подтверждением отправки.

Подготовка среды

В этом разделе рассказывается, как настроить проект Google Cloud для приложения Chat.

Откройте облачный проект в Google API Console

Если он ещё не открыт, откройте облачный проект, который вы хотите использовать для этого примера:

  1. В Google API Console перейдите на страницу Select a project (Выберите проект).

    Выберите облачный проект

  2. Выберите проект Google Cloud, который хотите использовать. Или нажмите Создать проект и следуйте инструкциям на экране. Если вы создадите проект Google Cloud, вам может понадобиться включить для него платежные функции.

Настройка аутентификации и авторизации

Приложения Google Chat требуют настройки экрана запроса согласия OAuth, чтобы пользователи могли авторизовать ваше приложение в приложениях Google Workspace, включая Google Chat.

В этом руководстве вы развернете приложение Chat, предназначенное только для тестирования и внутреннего использования, поэтому для экрана согласия можно использовать информацию-заполнитель. Перед публикацией приложения Chat замените все плейсхолдеры реальной информацией.

  1. В консоли API Google выберите "Меню > Платформа аутентификации Google > Брендинг".

    Перейти к брендингу

  2. Если вы уже настроили платформу Google Auth, вы можете задать следующие настройки окна запроса доступа OAuth в разделах Брендинг, Аудитория и Доступ к данным. Если вы видите сообщение Google Auth platform not configured yet (Платформа аутентификации Google ещё не настроена), нажмите Get Started (Начать):

    1. В разделе Информация о приложении в поле Название приложения введите Contact Manager.
    2. В поле Электронный адрес службы поддержки выберите свой адрес электронной почты или подходящую группу Google.
    3. Нажмите Далее.
    4. В разделе Аудитория выберите Внутренние. Если вы не можете выбрать Внутренний, выберите Внешний.
    5. Нажмите Далее.
    6. В разделе Контактная информация укажите адрес электронной почты, на который вы хотите получать уведомления об изменениях в проекте.
    7. Нажмите Далее.
    8. В разделе Завершение ознакомьтесь с правилами в отношении пользовательских данных сервисов API Google и, если вы согласны с ними, выберите Я принимаю правила в отношении пользовательских данных сервисов API Google.
    9. Нажмите Продолжить.
    10. Нажмите Создать.
    11. Если в качестве типа пользователя вы выбрали Внешний, добавьте тестовых пользователей:
      1. Нажмите Аудитория.
      2. В разделе Тестировщики нажмите Добавить пользователей.
      3. Введите свой адрес электронной почты и адреса других авторизованных тестировщиков, а затем нажмите Сохранить.

Как создать и развернуть приложение Chat

В следующем разделе вы создадите и обновите проект Apps Script с кодом приложения (Code.gs и appsscript.json) для приложения Chat.

При желании вы можете посмотреть весь проект на GitHub.

Посмотреть на GitHub

Ниже приведена информация о каждом файле.

Code.gs

Обрабатывает всю логику приложения, включая взаимодействие с пользователем (onMessage, onAppCommand, openInitialDialog, openConfirmationDialog и submitForm), а также виджеты ввода форм, которые отображаются на карточках в сообщениях и диалоговых окнах.

Посмотреть Code.gs код

apps-script/chat/contact-form-app/Code.gs
/**
 * Copyright 2025 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Responds to a message in Google Chat.
 *
 * @param {Object} event The event object from the Google Workspace add-on.
 * @return {Object} response that handles dialogs.
 */
function onMessage(event) {
  // Reply with a message that contains a button to open the initial dialog
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    text: "To add a contact, use the `ADD CONTACT` button below.",
    accessoryWidgets: [
      { buttonList: { buttons: [{
        text: "ADD CONTACT",
        onClick: { action: {
          function: "openInitialDialog",
          interaction: "OPEN_DIALOG"
        }}
      }]}}
    ]
  }}}}};
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @param {Object} event The event object from the Google Workspace add-on.
 * @return {Object} open the dialog.
 */
function openInitialDialog(event) {
  return { action: { navigations: [{ pushCard: { sections: [{ 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 }
      ]
    }},
    { buttonList: { buttons: [{
      text: "NEXT",
      onClick: { action: { function : "openConfirmationDialog" }}
    }]}}
  ]}]}}]}};
}

/**
 * Opens the second step of the dialog that lets users confirm details.
 *
 * @param {Object} event The event object from the Google Workspace add-on.
 * @return {Object} update the dialog.
 */
function openConfirmationDialog(event) {
  // Retrieve the form input values
  const name = event.commonEventObject.formInputs["contactName"].stringInputs.value[0];
  const birthdate = event.commonEventObject.formInputs["contactBirthdate"].dateInput.msSinceEpoch;
  const type = event.commonEventObject.formInputs["contactType"].stringInputs.value[0];
  // Display the input values for confirmation
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [
    { textParagraph: { text: "Confirm contact information and submit:" }},
    { textParagraph: { text: "<b>Name:</b> " + name }},
    { textParagraph: { text: "<b>Birthday:</b> " + new Date(birthdate) }},
    { textParagraph: { text: "<b>Type:</b> " + type }},
    { 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 }
        ]
      }}
    }]}}
  ]}]}}]}};
}

/**
 * Handles submission and closes the dialog.
 *
 * @param {Object} event The event object from the Google Workspace add-on.
 * @return {Object} close the dialog with a status in text notification or message.
 */
function submitDialog(event) {
  // Validate the parameters.
  if (!event.commonEventObject.parameters["contactName"]) {
    return { action: {
      navigations: [{ endNavigation: { action: "CLOSE_DIALOG"}}],
      notification: { text: "Failure, the contact name was missing!" }
    }};
  }

  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    text: "✅ " + event.commonEventObject.parameters["contactName"] + " has been added to your contacts."
  }}}}};
}
appsscript.json

Манифест Apps Script, который определяет и настраивает проект Apps Script для приложения Chat.

Посмотреть appsscript.json код

apps-script/chat/contact-form-app/appsscript.json
{
  "timeZone": "America/Los_Angeles",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "addOns": {
    "common": {
      "name": "Contact Form app",
      "logoUrl": "https://developers.google.com/workspace/add-ons/images/contact-icon.png"
    },
    "chat": {}
  }
}

Как создать проект Apps Script

Чтобы создать проект Apps Script на основе файлов Code.gs и appsscript.json:

  1. Перейдите на страницу Google Apps Script и нажмите Новый проект.
  2. Назовите проект Apps Script:

    1. Нажмите Проект без названия.

    2. В поле Название проекта введите Contact Manager - Google Chat app.

    3. Нажмите Переименовать.

  3. Замените содержимое Code.gs на образец кода Code.gs, приведенный выше.

  4. Нажмите Настройки проекта Значок настроек проекта и выберите Показывать файл манифеста appsscript.json в редакторе.

  5. Вернитесь в Редактор и замените содержимое appsscript.json кодом манифеста appsscript.json, приведенным выше. Затем сохраните проект.

В будущем, если вы захотите использовать определенные API Google или опубликовать приложение, вам нужно будет связать облачный проект с проектом Apps Script. В этом руководстве вам не нужно этого делать. Подробнее о проектах Google Cloud…

Как создать развертывание Apps Script

Теперь, когда весь код добавлен, разверните проект Apps Script. Идентификатор развертывания используется при настройке приложения Chat в Google Cloud.

  1. В Apps Script откройте проект приложения Chat.

    Перейти в Apps Script

  2. Нажмите Развернуть > Новое развертывание.

  3. Если Дополнение ещё не выбрано, рядом с пунктом Выберите тип нажмите на типы развертывания Значок настроек проекта и выберите Дополнение.

  4. В поле Описание введите описание этой версии, например: Test of Contact Manager.

  5. Нажмите Развернуть. Apps Script сообщает об успешном развертывании и предоставляет идентификатор развертывания.

  6. Нажмите Копировать, чтобы скопировать идентификатор развертывания, а затем нажмите Готово.

Как настроить приложение Chat в Google API Console

В этом разделе рассказывается, как настроить Google Chat API в Google API Console, указав информацию о приложении Chat, в том числе идентификатор развертывания, созданного в проекте Apps Script.

  1. В Google API Console нажмите Меню > API и сервисы > Включенные API и сервисы > Google Chat API > Конфигурация.

    Перейти к настройке Chat API

  2. В поле Название приложения введите Contact Manager.

  3. В поле URL аватара введите https://developers.google.com/chat/images/contact-icon.png.

  4. В поле Описание введите Manage your personal and business contacts.

  5. Переведите переключатель Включить интерактивные функции в положение "Включено".

  6. В разделе Функциональность выберите Присоединяться к чат-группам и групповым чатам.

  7. В разделе Настройки подключения выберите Скрипт приложений.

  8. В поле Идентификатор развертывания вставьте идентификатор развертывания Apps Script, который вы скопировали в предыдущем разделе при создании развертывания Apps Script.

  9. В разделе Триггеры настройте функции, которые реагируют на действия пользователя:

    • Для триггера Сообщение введите onMessage.
    • В качестве триггера Команда приложения введите onAppCommand.
  10. В разделе Команды настройте слеш-команды /about и /addContact:

    1. Нажмите Добавить команду, чтобы настроить первую слеш-команду.
    2. В поле Идентификатор команды введите 1.
    3. В поле Описание введите Learn how to use this Chat app to manage your contacts.
    4. В разделе Тип команды выберите Slash command.
    5. В поле Название слеш-команды введите /about.
    6. Нажмите Готово.
    7. Нажмите Добавить команду, чтобы настроить ещё одну слеш-команду.
    8. В поле Идентификатор команды введите 2.
    9. В поле Описание введите Submit information about a contact.
    10. В разделе Тип команды выберите Slash command.
    11. В поле Название слеш-команды введите /addContact.
    12. Выберите Открыть диалоговое окно.
    13. Нажмите Готово.
  11. В разделе Видимость установите флажок Сделать это приложение Chat доступным для определенных пользователей и групп в YOUR DOMAIN и введите свой адрес электронной почты.

  12. В разделе Журналы выберите Регистрировать ошибки в Logging.

  13. Нажмите Сохранить. Появится сообщение о том, что конфигурация сохранена.

Приложение Chat готово к установке и тестированию в Chat.

Как протестировать приложение Chat

Чтобы протестировать приложение Chat, откройте прямую переписку с ним и отправьте сообщение:

  1. Откройте Google Chat, используя аккаунт Google Workspace, который вы указали, когда добавляли себя в качестве доверенного тестировщика.

    Перейти в Google Chat

  2. Нажмите Новый чат.
  3. В поле Добавьте одного или нескольких пользователей введите название приложения Chat.
  4. Выберите приложение Chat в результатах поиска. Откроется прямая переписка.

  1. В новой прямой переписке с приложением Chat введите /addContact и нажмите Ввод.

  2. В открывшемся диалоговом окне введите контактную информацию:

    1. В текстовом поле Имя и фамилия введите имя.
    2. В окне выбора даты Дата рождения выберите дату.
    3. В разделе Тип контакта выберите переключатель Рабочий или Личный.
  3. Нажмите Проверить и отправить.

  4. В диалоговом окне подтверждения проверьте введенную информацию и нажмите Отправить. Приложение Chat ответит текстовым сообщением с текстом ✅ CONTACT NAME has been added to your contacts..

  5. Вы также можете протестировать и отправить форму обратной связи следующими способами:

    • Используйте слеш-команду /about. Приложение для обмена сообщениями отвечает текстовым сообщением и кнопкой виджета аксессуара с надписью Add a contact. Нажав на кнопку, вы откроете диалоговое окно с формой обратной связи.
    • Отправьте приложению Chat прямое сообщение без слеш-команды, например Hello. Приложение Chat ответит текстом и карточкой с формой обратной связи.

Организовать

Чтобы избежать списания средств с аккаунта Google Cloud за ресурсы, использованные в этом руководстве, рекомендуем удалить облачный проект.

  1. В Google API Console перейдите на страницу Управление ресурсами. Нажмите Меню > IAM и администрирование > Управление ресурсами.

    Перейти в Менеджер ресурсов

  2. В списке проектов выберите проект, который хотите удалить, и нажмите Удалить .
  3. В диалоговом окне введите идентификатор проекта и нажмите Закрыть, чтобы удалить проект.

Приложения для Chat, которые не являются дополнениями: управление контактами из Google Chat

Приведенные ниже инструкции и примеры кода относятся к приложению Chat, которое не является дополнением Google Workspace (посмотреть на GitHub).

Файлы Apps Script

main.gs

Обрабатывает всю логику приложения, включая события взаимодействия, когда пользователи отправляют сообщения в приложение Chat, нажимают кнопки в сообщении приложения Chat или открывают и закрывают диалоговые окна.

apps-script/contact-form-app/main.gs
/**
 * Copyright 2024 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Responds to a MESSAGE interaction event in Google Chat.
 *
 * @param {Object} event the MESSAGE interaction event from Chat API.
 * @return {Object} message response that opens a dialog or sends private
 *                          message with text and card.
 */
function onMessage(event) {
  if (event.message.slashCommand) {
    switch (event.message.slashCommand.commandId) {
      case 1:
        // If the slash command is "/about", responds with a text message and button
        // that opens a dialog.
        return {
          text: "Manage your personal and business contacts 📇. To add a " +
                  "contact, use the slash command `/addContact`.",
          accessoryWidgets: [{
            buttonList: { buttons: [{
              text: "Add Contact",
              onClick: { action: {
                function: "openInitialDialog",
                interaction: "OPEN_DIALOG"
              }}
            }]}
          }]
        }
      case 2:
        // If the slash command is "/addContact", opens a dialog.
        return openInitialDialog();
    }
  }

  // If user sends the Chat app a message without a slash command, the app responds
  // privately with a text and card to add a contact.
  return {
    privateMessageViewer: event.user,
    text: "To add a contact, try `/addContact` or complete the form below:",
    cardsV2: [{
      cardId: "addContactForm",
      card: {
        header: { title: "Add a contact" },
        sections:[{ widgets: CONTACT_FORM_WIDGETS.concat([{
          buttonList: { buttons: [{
            text: "Review and submit",
            onClick: { action: { function : "openConfirmation" }}
          }]}
        }])}]
      }
    }]
  };
}

/**
 * Responds to CARD_CLICKED interaction events in Google Chat.
 *
 * @param {Object} event the CARD_CLICKED interaction event from Google Chat.
 * @return {Object} message responses specific to the dialog handling.
 */
function onCardClick(event) {
  // Initial dialog form page
  if (event.common.invokedFunction === "openInitialDialog") {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if (event.common.invokedFunction === "openConfirmation") {
    return openConfirmation(event);
  // Submission dialog form page
  } else if (event.common.invokedFunction === "submitForm") {
    return submitForm(event);
  }
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

/**
 * Returns the second step as a dialog or card message that lets users confirm details.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} returns a dialog or private card message.
 */
function openConfirmation(event) {
  const name = fetchFormValue(event, "contactName") ?? "";
  const birthdate = fetchFormValue(event, "contactBirthdate") ?? "";
  const type = fetchFormValue(event, "contactType") ?? "";
  const cardConfirmation = {
    header: "Your contact",
    widgets: [{
      textParagraph: { text: "Confirm contact information and submit:" }}, {
      textParagraph: { text: "<b>Name:</b> " + name }}, {
      textParagraph: {
        text: "<b>Birthday:</b> " + convertMillisToDateString(birthdate)
      }}, {
      textParagraph: { text: "<b>Type:</b> " + type }}, {
      buttonList: { buttons: [{
        text: "Submit",
        onClick: { action: {
          function: "submitForm",
          parameters: [{
            key: "contactName", value: name }, {
            key: "contactBirthdate", value: birthdate }, {
            key: "contactType", value: type
          }]
        }}
      }]}
    }]
  };

  // Returns a dialog with contact information that the user input.
  if (event.isDialogEvent) {
    return { action_response: {
      type: "DIALOG",
      dialogAction: { dialog: { body: { sections: [ cardConfirmation ]}}}
    }};
  }

  // Updates existing card message with contact information that the user input.
  return {
    actionResponse: { type: "UPDATE_MESSAGE" },
    privateMessageViewer: event.user,
    cardsV2: [{
      card: { sections: [cardConfirmation]}
    }]
  }
}

/**
  * Validates and submits information from a dialog or card message
  * and notifies status.
  *
  * @param {Object} event the interactive event with parameters.
  * @return {Object} a message response that opens a dialog or posts a private
  *                  message.
  */
function submitForm(event) {
  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
      }}
    }};
  }
  if (!contactName) {
    return {
      privateMessageViewer: event.user,
      text: errorMessage
    };
  }

  // The Chat app indicates that it received form data from the dialog or card.
  // Sends private text message that confirms submission.
  const confirmationMessage = "✅ " + contactName + " has been added to your contacts.";
  if (event.dialogEventType === "SUBMIT_DIALOG") {
    return {
      actionResponse: {
        type: "DIALOG",
        dialogAction: { actionStatus: {
          statusCode: "OK",
          userFacingMessage: "Success " + contactName
        }}
      }
    };
  }
  return {
    actionResponse: { type: "NEW_MESSAGE" },
    privateMessageViewer: event.user,
    text: confirmationMessage
  };
}

/**
 * Extracts form input value for a given widget.
 *
 * @param {Object} event the CARD_CLICKED interaction event from Google Chat.
 * @param {String} widgetName a unique ID for the widget, specified in the widget's name field.
 * @returns the value inputted by the user, null if no value can be found.
 */
function fetchFormValue(event, widgetName) {
  const formItem = event.common.formInputs[widgetName][""];
  // For widgets that receive StringInputs data, the value input by the user.
  if (formItem.hasOwnProperty("stringInputs")) {
    const stringInput = event.common.formInputs[widgetName][""].stringInputs.value[0];
    if (stringInput != null) {
      return stringInput;
    }
  // For widgets that receive dateInput data, the value input by the user.
  } else if (formItem.hasOwnProperty("dateInput")) {
    const dateInput = event.common.formInputs[widgetName][""].dateInput.msSinceEpoch;
     if (dateInput != null) {
       return dateInput;
     }
  }

  return null;
}

/**
 * Converts date in milliseconds since epoch to user-friendly string.
 *
 * @param {Object} millis the milliseconds since epoch time.
 * @return {string} Display-friend date (English US).
 */
function convertMillisToDateString(millis) {
  const date = new Date(millis);
  const options = { year: 'numeric', month: 'long', day: 'numeric' };
  return date.toLocaleDateString('en-US', options);
}
contactForm.gs

Содержит виджеты, которые получают данные из форм от пользователей. Эти виджеты ввода форм отображаются на карточках, которые появляются в сообщениях и диалоговых окнах.

apps-script/contact-form-app/contactForm.gs
/**
 * Copyright 2024 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * 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
        }
      ]
    }
  }
];
appsscript.json

Манифест Apps Script, который определяет и настраивает проект Apps Script для приложения Chat, не являющегося дополнением.

apps-script/contact-form-app/appsscript.json
{
  "timeZone": "America/Los_Angeles",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "chat": {}
}

Как создать и настроить проект Apps Script

  1. Откройте проект Apps Script Управление контактами в Google Chat для приложения Chat, которое не является дополнением, и создайте его копию.
  2. При настройке Chat API в Google API Console: снимите флажок Создать это приложение Chat как дополнение Google Workspace. Откроется диалоговое окно с запросом на подтверждение. В диалоговом окне нажмите Отключить.