Реагируйте на инциденты с помощью Google Chat, Vertex AI и Apps Script.

В этом руководстве используются области авторизации, начинающиеся с https://www.googleapis.com/auth/chat.app.* , которые доступны как часть предварительной версии для разработчиков. Ваше приложение Chat должно получить единоразовое одобрение администратора .

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

Инцидент – это событие, для разрешения которого требуется немедленное внимание группы людей. Примеры инцидентов включают в себя:

  • На платформе управления взаимоотношениями с клиентами (CRM) создается срочный случай, требующий совместной работы группы обслуживания над решением.
  • Система отключается, оповещая группу инженеров по надежности объекта (SRE), чтобы они могли вместе работать над ее возобновлением.
  • Происходит землетрясение высокой магнитуды, и спасателям необходимо координировать свои действия.

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

Посмотрите приложение Chat для управления инцидентами в действии:

  • Веб-сайт, с которого начинается инцидент.
    Рисунок 1. Веб-сайт, на котором можно сообщить об инциденте.
  • Уведомление о том, что создано пространство чата по инциденту.
    Рисунок 2. Уведомление о создании пространства чата по инциденту.
  • Реагирование на инцидент Чат.
    Рисунок 3. Реагирование на инцидент. Пространство чата.
  • Разрешение инцидента с помощью косой черты.
    Рисунок 4. Разрешение инцидента с помощью команды косой черты.
  • Диалог разрешения инцидентов.
    Рисунок 5. Диалоговое окно разрешения инцидента.
  • Документ Google Docs по разрешению инцидентов опубликован в космосе.
    Рисунок 6. Документ Google Docs по разрешению инцидентов, доступный в пространстве.
  • Сводное решение инцидентов с использованием ИИ, Google Doc.
    Рисунок 7. Документ Google Docs со сводкой по разрешению инцидентов с использованием ИИ.

Предварительные условия

Если вам необходимо включить какие-либо из этих предварительных условий для вашей организации, попросите администратора Google Workspace включить их:

  • Аккаунт Google Workspace для бизнеса или предприятия с доступом к Google Chat .
  • Чтобы включить каталог (обмен контактами) для Google Workspace. Приложение для инцидентов использует каталог для поиска контактной информации лиц, отвечающих на инциденты, таких как имя и адрес электронной почты. Ответственные за инциденты должны быть пользователями с учетной записью Google Chat в вашей организации Google Workspace.

Цели

  • Создайте приложение чата, которое реагирует на инциденты.
  • Помогите пользователям реагировать на инциденты, выполнив следующие действия:
    • Создание пространств реагирования на инциденты.
    • Публикация сообщений с кратким описанием инцидентов и ответов.
    • Поддержка совместной работы с помощью функций интерактивного приложения чата.
  • Подведите итоги разговоров и принятых решений с помощью Vertex AI.

Архитектура

На следующей диаграмме показана архитектура ресурсов Google Workspace и Google Cloud, используемых приложением Google Chat для реагирования на инциденты.

Архитектура приложения Google Chat для реагирования на инциденты

Архитектура показывает, как приложение Google Chat для реагирования на инциденты обрабатывает инцидент и разрешает его.

  1. Пользователь запускает инцидент с внешнего веб-сайта, размещенного на Apps Script.

  2. Веб-сайт отправляет асинхронный HTTP-запрос в приложение Google Chat, также размещенное на Apps Script.

  3. Приложение Google Chat для реагирования на инциденты обрабатывает запрос:

    1. Служба Apps Script Admin SDK получает информацию о членах команды, например идентификатор пользователя и адрес электронной почты.

    2. С помощью набора HTTP-запросов к Chat API с использованием службы расширенного чата Apps Script приложение Google Chat для ответа на инцидент создает пространство чата для инцидентов, заполняет его членами команды и отправляет сообщение в это пространство.

  4. Члены команды обсуждают инцидент в чате.

  5. Член команды вызывает косую черту, чтобы сообщить о разрешении инцидента.

    1. HTTP-вызов API Chat с использованием расширенной службы Chat Apps Script выводит список всех сообщений пространства Chat.

    2. Vertex AI получает перечисленные сообщения и генерирует сводку.

    3. Служба Apps Script DocumentApp создает документ Docs и добавляет в него резюме Vertex AI.

    4. Приложение Google Chat для ответа на инцидент вызывает Chat API, чтобы отправить сообщение со ссылкой на сводный документ Документов.

Подготовьте окружающую среду

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

Создайте проект Google Cloud

Консоль Google Cloud

  1. В консоли Google Cloud выберите > IAM и администрирование > Создать проект .

    Перейти к созданию проекта

  2. В поле «Имя проекта» введите описательное имя вашего проекта.

    Необязательно: Чтобы изменить идентификатор проекта , нажмите «Изменить» . Идентификатор проекта нельзя изменить после его создания, поэтому выберите идентификатор, который соответствует вашим потребностям на протяжении всего срока действия проекта.

  3. В поле «Местоположение» нажмите «Обзор» , чтобы отобразить возможные местоположения для вашего проекта. Затем нажмите «Выбрать» .
  4. Нажмите Создать . Консоль Google Cloud перейдет на страницу панели инструментов, и ваш проект будет создан в течение нескольких минут.

интерфейс командной строки gcloud

В одной из следующих сред разработки получите доступ к Google Cloud CLI ( gcloud ):

  • Cloud Shell : чтобы использовать онлайн-терминал с уже настроенным интерфейсом командной строки gcloud, активируйте Cloud Shell.
    Активировать Cloud Shell
  • Локальная оболочка : чтобы использовать локальную среду разработки, установите и инициализируйте интерфейс командной строки gcloud.
    Чтобы создать облачный проект, используйте команду gcloud projects create :
    gcloud projects create PROJECT_ID
    Замените PROJECT_ID , указав идентификатор проекта, который вы хотите создать.

Включить биллинг для облачного проекта

Консоль Google Cloud

  1. В консоли Google Cloud перейдите в раздел «Оплата» . > Оплата > Мои проекты .

    Перейти к оплате за мои проекты

  2. В разделе «Выберите организацию» выберите организацию, связанную с вашим проектом Google Cloud.
  3. В строке проекта откройте меню «Действия» ( ), нажмите «Изменить биллинг» и выберите учетную запись Cloud Billing.
  4. Нажмите Установить учетную запись .

интерфейс командной строки gcloud

  1. Чтобы просмотреть список доступных платежных учетных записей, запустите:
    gcloud billing accounts list
  2. Свяжите платежный аккаунт с проектом Google Cloud:
    gcloud billing projects link PROJECT_ID --billing-account=BILLING_ACCOUNT_ID

    Замените следующее:

    • PROJECT_ID — это идентификатор облачного проекта, для которого вы хотите включить оплату.
    • BILLING_ACCOUNT_ID — это идентификатор платежного аккаунта , который нужно связать с проектом Google Cloud.

Включите API

Консоль Google Cloud

  1. В консоли Google Cloud включите Google Chat API, Google Docs API, Admin SDK API, Google Workspace Marketplace SDK и Vertex AI API.

    Включите API

  2. Убедитесь, что вы включаете API в правильном облачном проекте, затем нажмите «Далее» .

  3. Убедитесь, что вы включаете правильные API, затем нажмите « Включить» .

интерфейс командной строки gcloud

  1. При необходимости установите текущий проект Cloud на тот, который вы создали с помощью команды gcloud config set project :

    gcloud config set project PROJECT_ID

    Замените PROJECT_ID на идентификатор созданного вами облачного проекта.

  2. Включите Google Chat API, Google Docs API, Admin SDK API, Google Workspace Marketplace SDK и Vertex AI API с помощью команды gcloud services enable :

    gcloud services enable chat.googleapis.com docs.googleapis.com admin.googleapis.com aiplatform.googleapis.com appsmarket-component.googleapis.com

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

Приложение Chat обращается к API Google Chat, используя учетные данные приложения Chat. Приложение обращается к API Admin SDK и API Google Docs с учетными данными пользователя.

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

Аутентификация и авторизация позволяют приложению Chat получать доступ к ресурсам в Google Workspace и Google Cloud для обработки реагирования на инциденты. в частности, аутентификация пользователя используется для вызова API Google Docs и API Admin SDK.

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

  1. В консоли Google Cloud перейдите в Меню > > Брендинг .

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

  2. Если вы уже настроиливы можете настроить следующие параметры экрана согласия OAuth в разделах «Брендинг» , «Аудитория» и «Доступ к данным» . Если вы видите сообщение, в котором говорится еще не настроено , нажмите «Начать» :

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

    1. В разделе «Добавление областей вручную» вставьте следующие области:

      • https://www.googleapis.com/auth/documents
      • https://www.googleapis.com/auth/admin.directory.user.readonly
      • https://www.googleapis.com/auth/script.external_request
      • https://www.googleapis.com/auth/userinfo.email
      • https://www.googleapis.com/auth/cloud-platform
    2. Нажмите «Добавить в таблицу» .

    3. Нажмите Обновить .

    4. После выбора областей, необходимых вашему приложению, на странице «Доступ к данным» нажмите «Сохранить ».

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

Аутентификация приложения используется для вызова API Google Chat.

Создайте сервисную учетную запись в консоли Google Cloud.

Чтобы создать учетную запись службы, выполните следующие действия:

Консоль Google Cloud

  1. В консоли Google Cloud выберите > IAM и администрирование > Учетные записи служб .

    Перейти к учетным записям служб

  2. Нажмите Создать учетную запись службы .
  3. Заполните данные учетной записи службы, затем нажмите «Создать и продолжить» .
  4. Необязательно: назначьте роли своему сервисному аккаунту, чтобы предоставить доступ к ресурсам вашего проекта Google Cloud. Дополнительные сведения см. в разделе Предоставление, изменение и отзыв доступа к ресурсам .
  5. Нажмите Продолжить .
  6. Необязательно: укажите пользователей или группы, которые могут управлять этой учетной записью службы и выполнять действия с ней. Дополнительные сведения см. в разделе Управление олицетворением учетной записи службы .
  7. Нажмите Готово . Запишите адрес электронной почты для учетной записи службы.

интерфейс командной строки gcloud

  1. Создайте учетную запись службы:
    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name="SERVICE_ACCOUNT_NAME"
  2. Необязательно: назначьте роли своему сервисному аккаунту, чтобы предоставить доступ к ресурсам вашего проекта Google Cloud. Дополнительные сведения см. в разделе Предоставление, изменение и отзыв доступа к ресурсам .

Учетная запись службы отображается на странице учетной записи службы. Затем создайте закрытый ключ для учетной записи службы.

Создать закрытый ключ

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

  1. В консоли Google Cloud выберите > IAM и администрирование > Учетные записи служб .

    Перейти к учетным записям служб

  2. Выберите свою учетную запись службы.
  3. Нажмите «Ключи» > «Добавить ключ» > «Создать новый ключ» .
  4. Выберите JSON , затем нажмите «Создать» .

    Ваша новая пара открытого/закрытого ключей генерируется и загружается на ваш компьютер в виде нового файла. Сохраните загруженный файл JSON как credentials.json в своем рабочем каталоге. Этот файл является единственной копией этого ключа. Информацию о том, как безопасно хранить ключ, см. в разделе Управление ключами учетной записи службы .

  5. Нажмите Закрыть .

Дополнительную информацию об учетных записях служб см. в учетных записях служб в документации Google Cloud IAM.

Создайте клиент OAuth, совместимый с Google Workspace Marketplace.

Чтобы создать клиент OAuth, совместимый с Google Workspace Marketplace, выполните следующие действия:

  1. В консоли Google Cloud выберите > IAM и администрирование > Учетные записи служб .

    Перейти к учетным записям служб

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

  3. Нажмите «Дополнительные настройки» .

  4. Нажмите Создать клиент OAuth, совместимый с Google Workspace Marketplace .

  5. Нажмите Продолжить .

Появится сообщение с подтверждением о том, что клиент OAuth, совместимый с Google Workspace Marketplace, создан.

Создайте и разверните приложение чата

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

Некоторые функции включают подчеркивания в конце своих имен, например, processSlashCommand_() из ChatApp.gs . Подчеркивание скрывает функцию с веб-страницы инициализации инцидента, когда она открыта в браузере. Дополнительные сведения см. в разделе Частные функции .

Apps Script поддерживает два типа файлов: сценарии .gs и файлы .html . Чтобы обеспечить эту поддержку, клиентский JavaScript приложения включается в теги <script /> , а его CSS — в теги <style /> внутри HTML-файла.

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

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

Вот обзор каждого файла:

Consts.gs

Определяет константы, на которые ссылаются другие файлы кода, включая идентификатор вашего облачного проекта, идентификатор местоположения Vertex AI, учетные данные приложения для учетной записи службы и идентификатор команды с косой чертой для закрытия инцидента.

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

apps-script/incident-response-app-auth/Consts.gs
const PROJECT_ID = 'replace-with-your-project-id';
const CLOSE_INCIDENT_COMMAND_ID = 1;
const APP_CREDENTIALS = 'replace-with-your-app-credentials';
const APP_CREDENTIALS_SCOPES = 'https://www.googleapis.com/auth/chat.bot https://www.googleapis.com/auth/chat.app.memberships https://www.googleapis.com/auth/chat.app.spaces.create';
const VERTEX_AI_LOCATION_ID = 'us-central1';
const MODEL_ID = 'gemini-1.5-flash-002';
ChatApp.gs

Обрабатывает события взаимодействия в чате, включая сообщения, щелчки карточек, команды с косой чертой и диалоговые окна. Отвечает на косую черту /closeIncident , открывая диалоговое окно для сбора сведений о разрешении инцидента. Читает сообщения в чат-группе, вызывая метод spaces.messages.list в Chat API. Получает идентификаторы пользователей с помощью службы каталогов Admin SDK в Apps Script.

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

apps-script/incident-response-app-auth/ChatApp.gs
/**
 * Responds to a MESSAGE event in Google Chat.
 *
 * This app only responds to a slash command with the ID 1 ("/closeIncident").
 * It will respond to any other message with a simple "Hello" text message.
 *
 * @param {Object} event the event object from Google Chat
 */
function onMessage(event) {
  if (event.message.slashCommand) {
    return processSlashCommand_(event);
  }
  return { "text": "Hello from Incident Response app!" };
}

/**
 * Responds to a CARD_CLICKED event in Google Chat.
 *
 * This app only responds to one kind of dialog (Close Incident).
 *
 * @param {Object} event the event object from Google Chat
 */
function onCardClick(event) {
  if (event.isDialogEvent) {
    if (event.dialogEventType == 'SUBMIT_DIALOG') {
      return processSubmitDialog_(event);
    }
    return {
      actionResponse: {
        type: "DIALOG",
        dialogAction: {
          actionStatus: "OK"
        }
      }
    };
  }
}

/**
 * Responds to a MESSAGE event with a Slash command in Google Chat.
 *
 * This app only responds to a slash command with the ID 1 ("/closeIncident")
 * by returning a Dialog.
 *
 * @param {Object} event the event object from Google Chat
 */
function processSlashCommand_(event) {
  if (event.message.slashCommand.commandId != CLOSE_INCIDENT_COMMAND_ID) {
    return {
      "text": "Command not recognized. Use the command `/closeIncident` to close the incident managed by this space."
    };
  }
  const sections = [
    {
      header: "Close Incident",
      widgets: [
        {
          textInput: {
            label: "Please describe the incident resolution",
            type: "MULTIPLE_LINE",
            name: "description"
          }
        },
        {
          buttonList: {
            buttons: [
              {
                text: "Close Incident",
                onClick: {
                  action: {
                    function: "closeIncident"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  ];
  return {
    actionResponse: {
      type: "DIALOG",
      dialogAction: {
        dialog: {
          body: {
            sections,
          }
        }
      }
    }
  };
}

/**
 * Responds to a CARD_CLICKED event with a Dialog submission in Google Chat.
 *
 * This app only responds to one kind of dialog (Close Incident).
 * It creates a Doc with a summary of the incident information and posts a message
 * to the space with a link to the Doc.
 *
 * @param {Object} event the event object from Google Chat
 */
function processSubmitDialog_(event) {
  const resolution = event.common.formInputs.description[""].stringInputs.value[0];
  const chatHistory = concatenateAllSpaceMessages_(event.space.name);
  const chatSummary = summarizeChatHistory_(chatHistory);
  const docUrl = createDoc_(event.space.displayName, resolution, chatHistory, chatSummary);
  return {
    actionResponse: {
      type: "NEW_MESSAGE",
    },
    text: `Incident closed with the following resolution: ${resolution}\n\nHere is the automatically generated post-mortem:\n${docUrl}`
  };
}

/**
 * Lists all the messages in the Chat space, then concatenate all of them into
 * a single text containing the full Chat history.
 *
 * For simplicity for this demo, it only fetches the first 100 messages.
 *
 * Messages with slash commands are filtered out, so the returned history will
 * contain only the conversations between users and not app command invocations.
 *
 * @return {string} a text containing all the messages in the space in the format:
 *          Sender's name: Message
 */
function concatenateAllSpaceMessages_(spaceName) {
  // Call Chat API method spaces.messages.list
  const response = Chat.Spaces.Messages.list(spaceName, { 'pageSize': 100 });
  const messages = response.messages;
  // Fetch the display names of the message senders and returns a text
  // concatenating all the messages.
  let userMap = new Map();
  return messages
    .filter(message => message.slashCommand === undefined)
    .map(message => `${getUserDisplayName_(userMap, message.sender.name)}: ${message.text}`)
    .join('\n');
}

/**
 * Obtains the display name of a user by using the Admin Directory API.
 *
 * The fetched display name is cached in the provided map, so we only call the API
 * once per user.
 *
 * If the user does not have a display name, then the full name is used.
 *
 * @param {Map} userMap a map containing the display names previously fetched
 * @param {string} userName the resource name of the user
 * @return {string} the user's display name
 */
function getUserDisplayName_(userMap, userName) {
  if (userMap.has(userName)) {
    return userMap.get(userName);
  }
  let displayName = 'Unknown User';
  try {
    const user = AdminDirectory.Users.get(
      userName.replace("users/", ""),
      { projection: 'BASIC', viewType: 'domain_public' });
    displayName = user.name.displayName ? user.name.displayName : user.name.fullName;
  } catch (e) {
    // Ignore error if the API call fails (for example, because it's an
    // out-of-domain user or Chat app)) and just use 'Unknown User'.
  }
  userMap.set(userName, displayName);
  return displayName;
}
ChatSpaceCreator.gs

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

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

apps-script/incident-response-app-auth/ChatSpaceCreator.gs
/**
 * Handles an incident by creating a chat space, adding members, and posting a message.
 * All the actions are done using application credentials.
 *
 * @param {Object} formData - The data submitted by the user. It should contain the fields:
 *                           - title: The display name of the chat space.
 *                           - description: The description of the incident.
 *                           - users: A comma-separated string of user emails to be added to the space.
 * @return {string} The resource name of the new space.
 */
function handleIncident(formData) {
  const users = formData.users.trim().length > 0 ? formData.users.split(',') : [];
  const service = getService_();
  if (!service.hasAccess()) {
    console.error(service.getLastError());
    return;
   }
  const spaceName = createChatSpace_(formData.title, service);
  createHumanMembership_(spaceName, getUserEmail(), service);
  for (const user of users ){
    createHumanMembership_(spaceName, user, service);
  }
  createMessage_(spaceName, formData.description, service);
  return spaceName;
}
/**
 * Creates a chat space with application credentials.
 *
 * @param {string} displayName - The name of the chat space.
 * @param {object} service - The credentials of the service account.
 * @returns {string} The resource name of the new space.
*/
function createChatSpace_(displayName, service) {
  try {
    // For private apps, the alias can be used
    const my_customer_alias = "customers/my_customer";
    // Specify the space to create.
    const space = {
        displayName: displayName,
        spaceType: 'SPACE',                
        customer: my_customer_alias
    };
    // Call Chat API with a service account to create a message.
    const createdSpace = Chat.Spaces.create(
        space,
        {},
        // Authenticate with the service account token.
        {'Authorization': 'Bearer ' + service.getAccessToken()});
    return createdSpace.name;
  } catch (err) {
    // TODO (developer) - Handle exception.
    console.log('Failed to create space with error %s', err.message);
  }
}
/*
 * Creates a chat message with application credentials.
 *
 * @param {string} spaceName - The resource name of the space.
 * @param {string} message - The text to be posted.
 * @param {object} service - The credentials of the service account.
 * @return {string} the resource name of the new space.
 */
function createMessage_(spaceName, message, service) {
  try {
    // Call Chat API with a service account to create a message.
    const result = Chat.Spaces.Messages.create(
        {'text': message},
        spaceName,
        {},
        // Authenticate with the service account token.
        {'Authorization': 'Bearer ' + service.getAccessToken()});

  } catch (err) {
    // TODO (developer) - Handle exception.
    console.log('Failed to create message with error %s', err.message);
  }
}
/**
 * Creates a human membership in a chat space with application credentials.
 *
 * @param {string} spaceName - The resource name of the space.
 * @param {string} email - The email of the user to be added.
 * @param {object} service - The credentials of the service account.
 */
function createHumanMembership_(spaceName, email, service){
  try{
    const membership = {
      member: {
        name: 'users/'+email,
        // User type for the membership
        type: 'HUMAN'
      }
    };
    const result = Chat.Spaces.Members.create(
      membership,
      spaceName,
      {},
      {'Authorization': 'Bearer ' + service.getAccessToken()}
    );
  } catch (err){
    console.log('Failed to create membership with error %s', err.message)
  }

}

 /*
 * Creates a service for the service account.
 * @return {object}  - The credentials of the service account.
 */
function getService_() {
  return OAuth2.createService(APP_CREDENTIALS.client_email)
      .setTokenUrl('https://oauth2.googleapis.com/token')
      .setPrivateKey(APP_CREDENTIALS.private_key)
      .setIssuer(APP_CREDENTIALS.client_email)
      .setSubject(APP_CREDENTIALS.client_email)
      .setScope(APP_CREDENTIALS_SCOPES)
      .setPropertyStore(PropertiesService.getScriptProperties());
}
DocsApi.gs

Вызывает API Документов Google для создания документа Документов Google на Google Диске пользователя и записывает в документ сводку информации об инциденте, созданную в VertexAiApi.gs .

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

apps-script/incident-response-app-auth/DocsApi.gs
/**
 * Creates a Doc in the user's Google Drive and writes a summary of the incident information to it.
 *
 * @param {string} title The title of the incident
 * @param {string} resolution Incident resolution described by the user
 * @param {string} chatHistory The whole Chat history be included in the document
 * @param {string} chatSummary A summary of the Chat conversation to be included in the document
 * @return {string} the URL of the created Doc
 */
function createDoc_(title, resolution, chatHistory, chatSummary) {
  let doc = DocumentApp.create(title);
  let body = doc.getBody();
  body.appendParagraph(`Post-Mortem: ${title}`).setHeading(DocumentApp.ParagraphHeading.TITLE);
  body.appendParagraph("Resolution").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(resolution);
  body.appendParagraph("Summary of the conversation").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(chatSummary);
  body.appendParagraph("Full Chat history").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(chatHistory);
  return doc.getUrl();
}
VertexAiApi.gs

Обобщает разговор в чате с помощью Vertex AI API. Это резюме публикуется в специально созданном документе в DocsAPI.gs .

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

apps-script/incident-response-app-auth/VertexAiApi.gs
/**
 * Summarizes a Chat conversation using the Vertex AI text prediction API.
 *
 * @param {string} chatHistory The Chat history that will be summarized.
 * @return {string} The content from the text prediction response.
 */


function summarizeChatHistory_(chatHistory) {

  const API_ENDPOINT = `https://${VERTEX_AI_LOCATION_ID}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${VERTEX_AI_LOCATION_ID}/publishers/google/models/${MODEL_ID}:generateContent`;
  const prompt = "Summarize the following conversation between Engineers resolving an incident"
      + " in a few sentences. Use only the information from the conversation.\n\n" + chatHistory;
  // Get the access token.
  const accessToken = ScriptApp.getOAuthToken();

  const headers = {
    'Authorization': 'Bearer ' + accessToken,
    'Content-Type': 'application/json',
  };
  const payload = {
    'contents': {
      'role': 'user',
      'parts' : [
        {
          'text': prompt
        }
      ]
    }
  }
  const options = {
    'method': 'post',
    'headers': headers,
    'payload': JSON.stringify(payload),
    'muteHttpExceptions': true,
  };
  try {
    const response = UrlFetchApp.fetch(API_ENDPOINT, options);
    const responseCode = response.getResponseCode();
    const responseText = response.getContentText();

    if (responseCode === 200) {
      const jsonResponse = JSON.parse(responseText);
      console.log(jsonResponse)
      if (jsonResponse.candidates && jsonResponse.candidates.length > 0) {
        return jsonResponse.candidates[0].content.parts[0].text; // Access the summarized text
      } else {
        return "No summary found in response.";
      }

    } else {
      console.error("Vertex AI API Error:", responseCode, responseText);
      return `Error: ${responseCode} - ${responseText}`;
    }
  } catch (e) {
    console.error("UrlFetchApp Error:", e);
    return "Error: " + e.toString();
  }
}
WebController.gs

Обслуживает веб-сайт инициализации инцидентов.

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

apps-script/incident-response-app-auth/WebController.gs
/**
 * Serves the web page from Index.html.
 */
function doGet() {
  return HtmlService
    .createTemplateFromFile('Index')
    .evaluate();
}

/**
 * Serves the web content from the specified filename.
 */
function include(filename) {
  return HtmlService
    .createHtmlOutputFromFile(filename)
    .getContent();
}

/**
 * Returns the email address of the user running the script.
 */
function getUserEmail() {
  return Session.getActiveUser().getEmail();
}
Index.html

HTML-код, содержащий веб-сайт инициализации инцидента.

Посмотреть код Index.html

apps-script/incident-response-app-auth/Index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
    <?!= include('Stylesheet'); ?>
  </head>
  <body>
    <div class="container">
      <div class="content">
        <h1>Incident Manager</h1>
        <form id="incident-form" onsubmit="handleFormSubmit(this)">
          <div id="form">
            <p>
              <label for="title">Incident title</label><br/>
              <input type="text" name="title" id="title" />
            </p>
            <p>
              <label for="users">Incident responders</label><br/>
              <small>
                Please enter a comma-separated list of email addresses of the users
                that should be added to the space.
                Do not include <?= getUserEmail() ?> as it will be added automatically.
              </small><br/>
              <input type="text" name="users" id="users" />
            </p>
            <p>
              <label for="description">Initial message</label></br>
              <small>This message will be posted after the space is created.</small><br/>
              <textarea name="description" id="description"></textarea>
            </p>
            <p class="text-center">
              <input type="submit" value="CREATE CHAT SPACE" />
            </p>
          </div>
          <div id="output" class="hidden"></div>
          <div id="clear" class="hidden">
            <input type="reset" value="CREATE ANOTHER INCIDENT" onclick="onReset()" />
          </div>
        </form>
      </div>
    </div>
    <?!= include('JavaScript'); ?>
  </body>
</html>
JavaScript.html

Обрабатывает поведение формы, включая отправку, ошибки и очистку, для веб-сайта инициализации инцидентов. Он включается в Index.html с помощью специальной функции include в WebController.gs .

Посмотреть код JavaScript.html

apps-script/incident-response-app-auth/JavaScript.html
<script>
  var formDiv = document.getElementById('form');
  var outputDiv = document.getElementById('output');
  var clearDiv = document.getElementById('clear');

  function handleFormSubmit(formObject) {
    event.preventDefault();
    outputDiv.innerHTML = 'Please wait while we create the space...';
    hide(formDiv);
    show(outputDiv);
    google.script.run
      .withSuccessHandler(updateOutput)
      .withFailureHandler(onFailure)
      .handleIncident(formObject);
  }

  function updateOutput(response) {
    var spaceId = response.replace('spaces/', '');
    outputDiv.innerHTML =
      '<p>Space created!</p><p><a href="https://mail.google.com/chat/#chat/space/'
        + spaceId
        + '" target="_blank">Open space</a></p>';
    show(outputDiv);
    show(clearDiv);
  }

  function onFailure(error) {
    outputDiv.innerHTML = 'ERROR: ' + error.message;
    outputDiv.classList.add('error');
    show(outputDiv);
    show(clearDiv);
  }

  function onReset() {
    outputDiv.innerHTML = '';
    outputDiv.classList.remove('error');
    show(formDiv);
    hide(outputDiv);
    hide(clearDiv);
  }

  function hide(element) {
    element.classList.add('hidden');
  }

  function show(element) {
    element.classList.remove('hidden');
  }
</script>
Stylesheet.html

CSS для веб-сайта инициализации инцидента. Он включается в Index.html с помощью специальной функции include в WebController.gs .

Посмотреть код Stylesheet.html

apps-script/incident-response-app-auth/Stylesheet.html
<style>
  * {
    box-sizing: border-box;
  }
  body {
    font-family: Roboto, Arial, Helvetica, sans-serif;
  }
  div.container {
    display: flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
  }
  div.content {
    width: 80%;
    max-width: 1000px;
    padding: 1rem;
    border: 1px solid #999;
    border-radius: 0.25rem;
    box-shadow: 0 2px 2px 0 rgba(66, 66, 66, 0.08), 0 2px 4px 2px rgba(66, 66, 66, 0.16);
  }
  h1 {
    text-align: center;
    padding-bottom: 1rem;
    margin: 0 -1rem 1rem -1rem;
    border-bottom: 1px solid #999;
  }
 #output {
    text-align: center;
    min-height: 250px;
  }
  div#clear {
    text-align: center;
    padding-top: 1rem;
    margin: 1rem -1rem 0 -1rem;
    border-top: 1px solid #999;
  }
  input[type=text], textarea {
    width: 100%;
    padding: 1rem 0.5rem;
    margin: 0.5rem 0;
    border: 0;
    border-bottom: 1px solid #999;
    background-color: #f0f0f0;
  }
  textarea {
    height: 5rem;
  }
  small {
    color: #999;
  }
  input[type=submit], input[type=reset] {
    padding: 1rem;
    border: none;
    background-color: #6200ee;
    color: #fff;
    border-radius: 0.25rem;
    width: 25%;
  }
  .hidden {
    display: none;
  }
  .text-center {
    text-align: center;
  }
  .error {
    color: red;
  }
</style>

Найдите номер и идентификатор своего облачного проекта

  1. В консоли Google Cloud перейдите к своему облачному проекту.

    Перейдите в консоль Google Cloud.

  2. Нажмите «Настройки и утилиты» > «Настройки проекта» .

  3. Обратите внимание на значения в полях Номер проекта и Идентификатор проекта . Вы будете использовать их в следующих разделах.

Создайте проект скрипта приложений.

Чтобы создать проект Apps Script и связать его с проектом Cloud:

  1. Нажмите следующую кнопку, чтобы открыть проект « Реагировать на инциденты с помощью сценария приложений Google Chat» .
    Открыть проект
  2. Нажмите Обзор .
  3. На странице обзора нажмите Значок для создания копии Сделайте копию .
  4. Назовите свою копию проекта Apps Script:

    1. Нажмите «Копия ответа на инциденты в Google Chat» .

    2. В названии проекта введите Incident Management Chat app .

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

  5. В своей копии проекта Apps Script перейдите в файл Consts.gs и замените YOUR_PROJECT_ID на идентификатор вашего облачного проекта.

Установите облачный проект проекта Apps Script.

  1. В проекте Apps Script нажмите Значок настроек проекта Настройки проекта .
  2. В разделе «Проект Google Cloud Platform (GCP)» нажмите «Изменить проект» .
  3. В поле «Номер проекта GCP» вставьте номер вашего облачного проекта.
  4. Нажмите Установить проект . Проект Cloud и проект Apps Script теперь связаны.

Создание развертывания скрипта приложений

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

  1. В Apps Script откройте проект приложения реагирования на инциденты.

    Перейти к скрипту приложений

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

  3. Если надстройка и веб-приложение еще не выбраны, рядом с пунктом «Выбрать тип» щелкните «Типы развертывания». Значок настроек проекта и выберите Надстройка и веб-приложение .

  4. В поле «Описание» введите описание этой версии, например Complete version of incident management app .

  5. В разделе «Выполнить от имени» выберите «Пользователь, имеющий доступ к веб-приложению».

  6. В разделе «У кого есть доступ » выберите «Любой в вашей организации Workspace» , где «ваша организация Workspace» — это название вашей организации Google Workspace.

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

  8. Запишите URL-адрес веб-приложения , чтобы посетить его позже, когда начнете инцидент. Скопируйте идентификатор развертывания . Вы используете этот идентификатор при настройке приложения Chat в консоли Google Cloud.

  9. Нажмите Готово .

Настройте приложение Chat в консоли Google Cloud.

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

  1. В консоли Google Cloud нажмите Меню Другие продукты > Google Workspace > Библиотека продуктов > Google Chat API > Управление > Конфигурация .

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

  2. В поле «Имя приложения» введите Incident Management .

  3. В URL-адресе аватара введите https://developers.google.com/chat/images/quickstart-app-avatar.png .

  4. В поле «Описание» введите Responds to incidents. .

  5. Установите переключатель «Включить интерактивные функции» во включенное положение.

  6. В разделе «Функциональность» выберите «Получать сообщения 1:1» , «Присоединяйтесь к группам и групповым беседам» .

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

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

  9. Зарегистрируйте косую черту , которую использует полностью реализованное приложение Chat:

    1. В разделе «Команды» нажмите «Добавить команду» .

    2. В поле «Идентификатор команды» введите 1 .

    3. В поле «Описание» введите Closes the incident being discussed in the space.

    4. В разделе «Тип команды» выберите «Слэш-команда» .

    5. В имени команды Slash введите /closeIncident .

    6. Выбрать Открывает диалоговое окно .

    7. Нажмите Готово . Команда косой черты зарегистрирована и внесена в список.

  10. В разделе «Видимость» выберите «Сделать это приложение чата доступным для определенных людей и групп в вашем домене рабочей области» и введите свой адрес электронной почты.

  11. В разделе «Журналы» выберите «Записывать ошибки в журнал» .

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

Получить одобрение администратора

Чтобы получить одобрение администратора, вам необходимо настроить приложение Chat в SDK Google Workspace Marketplace.

Настройте приложение Chat в SDK Google Workspace Marketplace.

Чтобы настроить приложение Chat в SDK Google Workspace Marketplace, выполните следующие действия:

  1. В консоли Google Cloud выберите Меню API и службы > Включенные API и службы > Google Workspace Marketplace SDK > Конфигурация приложения .

    Зайдите в конфигурацию приложения

  2. Заполните страницу конфигурации приложения. Способ настройки приложения чата зависит от целевой аудитории и других факторов. Информацию о заполнении страницы конфигурации приложения см. в разделе Настройка приложения в SDK Google Workspace Marketplace . Для целей данного руководства введите следующую информацию:

    1. В разделе «Видимость приложения» выберите «Частное» .
    2. В разделе «Параметры установки» выберите «Установка с правами администратора» .
    3. В разделе «Интеграция приложений» выберите «Приложение чата» .
    4. В разделе «Области OAuth» введите следующие области:
      • https://www.googleapis.com/auth/chat.app.spaces
      • https://www.googleapis.com/auth/chat.app.memberships
    5. В разделе «Информация о разработчике» введите свое имя разработчика , URL-адрес веб-сайта разработчика и адрес электронной почты разработчика .
    6. Нажмите Сохранить черновик .

После настройки приложения обновите список магазинов:

  1. В консоли Google Cloud выберите Меню > API и службы > Включенные API и службы > Google Workspace Marketplace SDK > Список магазинов .
  2. В разделе «Сведения о приложении» выберите «Веб-разработка» в качестве категории.
  3. В графических ресурсах загрузите значки приложений в запрошенных форматах.
  4. В разделе «Скриншоты» загрузите скриншот приложения.
  5. В разделе «Ссылки на поддержку» укажите URL-адрес условий обслуживания, URL-адрес конфиденциальности и URL-адрес поддержки.
  6. В разделе «Распространение» выберите регионы, в которых это приложение будет доступно.
  7. Нажмите «Опубликовать» .

Получить одобрение администратора

Теперь, когда ваш сервисный аккаунт настроен на получение одобрения администратора, получите его у администратора Google Workspace, который сможет предоставить одобрение, выполнив действия, описанные в разделе Настройка авторизации для приложений чата .

Протестируйте приложение Чат

Чтобы протестировать приложение Chat для управления инцидентами, инициируйте инцидент с веб-страницы и убедитесь, что приложение Chat работает должным образом:

  1. Перейдите по URL-адресу веб-приложения для развертывания Apps Script.

  2. Когда Apps Script запросит разрешение на доступ к вашим данным, нажмите «Просмотреть разрешения» , войдите в систему с помощью соответствующей учетной записи Google в своем домене Google Workspace и нажмите «Разрешить» .

  3. Откроется веб-страница инициализации инцидента. Введите информацию о тесте:

    1. В заголовке «Инцидент» введите The First Incident .
    2. При необходимости в разделе «Ответчики на инциденты» введите адреса электронной почты ваших коллег, отвечающих на инциденты. Это должны быть пользователи с учетной записью Google Chat в вашей организации Google Workspace, иначе создать пространство не удастся. Не вводите свой собственный адрес электронной почты, поскольку он добавляется автоматически.
    3. В поле «Первое сообщение» введите Testing the incident management Chat app.
  4. Нажмите Создать пространство для чата . Появится сообщение creating space .

  5. После того, как пространство создано, Space created! появится сообщение. Нажмите «Открыть пространство» , чтобы открыть пространство в чате на новой вкладке.

  6. При желании вы и другие специалисты по реагированию на инциденты можете отправлять сообщения в это пространство. Приложение обобщает эти сообщения с помощью Vertex AI и публикует ретроспективный документ.

  7. Чтобы завершить реагирование на инцидент и начать процесс разрешения, в области чата введите /closeIncident . Откроется диалоговое окно управления инцидентами.

  8. В поле «Закрыть инцидент» введите описание разрешения инцидента, например Test complete .

  9. Нажмите «Закрыть инцидент» .

Приложение «Управление инцидентами» перечисляет сообщения в пространстве, суммирует их с помощью Vertex AI, вставляет сводку в документ Google Docs и публикует документ в пространстве.

Очистить

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

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

    Зайдите в диспетчер ресурсов

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

В этом руководстве используются области авторизации, начинающиеся с https://www.googleapis.com/auth/chat.app.* , которые доступны как часть предварительной версии для разработчиков. Ваше приложение Chat должно получить единоразовое одобрение администратора .

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

Инцидент – это событие, для разрешения которого требуется немедленное внимание группы людей. Примеры инцидентов включают в себя:

  • На платформе управления взаимоотношениями с клиентами (CRM) создается срочный случай, требующий совместной работы группы обслуживания над решением.
  • Система отключается, оповещая группу инженеров по надежности объекта (SRE), чтобы они могли вместе работать над ее возобновлением.
  • Происходит землетрясение высокой магнитуды, и спасателям необходимо координировать свои действия.

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

Посмотрите приложение Chat для управления инцидентами в действии:

  • Веб-сайт, с которого начинается инцидент.
    Рисунок 1. Веб-сайт, на котором можно сообщить об инциденте.
  • Уведомление о том, что создано пространство чата по инциденту.
    Рисунок 2. Уведомление о создании пространства чата по инциденту.
  • Реагирование на инцидент Чат.
    Рисунок 3. Реагирование на инцидент. Пространство чата.
  • Разрешение инцидента с помощью косой черты.
    Рисунок 4. Разрешение инцидента с помощью команды косой черты.
  • Диалог разрешения инцидентов.
    Рисунок 5. Диалоговое окно разрешения инцидента.
  • Документ Google Docs по разрешению инцидентов опубликован в космосе.
    Рисунок 6. Документ Google Docs по разрешению инцидентов, доступный в пространстве.
  • Сводное решение инцидентов с использованием ИИ, Google Doc.
    Рисунок 7. Документ Google Docs со сводкой по разрешению инцидентов с использованием ИИ.

Предварительные условия

Если вам необходимо включить какие-либо из этих предварительных условий для вашей организации, попросите администратора Google Workspace включить их:

  • Аккаунт Google Workspace для бизнеса или предприятия с доступом к Google Chat .
  • Чтобы включить каталог (обмен контактами) для Google Workspace. Приложение для инцидентов использует каталог для поиска контактной информации лиц, отвечающих на инциденты, таких как имя и адрес электронной почты. Ответственные за инциденты должны быть пользователями с учетной записью Google Chat в вашей организации Google Workspace.

Цели

  • Создайте приложение чата, которое реагирует на инциденты.
  • Помогите пользователям реагировать на инциденты, выполнив следующие действия:
    • Создание пространств реагирования на инциденты.
    • Публикация сообщений с кратким описанием инцидентов и ответов.
    • Поддержка совместной работы с помощью функций интерактивного приложения чата.
  • Подведите итоги разговоров и принятых решений с помощью Vertex AI.

Архитектура

На следующей диаграмме показана архитектура ресурсов Google Workspace и Google Cloud, используемых приложением Google Chat для реагирования на инциденты.

Архитектура приложения Google Chat для реагирования на инциденты

Архитектура показывает, как приложение Google Chat для реагирования на инциденты обрабатывает инцидент и разрешает его.

  1. Пользователь запускает инцидент с внешнего веб-сайта, размещенного на Apps Script.

  2. Веб-сайт отправляет асинхронный HTTP-запрос в приложение Google Chat, также размещенное на Apps Script.

  3. Приложение Google Chat для реагирования на инциденты обрабатывает запрос:

    1. Служба Apps Script Admin SDK получает информацию о членах команды, например идентификатор пользователя и адрес электронной почты.

    2. С помощью набора HTTP-запросов к Chat API с использованием службы расширенного чата Apps Script приложение Google Chat для ответа на инцидент создает пространство чата для инцидентов, заполняет его членами команды и отправляет сообщение в это пространство.

  4. Члены команды обсуждают инцидент в чате.

  5. Член команды вызывает косую черту, чтобы сообщить о разрешении инцидента.

    1. HTTP-вызов API Chat с использованием расширенной службы Chat Apps Script выводит список всех сообщений пространства Chat.

    2. Vertex AI получает перечисленные сообщения и генерирует сводку.

    3. Служба Apps Script DocumentApp создает документ Docs и добавляет в него резюме Vertex AI.

    4. Приложение Google Chat для ответа на инцидент вызывает Chat API, чтобы отправить сообщение со ссылкой на сводный документ Документов.

Подготовьте окружающую среду

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

Создайте проект Google Cloud

Консоль Google Cloud

  1. В консоли Google Cloud выберите > IAM и администрирование > Создать проект .

    Перейти к созданию проекта

  2. В поле «Имя проекта» введите описательное имя вашего проекта.

    Необязательно: Чтобы изменить идентификатор проекта , нажмите «Изменить» . Идентификатор проекта нельзя изменить после его создания, поэтому выберите идентификатор, который соответствует вашим потребностям на протяжении всего срока действия проекта.

  3. В поле «Местоположение» нажмите «Обзор» , чтобы отобразить возможные местоположения для вашего проекта. Затем нажмите «Выбрать» .
  4. Нажмите Создать . Консоль Google Cloud перейдет на страницу панели инструментов, и ваш проект будет создан в течение нескольких минут.

интерфейс командной строки gcloud

В одной из следующих сред разработки получите доступ к Google Cloud CLI ( gcloud ):

  • Cloud Shell : чтобы использовать онлайн-терминал с уже настроенным интерфейсом командной строки gcloud, активируйте Cloud Shell.
    Активировать Cloud Shell
  • Локальная оболочка : чтобы использовать локальную среду разработки, установите и инициализируйте интерфейс командной строки gcloud.
    Чтобы создать облачный проект, используйте команду gcloud projects create :
    gcloud projects create PROJECT_ID
    Замените PROJECT_ID , установив идентификатор для проекта, который вы хотите создать.

Включить биллинг для облачного проекта

Google Cloud Console

  1. В консоли Cloud Google отправляйтесь на биллинг . Нажмите «Меню > «Биллинг» > «Мои проекты» .

    Пойдите на выставление счетов за мои проекты

  2. В избранной организации выберите организацию, связанную с вашим Google Cloud Project.
  3. В строке проекта откройте меню Actions ( ), нажмите «Изменить Биллинг» и выберите учетную запись Cloud Billing.
  4. Нажмите «Установить учетную запись» .

Gcloud Cli

  1. Чтобы перечислить доступные счеты счетов, запустите:
    gcloud billing accounts list
  2. Свяжите биллинговую учетную запись с помощью Google Cloud Project:
    gcloud billing projects link PROJECT_ID --billing-account=BILLING_ACCOUNT_ID

    Замените следующее:

    • PROJECT_ID - это идентификатор проекта для облачного проекта, для которого вы хотите включить выставление счетов.
    • BILLING_ACCOUNT_ID - это идентификатор биллинговой учетной записи для ссылки с Google Cloud Project.

Включить API

Google Cloud Console

  1. В Cloud Console Google включите API Google Chat, API Google Docs, Admin SDK API, Google Workspace SDK и API Vertex AI.

    Включить API

  2. Убедитесь, что вы включите API в правильном облачном проекте, затем нажмите Далее .

  3. Убедитесь, что вы включите правильные API, затем нажмите « Включить» .

Gcloud Cli

  1. При необходимости установите текущий облачный проект на тот, который вы создали с помощью команды gcloud config set project :

    gcloud config set project PROJECT_ID

    Замените PROJECT_ID на идентификатор проекта созданного вами облачного проекта.

  2. Включите API Google Chat API, Google Docs API, Admin SDK API, Google Workspace Marketplace SDK и API Vertex API с gcloud services enable :

    gcloud services enable chat.googleapis.com docs.googleapis.com admin.googleapis.com aiplatform.googleapis.com appsmarket-component.googleapis.com

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

Приложение Chat обращается к Google Chat API, используя учетные данные приложения Chat. Приложение получает доступ к API API Admin SDK и Google DOCS с учетными данными пользователя.

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

Аутентификация и авторизация позволяют ресурсам доступа к приложению в чате в Google Workspace и Google Cloud обрабатывать ответ инцидента. В частности, аутентификация пользователя используется для вызова API Google Docs и ADM SDK API.

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

  1. В консоли Cloud Google перейдите в меню > > Брендинг .

    Пойти на брендинг

  2. Если вы уже настроили, вы можете настроить следующие настройки экрана согласия OAuth в брендинге , аудитории и доступе к данным . Если вы видите сообщение, в котором говорится Еще не настроен , нажмите «Начни» :

    1. В разделе «Информация о приложении» , в названии приложения , тип Incident Management .
    2. В электронной почте пользователя выберите свой адрес электронной почты или подходящую группу Google.
    3. Нажмите Далее .
    4. Под аудиторией выберите внутренний . Если вы не можете выбрать Internal , выберите внешний .
    5. Нажмите Далее .
    6. В соответствии с контактной информацией введите адрес электронной почты , где вы можете быть уведомлены о любых изменениях в вашем проекте.
    7. Нажмите Далее .
    8. В соответствии с финишем просмотрите политику пользовательских данных Google API Services , и если вы согласны, выберите «Я согласен с службами Google API: Политика пользовательских данных» .
    9. Нажмите «Продолжить» .
    10. Нажмите «Создать» .
    11. Если вы выбрали внешний для типа пользователя, добавьте тестовые пользователи:
      1. Нажмите на аудиторию .
      2. Под тестируемыми пользователями нажмите «Добавить пользователей» .
      3. Введите свой адрес электронной почты и любых других авторизованных тестовых пользователей, затем нажмите « Сохранить» .
  3. Нажмите Доступ к данным > Добавить или удалить области . Панель появляется со списком областей применения для каждого API, который вы включили в своем Google Cloud Project.

    1. Под вручную добавить область , вставьте следующие прицелы:

      • https://www.googleapis.com/auth/documents
      • https://www.googleapis.com/auth/admin.directory.user.readonly
      • https://www.googleapis.com/auth/script.external_request
      • https://www.googleapis.com/auth/userinfo.email
      • https://www.googleapis.com/auth/cloud-platform
    2. Нажмите «Добавить в таблицу» .

    3. Нажмите обновление .

    4. После выбора областей, требуемых вашим приложением, на странице доступа к данным нажмите «Сохранить» .

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

Аутентификация приложения используется для вызова API Google Chat.

Создать учетную запись службы в Cloud Console Google

Чтобы создать учетную запись службы, выполните следующие действия:

Google Cloud Console

  1. В Cloud Console Google перейдите в меню > IAM & Admin > Сервисные учетные записи .

    Перейти к счетам обслуживания

  2. Нажмите «Создать учетную запись службы» .
  3. Заполните сведения об учетной записи службы, затем нажмите «Создать и продолжить» .
  4. Необязательно: назначьте роли вашей учетной записи службы, чтобы предоставить доступ к ресурсам вашего Google Cloud Project. Для получения более подробной информации обратитесь к предоставлению, изменению и отмене доступа к ресурсам .
  5. Нажмите «Продолжить» .
  6. Необязательно: введите пользователей или группы, которые могут управлять и выполнять действия с этой учетной записью службы. Для получения более подробной информации обратитесь к управлению подражанием учетной записи услуги .
  7. Нажмите «Готово» . Запишите адрес электронной почты для учетной записи службы.

Gcloud Cli

  1. Создайте учетную запись службы:
    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name="SERVICE_ACCOUNT_NAME"
  2. Необязательно: назначьте роли вашей учетной записи службы, чтобы предоставить доступ к ресурсам вашего Google Cloud Project. Для получения более подробной информации обратитесь к предоставлению, изменению и отмене доступа к ресурсам .

Сервисная учетная запись появляется на странице учетной записи службы. Далее создайте закрытый ключ для учетной записи службы.

Создать личный ключ

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

  1. В Cloud Console Google перейдите в меню > IAM & Admin > Сервисные учетные записи .

    Перейти к счетам обслуживания

  2. Выберите свою учетную запись службы.
  3. Щелкните клавиши > Добавить клавишу > Создать новый ключ .
  4. Выберите JSON , затем нажмите «Создать» .

    Ваша новая пара публичных/частных ключей генерируется и загружается на вашу машину в качестве нового файла. Сохраните загруженный файл json в качестве credentials.json . Этот файл является единственной копией этого ключа. Для получения информации о том, как надежно хранить ключ, см. Управление ключами учетной записи службы .

  5. Нажмите «Закрыть» .

Для получения дополнительной информации о учетных записях услуг см. В документации Google Cloud IAM.

Создайте клиент OAuth, совместимый с рынком Google Workspace.

Чтобы создать клиент OAuth, совместимый с клиентом Google Workspace, выполните следующие действия:

  1. В Cloud Console Google перейдите в меню > IAM & Admin > Сервисные учетные записи .

    Перейти к счетам обслуживания

  2. Нажмите на созданную вами учетную запись службы для приложения чата.

  3. Нажмите расширенные настройки .

  4. Нажмите «Создать Google Workspace», совместимый с клиентом OAuth .

  5. Нажмите «Продолжить» .

Появляется подтверждающее сообщение, в котором говорится, что клиент OAuth, совместимый с рынком Google, был создан.

Создать и развернуть приложение чата

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

Некоторые функции включают в себя недостатки в конце их имен, такие как processSlashCommand_() от ChatApp.gs . Подчеркивание скрывает функцию на веб -странице инициализации инцидента, когда она открыта в браузере. Для получения дополнительной информации см. Частные функции .

Сценарий приложений поддерживает два типа файлов: .gs сценарии и файлов .html . Чтобы соблюдать эту поддержку, JavaScript приложения включен в теги <script /> , а его CSS включен в теги <style /> внутри HTML-файла.

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

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

Вот обзор каждого файла:

Consts.gs

Определяет констант, на которые ссылаются другие файлы кода, включая ваш идентификатор облачного проекта, идентификатор местоположения Vertex AI, учетные данные приложения для учетной записи службы и идентификатор команды SLASH для закрытия инцидента.

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

Apps-Script/инцидент-ответ-App-Auth/consts.gs
const PROJECT_ID = 'replace-with-your-project-id';
const CLOSE_INCIDENT_COMMAND_ID = 1;
const APP_CREDENTIALS = 'replace-with-your-app-credentials';
const APP_CREDENTIALS_SCOPES = 'https://www.googleapis.com/auth/chat.bot https://www.googleapis.com/auth/chat.app.memberships https://www.googleapis.com/auth/chat.app.spaces.create';
const VERTEX_AI_LOCATION_ID = 'us-central1';
const MODEL_ID = 'gemini-1.5-flash-002';
ChatApp.gs

Обработает события взаимодействия в чате, включая сообщения, клики карты, команды SLASH и диалоги. Отвечает на команду Slash /closeIncident , открыв диалог для сбора деталей разрешения инцидентов. Считает сообщения в пространстве, вызывая метод spaces.messages.list в API чата. Получает идентификаторы пользователей, используя службу каталогов Admin SDK в скрипте приложений.

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

apps-script/инцидент-ответ-ап-аут/чатапп.gs
/**
 * Responds to a MESSAGE event in Google Chat.
 *
 * This app only responds to a slash command with the ID 1 ("/closeIncident").
 * It will respond to any other message with a simple "Hello" text message.
 *
 * @param {Object} event the event object from Google Chat
 */
function onMessage(event) {
  if (event.message.slashCommand) {
    return processSlashCommand_(event);
  }
  return { "text": "Hello from Incident Response app!" };
}

/**
 * Responds to a CARD_CLICKED event in Google Chat.
 *
 * This app only responds to one kind of dialog (Close Incident).
 *
 * @param {Object} event the event object from Google Chat
 */
function onCardClick(event) {
  if (event.isDialogEvent) {
    if (event.dialogEventType == 'SUBMIT_DIALOG') {
      return processSubmitDialog_(event);
    }
    return {
      actionResponse: {
        type: "DIALOG",
        dialogAction: {
          actionStatus: "OK"
        }
      }
    };
  }
}

/**
 * Responds to a MESSAGE event with a Slash command in Google Chat.
 *
 * This app only responds to a slash command with the ID 1 ("/closeIncident")
 * by returning a Dialog.
 *
 * @param {Object} event the event object from Google Chat
 */
function processSlashCommand_(event) {
  if (event.message.slashCommand.commandId != CLOSE_INCIDENT_COMMAND_ID) {
    return {
      "text": "Command not recognized. Use the command `/closeIncident` to close the incident managed by this space."
    };
  }
  const sections = [
    {
      header: "Close Incident",
      widgets: [
        {
          textInput: {
            label: "Please describe the incident resolution",
            type: "MULTIPLE_LINE",
            name: "description"
          }
        },
        {
          buttonList: {
            buttons: [
              {
                text: "Close Incident",
                onClick: {
                  action: {
                    function: "closeIncident"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  ];
  return {
    actionResponse: {
      type: "DIALOG",
      dialogAction: {
        dialog: {
          body: {
            sections,
          }
        }
      }
    }
  };
}

/**
 * Responds to a CARD_CLICKED event with a Dialog submission in Google Chat.
 *
 * This app only responds to one kind of dialog (Close Incident).
 * It creates a Doc with a summary of the incident information and posts a message
 * to the space with a link to the Doc.
 *
 * @param {Object} event the event object from Google Chat
 */
function processSubmitDialog_(event) {
  const resolution = event.common.formInputs.description[""].stringInputs.value[0];
  const chatHistory = concatenateAllSpaceMessages_(event.space.name);
  const chatSummary = summarizeChatHistory_(chatHistory);
  const docUrl = createDoc_(event.space.displayName, resolution, chatHistory, chatSummary);
  return {
    actionResponse: {
      type: "NEW_MESSAGE",
    },
    text: `Incident closed with the following resolution: ${resolution}\n\nHere is the automatically generated post-mortem:\n${docUrl}`
  };
}

/**
 * Lists all the messages in the Chat space, then concatenate all of them into
 * a single text containing the full Chat history.
 *
 * For simplicity for this demo, it only fetches the first 100 messages.
 *
 * Messages with slash commands are filtered out, so the returned history will
 * contain only the conversations between users and not app command invocations.
 *
 * @return {string} a text containing all the messages in the space in the format:
 *          Sender's name: Message
 */
function concatenateAllSpaceMessages_(spaceName) {
  // Call Chat API method spaces.messages.list
  const response = Chat.Spaces.Messages.list(spaceName, { 'pageSize': 100 });
  const messages = response.messages;
  // Fetch the display names of the message senders and returns a text
  // concatenating all the messages.
  let userMap = new Map();
  return messages
    .filter(message => message.slashCommand === undefined)
    .map(message => `${getUserDisplayName_(userMap, message.sender.name)}: ${message.text}`)
    .join('\n');
}

/**
 * Obtains the display name of a user by using the Admin Directory API.
 *
 * The fetched display name is cached in the provided map, so we only call the API
 * once per user.
 *
 * If the user does not have a display name, then the full name is used.
 *
 * @param {Map} userMap a map containing the display names previously fetched
 * @param {string} userName the resource name of the user
 * @return {string} the user's display name
 */
function getUserDisplayName_(userMap, userName) {
  if (userMap.has(userName)) {
    return userMap.get(userName);
  }
  let displayName = 'Unknown User';
  try {
    const user = AdminDirectory.Users.get(
      userName.replace("users/", ""),
      { projection: 'BASIC', viewType: 'domain_public' });
    displayName = user.name.displayName ? user.name.displayName : user.name.fullName;
  } catch (e) {
    // Ignore error if the API call fails (for example, because it's an
    // out-of-domain user or Chat app)) and just use 'Unknown User'.
  }
  userMap.set(userName, displayName);
  return displayName;
}
ChatSpaceCreator.gs

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

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

apps-script/инцидент-ответ-ап-аут/чат-spacecreator.gs
/**
 * Handles an incident by creating a chat space, adding members, and posting a message.
 * All the actions are done using application credentials.
 *
 * @param {Object} formData - The data submitted by the user. It should contain the fields:
 *                           - title: The display name of the chat space.
 *                           - description: The description of the incident.
 *                           - users: A comma-separated string of user emails to be added to the space.
 * @return {string} The resource name of the new space.
 */
function handleIncident(formData) {
  const users = formData.users.trim().length > 0 ? formData.users.split(',') : [];
  const service = getService_();
  if (!service.hasAccess()) {
    console.error(service.getLastError());
    return;
   }
  const spaceName = createChatSpace_(formData.title, service);
  createHumanMembership_(spaceName, getUserEmail(), service);
  for (const user of users ){
    createHumanMembership_(spaceName, user, service);
  }
  createMessage_(spaceName, formData.description, service);
  return spaceName;
}
/**
 * Creates a chat space with application credentials.
 *
 * @param {string} displayName - The name of the chat space.
 * @param {object} service - The credentials of the service account.
 * @returns {string} The resource name of the new space.
*/
function createChatSpace_(displayName, service) {
  try {
    // For private apps, the alias can be used
    const my_customer_alias = "customers/my_customer";
    // Specify the space to create.
    const space = {
        displayName: displayName,
        spaceType: 'SPACE',                
        customer: my_customer_alias
    };
    // Call Chat API with a service account to create a message.
    const createdSpace = Chat.Spaces.create(
        space,
        {},
        // Authenticate with the service account token.
        {'Authorization': 'Bearer ' + service.getAccessToken()});
    return createdSpace.name;
  } catch (err) {
    // TODO (developer) - Handle exception.
    console.log('Failed to create space with error %s', err.message);
  }
}
/*
 * Creates a chat message with application credentials.
 *
 * @param {string} spaceName - The resource name of the space.
 * @param {string} message - The text to be posted.
 * @param {object} service - The credentials of the service account.
 * @return {string} the resource name of the new space.
 */
function createMessage_(spaceName, message, service) {
  try {
    // Call Chat API with a service account to create a message.
    const result = Chat.Spaces.Messages.create(
        {'text': message},
        spaceName,
        {},
        // Authenticate with the service account token.
        {'Authorization': 'Bearer ' + service.getAccessToken()});

  } catch (err) {
    // TODO (developer) - Handle exception.
    console.log('Failed to create message with error %s', err.message);
  }
}
/**
 * Creates a human membership in a chat space with application credentials.
 *
 * @param {string} spaceName - The resource name of the space.
 * @param {string} email - The email of the user to be added.
 * @param {object} service - The credentials of the service account.
 */
function createHumanMembership_(spaceName, email, service){
  try{
    const membership = {
      member: {
        name: 'users/'+email,
        // User type for the membership
        type: 'HUMAN'
      }
    };
    const result = Chat.Spaces.Members.create(
      membership,
      spaceName,
      {},
      {'Authorization': 'Bearer ' + service.getAccessToken()}
    );
  } catch (err){
    console.log('Failed to create membership with error %s', err.message)
  }

}

 /*
 * Creates a service for the service account.
 * @return {object}  - The credentials of the service account.
 */
function getService_() {
  return OAuth2.createService(APP_CREDENTIALS.client_email)
      .setTokenUrl('https://oauth2.googleapis.com/token')
      .setPrivateKey(APP_CREDENTIALS.private_key)
      .setIssuer(APP_CREDENTIALS.client_email)
      .setSubject(APP_CREDENTIALS.client_email)
      .setScope(APP_CREDENTIALS_SCOPES)
      .setPropertyStore(PropertiesService.getScriptProperties());
}
DocsApi.gs

Вызывает API Google Docs, чтобы создать документ Google Docs в Google Drive пользователя и записывает краткую информацию о информации об инциденте, созданную в VertexAiApi.gs , в документ.

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

apps-script/инцидент-ответ-ап-аут/docsapi.gs
/**
 * Creates a Doc in the user's Google Drive and writes a summary of the incident information to it.
 *
 * @param {string} title The title of the incident
 * @param {string} resolution Incident resolution described by the user
 * @param {string} chatHistory The whole Chat history be included in the document
 * @param {string} chatSummary A summary of the Chat conversation to be included in the document
 * @return {string} the URL of the created Doc
 */
function createDoc_(title, resolution, chatHistory, chatSummary) {
  let doc = DocumentApp.create(title);
  let body = doc.getBody();
  body.appendParagraph(`Post-Mortem: ${title}`).setHeading(DocumentApp.ParagraphHeading.TITLE);
  body.appendParagraph("Resolution").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(resolution);
  body.appendParagraph("Summary of the conversation").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(chatSummary);
  body.appendParagraph("Full Chat history").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(chatHistory);
  return doc.getUrl();
}
VertexAiApi.gs

Суммирует разговор в пространстве чата, используя API Vertex AI. Это резюме размещено в специально созданном документе в DocsAPI.gs .

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

apps-script/инцидент-ответ-ап-аут/vertexaiapi.gs
/**
 * Summarizes a Chat conversation using the Vertex AI text prediction API.
 *
 * @param {string} chatHistory The Chat history that will be summarized.
 * @return {string} The content from the text prediction response.
 */


function summarizeChatHistory_(chatHistory) {

  const API_ENDPOINT = `https://${VERTEX_AI_LOCATION_ID}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${VERTEX_AI_LOCATION_ID}/publishers/google/models/${MODEL_ID}:generateContent`;
  const prompt = "Summarize the following conversation between Engineers resolving an incident"
      + " in a few sentences. Use only the information from the conversation.\n\n" + chatHistory;
  // Get the access token.
  const accessToken = ScriptApp.getOAuthToken();

  const headers = {
    'Authorization': 'Bearer ' + accessToken,
    'Content-Type': 'application/json',
  };
  const payload = {
    'contents': {
      'role': 'user',
      'parts' : [
        {
          'text': prompt
        }
      ]
    }
  }
  const options = {
    'method': 'post',
    'headers': headers,
    'payload': JSON.stringify(payload),
    'muteHttpExceptions': true,
  };
  try {
    const response = UrlFetchApp.fetch(API_ENDPOINT, options);
    const responseCode = response.getResponseCode();
    const responseText = response.getContentText();

    if (responseCode === 200) {
      const jsonResponse = JSON.parse(responseText);
      console.log(jsonResponse)
      if (jsonResponse.candidates && jsonResponse.candidates.length > 0) {
        return jsonResponse.candidates[0].content.parts[0].text; // Access the summarized text
      } else {
        return "No summary found in response.";
      }

    } else {
      console.error("Vertex AI API Error:", responseCode, responseText);
      return `Error: ${responseCode} - ${responseText}`;
    }
  } catch (e) {
    console.error("UrlFetchApp Error:", e);
    return "Error: " + e.toString();
  }
}
WebController.gs

Обслуживает веб -сайт инициализации инцидента.

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

apps-script/инцидент-ответ-ап-аут/webcontroller.gs
/**
 * Serves the web page from Index.html.
 */
function doGet() {
  return HtmlService
    .createTemplateFromFile('Index')
    .evaluate();
}

/**
 * Serves the web content from the specified filename.
 */
function include(filename) {
  return HtmlService
    .createHtmlOutputFromFile(filename)
    .getContent();
}

/**
 * Returns the email address of the user running the script.
 */
function getUserEmail() {
  return Session.getActiveUser().getEmail();
}
Index.html

HTML, включающий веб -сайт инициализации инцидента.

Просмотреть Index.html код

apps-script/инцидент-ответ-app-auth/index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
    <?!= include('Stylesheet'); ?>
  </head>
  <body>
    <div class="container">
      <div class="content">
        <h1>Incident Manager</h1>
        <form id="incident-form" onsubmit="handleFormSubmit(this)">
          <div id="form">
            <p>
              <label for="title">Incident title</label><br/>
              <input type="text" name="title" id="title" />
            </p>
            <p>
              <label for="users">Incident responders</label><br/>
              <small>
                Please enter a comma-separated list of email addresses of the users
                that should be added to the space.
                Do not include <?= getUserEmail() ?> as it will be added automatically.
              </small><br/>
              <input type="text" name="users" id="users" />
            </p>
            <p>
              <label for="description">Initial message</label></br>
              <small>This message will be posted after the space is created.</small><br/>
              <textarea name="description" id="description"></textarea>
            </p>
            <p class="text-center">
              <input type="submit" value="CREATE CHAT SPACE" />
            </p>
          </div>
          <div id="output" class="hidden"></div>
          <div id="clear" class="hidden">
            <input type="reset" value="CREATE ANOTHER INCIDENT" onclick="onReset()" />
          </div>
        </form>
      </div>
    </div>
    <?!= include('JavaScript'); ?>
  </body>
</html>
JavaScript.html

Обработает поведение формы, включая подачу, ошибки и очистки, для веб -сайта инициализации инцидента. Он включен в Index.html по пользовательскому include функции в WebController.gs .

Просмотреть код JavaScript.html

apps-script/инцидент-ответ-ап-аут/javascript.html
<script>
  var formDiv = document.getElementById('form');
  var outputDiv = document.getElementById('output');
  var clearDiv = document.getElementById('clear');

  function handleFormSubmit(formObject) {
    event.preventDefault();
    outputDiv.innerHTML = 'Please wait while we create the space...';
    hide(formDiv);
    show(outputDiv);
    google.script.run
      .withSuccessHandler(updateOutput)
      .withFailureHandler(onFailure)
      .handleIncident(formObject);
  }

  function updateOutput(response) {
    var spaceId = response.replace('spaces/', '');
    outputDiv.innerHTML =
      '<p>Space created!</p><p><a href="https://mail.google.com/chat/#chat/space/'
        + spaceId
        + '" target="_blank">Open space</a></p>';
    show(outputDiv);
    show(clearDiv);
  }

  function onFailure(error) {
    outputDiv.innerHTML = 'ERROR: ' + error.message;
    outputDiv.classList.add('error');
    show(outputDiv);
    show(clearDiv);
  }

  function onReset() {
    outputDiv.innerHTML = '';
    outputDiv.classList.remove('error');
    show(formDiv);
    hide(outputDiv);
    hide(clearDiv);
  }

  function hide(element) {
    element.classList.add('hidden');
  }

  function show(element) {
    element.classList.remove('hidden');
  }
</script>
Stylesheet.html

CSS для сайта инициализации инцидента. Он включен в Index.html по пользовательскому include функции в WebController.gs .

Просмотреть Stylesheet.html код

apps-script/инцидент-ответ-ап-аут/stylesheet.html
<style>
  * {
    box-sizing: border-box;
  }
  body {
    font-family: Roboto, Arial, Helvetica, sans-serif;
  }
  div.container {
    display: flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
  }
  div.content {
    width: 80%;
    max-width: 1000px;
    padding: 1rem;
    border: 1px solid #999;
    border-radius: 0.25rem;
    box-shadow: 0 2px 2px 0 rgba(66, 66, 66, 0.08), 0 2px 4px 2px rgba(66, 66, 66, 0.16);
  }
  h1 {
    text-align: center;
    padding-bottom: 1rem;
    margin: 0 -1rem 1rem -1rem;
    border-bottom: 1px solid #999;
  }
 #output {
    text-align: center;
    min-height: 250px;
  }
  div#clear {
    text-align: center;
    padding-top: 1rem;
    margin: 1rem -1rem 0 -1rem;
    border-top: 1px solid #999;
  }
  input[type=text], textarea {
    width: 100%;
    padding: 1rem 0.5rem;
    margin: 0.5rem 0;
    border: 0;
    border-bottom: 1px solid #999;
    background-color: #f0f0f0;
  }
  textarea {
    height: 5rem;
  }
  small {
    color: #999;
  }
  input[type=submit], input[type=reset] {
    padding: 1rem;
    border: none;
    background-color: #6200ee;
    color: #fff;
    border-radius: 0.25rem;
    width: 25%;
  }
  .hidden {
    display: none;
  }
  .text-center {
    text-align: center;
  }
  .error {
    color: red;
  }
</style>

Найдите свой облачный номер проекта и идентификатор

  1. В консоли Cloud Google перейдите в свой облачный проект.

    Перейти в Google Cloud Console

  2. Нажмите «Настройки и утилиты» > Настройки проекта .

  3. Обратите внимание на значения в номере проекта и поля идентификатора проекта . Вы используете их в следующих разделах.

Создать проект сценария приложений

Чтобы создать проект сценария приложений и подключить его с вашим облачным проектом:

  1. Нажмите следующую кнопку, чтобы открыть проект « Ответить на инциденты» с помощью проекта сценария приложений Google Chat .
    Откройте проект
  2. Нажмите обзор .
  3. На странице обзора нажмите Значок для создания копии Сделать копию .
  4. Назовите свою копию проекта сценария приложений:

    1. Нажмите на копию ответа на инциденты с Google Chat .

    2. В названии проекта тип Incident Management Chat app .

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

  5. В вашей копии проекта сценария приложений перейдите в файл Consts.gs и замените YOUR_PROJECT_ID на идентификатор вашего облачного проекта.

Установите облачный проект Project Script Project

  1. В проекте сценария приложений нажмите Значок для настройки проекта Настройки проекта .
  2. В рамках проекта Google Cloud Platform (GCP) нажмите «Изменить проект» .
  3. В номере проекта GCP вставьте номер проекта вашего облачного проекта.
  4. Нажмите SET Project . Проект облачного проекта и скрипта приложений теперь подключены.

Создать развертывание сценария приложений

Теперь, когда весь код на месте, разверните проект сценария приложений. Вы используете идентификатор развертывания при настройке приложения чата в Google Cloud.

  1. В скрипте приложений откройте проект приложения для ответа на инцидент.

    Перейти к сценарию приложений

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

  3. Если дополнение и веб-приложение еще не выбрано, рядом с выберите «Тип » нажмите Типы развертывания Значок для настройки проекта и выберите дополнение и веб-приложение .

  4. В описании введите описание для этой версии, например Complete version of incident management app .

  5. В Exepute AS выберите пользователя, доступ к которому доступ к веб -приложению

  6. В том, кто имеет доступ , выберите любого в вашей организации рабочей области , где «ваша организация рабочей области» является названием вашей организации Google Workspace.

  7. Нажмите Deploy . Сценарий приложений сообщает об успешном развертывании и предоставляет идентификатор развертывания и URL -адрес веб -страницы инициализации инцидента.

  8. Запишите URL -адрес веб -приложения для посещения позже, когда вы начнете инцидент. Скопируйте идентификатор развертывания . Вы используете этот идентификатор при настройке приложения чата в Google Cloud Console.

  9. Нажмите «Готово» .

Настройте приложение чата в консоли Google Cloud Console

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

  1. В консоли Cloud Google нажмите « > « Больше продуктов» > «Google Workspace» > «Библиотека продуктов» > «Google Chat Api» > « Управление » .

    Перейдите в конфигурацию API чата

  2. В названии приложения тип Incident Management .

  3. В URL Avatar введите https://developers.google.com/chat/images/quickstart-app-avatar.png .

  4. В описании тип Responds to incidents. .

  5. Нажмите на включение интерактивных функций, переключающихся в положение ON.

  6. В рамках функциональности выберите «Получить сообщения» 1: 1 , присоединиться к пространствам и групповым разговорам .

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

  8. В идентификаторе развертывания вставьте идентификатор развертывания сценария приложений, который вы скопировали ранее из развертывания проекта приложений.

  9. Зарегистрируйте команду Slash , которую использует полностью реализованное приложение Chat:

    1. В разделе команды нажмите «Добавить команду» .

    2. В идентификаторе команды тип 1 .

    3. В описании тип Closes the incident being discussed in the space.

    4. Под типом команды выберите команду Slash .

    5. В названии команды Slash , Type /closeIncident .

    6. Выберите «Открывает диалог» .

    7. Нажмите «Готово» . Команда SLASH зарегистрирована и перечислена.

  10. В соответствии с видимостью выберите это приложение для чата доступным для конкретных людей и групп в вашем домене рабочей области и введите свой адрес электронной почты.

  11. Под журналами выберите ошибки журнала в журнале .

  12. Нажмите Сохранить . Появится сохраненная конфигурация, то есть приложение готово к тестированию.

Получить утверждение администратора

Чтобы получить утверждение администратора, вы должны настроить приложение Chat на рынке Google Workspace SDK.

Настройка приложения чата в Google Workspace Marketplace SDK

Чтобы настроить приложение чата в Google Workspace Marketplace SDK, выполните следующие действия:

  1. В Cloud Console Google перейдите в «Меню » > «API & Services» > «API & Services»> «API & Services» > «Google Workspace Marketplace SDK > Конфигурация приложения» .

    Перейдите в конфигурацию приложения

  2. Заполните страницу конфигурации приложения. То, как вы настраиваете приложение для чата, зависит от того, кто является вашей предполагаемой аудиторией, и других факторов. Для заполнения страницы конфигурации приложения см. Настройте приложение на рынке Google Workspace SDK . Для целей настоящего Руководства введите следующую информацию:

    1. Под видимостью приложения выберите Private .
    2. В условиях установки выберите Admin Install .
    3. В разделе «Интеграции приложений» выберите приложение чата .
    4. В рамках OAuth Scopes введите следующие прицелы:
      • https://www.googleapis.com/auth/chat.app.spaces
      • https://www.googleapis.com/auth/chat.app.memberships
    5. В разделе «Информация о разработчике» введите имя своего разработчика , URL -адрес веб -сайта разработчика и электронную почту разработчика .
    6. Нажмите «Сохранить черновик» .

После настройки приложения обновите список магазинов:

  1. В Cloud Console Google перейдите в меню > API и услуги > включенные API & Services > Google Workspace Marketplace SDK > Список магазинов .
  2. В данных приложения выберите веб -разработку в качестве категории.
  3. В графических активах загружайте значки приложений в запрошенных форматах.
  4. На скриншотах загрузите скриншот приложения.
  5. В ссылках на поддержку заполняйте Указы URL -адреса обслуживания, URL -адрес конфиденциальности и URL -адрес поддержки.
  6. В распределении выберите регионы, где будет доступно это приложение.
  7. Нажмите Publish .

Получить одобрение администратора

Теперь, когда ваша учетная запись сервиса настроена на получение утверждения администратора, получите его от администратора Workspace Google, который может предоставить одобрение, выполнив шаги по настройке авторизации для приложений для чата .

Проверьте приложение чата

Чтобы проверить приложение по управлению инцидентами, инициируйте инцидент с веб -страницы и убедитесь, что приложение чата работает как ожидалось:

  1. Перейдите в приложение для развертывания приложений приложения.

  2. Когда скрипт приложений требует разрешения на доступ к вашим данным, нажмите «Разрешения на просмотр» , войдите в систему с соответствующей учетной записью Google в вашем домене Google Workspace и нажмите «Разрешить» .

  3. Откроется веб -страница инициализации инцидента. Введите тестовую информацию:

    1. В названии инцидента введите The First Incident .
    2. При желании, в респондентах инцидентов , введите адреса электронной почты ваших коллег -респондентов. Они должны быть пользователями с учетной записью чата Google в вашей организации Google Workspace или создание пространства. Не вводите свой собственный адрес электронной почты, потому что он включен автоматически.
    3. В начальном сообщении введите Testing the incident management Chat app.
  4. Нажмите «Создать пространство чата» . Появляется creating space сообщение.

  5. После того, как пространство создано, Space created! Сообщение появляется. Нажмите Open Space , которое открывает пространство в чате на новой вкладке.

  6. При желании вы и другие респонденты инцидента можете отправлять сообщения в пространстве. Приложение суммирует эти сообщения с использованием вершины AI и делится ретроспективным документом.

  7. Чтобы закончить ответ инцидента и начать процесс разрешения, в пространстве чата, тип /closeIncident . Откроется диалог управления инцидентами.

  8. В тесном инциденте введите описание для разрешения инцидентов, например, Test complete .

  9. Нажмите «Закрыть инцидент» .

В приложении по управлению инцидентами перечислены сообщения в пространстве, суммирует их с помощью AI Vertex, внедряет резюме в документ Google Docs и делится документом в пространстве.

Очистить

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

  1. В консоли Cloud Google перейдите на страницу управления ресурсами . Нажмите Меню > IAM & Admin > Управление ресурсами .

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

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

В этом учебном пособии используются области авторизации, которые начинаются с https://www.googleapis.com/auth/chat.app.* , которые доступны как часть предварительного просмотра разработчика, ваше приложение для чата должно получить одноразовое одобрение администратора .

В этом уроке показано, как сделать приложение Google Chat, которое отвечает на инциденты в режиме реального времени. Отвечая на инцидент, приложение создает и заполняет пространство в чате, облегчает разрешение инцидентов с сообщениями, командами SLASH и диалогов, и использует ИИ, чтобы суммировать ответ инцидента в документе Google Docs.

Инцидент - это событие, которое требует немедленного внимания команды людей для решения. Примеры инцидентов включают:

  • Чувствительный к во времени случай создается на платформе управления взаимоотношениями с клиентами (CRM), которая требует от команды службы сотрудничать в разрешении.
  • Система остается в автономном режиме, предупреждая группу инженеров по надежности сайта (SRES), чтобы они могли работать вместе, чтобы вернуть ее в Интернете.
  • Высоко высокого землетрясения, и аварийные работники должны координировать свой ответ.

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

Смотрите приложение чата управления инцидентами в действии:

  • Сайт, который начинает инцидент.
    Рисунок 1. На сайте, где кто -то может сообщить об инциденте.
  • Уведомление о том, что инцидентное пространство чата создается.
    Рисунок 2. Уведомление о том, что инцидентное пространство чата создается.
  • Ответ инцидента в чате.
    Рисунок 3. Пространство чата в чате инцидента.
  • Разрешение инцидента с помощью команды Slash.
    Рисунок 4. Разрешение инцидента с помощью команды Slash.
  • Диалог разрешения инцидентов.
    Рисунок 5. Диалоговое окно разрешения инцидентов.
  • Резолюция об инцидентах Google Docs Document, разделенный в космосе.
    Рисунок 6. Разрешение инцидентов документ Google Docs, разделенный в космосе.
  • Резюме ИИ
    Рисунок 7. Документ Google Docs Resolution Retude Docs.

Предварительные условия

Если вам нужно какие -либо из этих предпосылок, включенных для вашей организации, попросите ваш администратор Workspace Google, чтобы включить их:

  • Бизнес или корпоративная учетная запись Google Workspace с доступом к Google Chat .
  • Чтобы включить каталог (обмен контактами) для Google Workspace. Приложение инцидента использует каталог для поиска контактной информации респондентов, например, имя и адрес электронной почты. Респонденты инцидентов должны быть пользователями с учетной записью Google Chat в вашей организации Google Workspace.

Цели

  • Создайте приложение чата, которое отвечает на инциденты.
  • Помогите пользователям реагировать на инциденты, выполняя следующие действия:
    • Создание пространств реагирования на инцидент.
    • Размещение сообщений, обобщающих инциденты и ответы.
    • Поддержка сотрудничества с интерактивными функциями приложения чата.
  • Суммируйте разговоры и резолюции с помощью вершины AI.

Архитектура

На следующей диаграмме показана архитектура Google Workspace и Google Cloud Resources, используемые в приложении Google Chat Google.

Архитектура ответа на инцидент приложение Google Chat

Архитектура показывает, как приложение Google Chat в Google обрабатывает инцидент и разрешение.

  1. Пользователь начинает инцидент с внешнего веб -сайта, размещенного в скрипте приложений.

  2. Веб -сайт отправляет асинхронный HTTP -запрос в приложение Google Chat, также размещенное в скрипте приложений.

  3. Ответ инцидента Google Chat Приложение обрабатывает запрос:

    1. Сервис SDK Script Script Apps получает информацию о членах команды, такую ​​как идентификатор пользователя и адрес электронной почты.

    2. Благодаря набору HTTP -запросов на API в чате с использованием Apps Script Script Advanced Chat Service, приложение Google Chat в Google создает пространство чата инцидента, заполняет его членами команды и отправляет сообщение в пространство.

  4. Члены команды обсуждают инцидент в пространстве чата.

  5. Член команды вызывает команду SLASH, чтобы сигнализировать о разрешении на инцидент.

    1. Вызов HTTP для чата с использованием Apps Script Script Script Advanced Chat Service перечисляет все сообщения в чате.

    2. Vertex AI получает перечисленные сообщения и генерирует резюме.

    3. Служба сценария приложений DocumentApp создает документ DOCS и добавляет резюме Vertex AI в документ.

    4. Ответ инцидента в приложении Google Chat вызывает API Chat, чтобы отправить сообщение об обмене ссылкой в ​​документ «Сводные документы».

Подготовьте окружающую среду

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

Создать Google Cloud Project

Google Cloud Console

  1. В Cloud Console Google перейдите в меню > IAM & Admin > Создайте проект .

    Перейти к созданию проекта

  2. В поле «Имя проекта» введите описательное имя для вашего проекта.

    Необязательно: Чтобы отредактировать идентификатор проекта , нажмите «Редактировать» . Идентификатор проекта не может быть изменен после создания проекта, поэтому выберите идентификатор, который отвечает вашим потребностям для жизни проекта.

  3. В поле «Расположение» нажмите «Обзор» , чтобы отобразить потенциальные местоположения для вашего проекта. Затем нажмите «Выбрать» .
  4. Нажмите «Создать» . Cloud Console Google перемещается на страницу приборной панели, и ваш проект создается в течение нескольких минут.

Gcloud Cli

В одной из следующих средств разработки обратитесь к Google Cloud CLI ( gcloud ):

  • Cloud Shell : Чтобы использовать онлайн -терминал с уже настроенным GCLOUD CLI, активируйте облачную оболочку.
    Активируйте облачную оболочку
  • Локальная оболочка : чтобы использовать местную среду разработки, установить и инициализировать Gcloud CLI.
    Чтобы создать облачный проект, используйте команду gcloud projects create :
    gcloud projects create PROJECT_ID
    Замените PROJECT_ID , установив идентификатор для проекта, который вы хотите создать.

Включить биллинг для облачного проекта

Google Cloud Console

  1. В консоли Cloud Google отправляйтесь на биллинг . Нажмите «Меню > «Биллинг» > «Мои проекты» .

    Пойдите на выставление счетов за мои проекты

  2. В избранной организации выберите организацию, связанную с вашим Google Cloud Project.
  3. В строке проекта откройте меню Actions ( ), нажмите «Изменить Биллинг» и выберите учетную запись Cloud Billing.
  4. Нажмите «Установить учетную запись» .

Gcloud Cli

  1. Чтобы перечислить доступные счеты счетов, запустите:
    gcloud billing accounts list
  2. Свяжите биллинговую учетную запись с помощью Google Cloud Project:
    gcloud billing projects link PROJECT_ID --billing-account=BILLING_ACCOUNT_ID

    Замените следующее:

    • PROJECT_ID - это идентификатор проекта для облачного проекта, для которого вы хотите включить выставление счетов.
    • BILLING_ACCOUNT_ID - это идентификатор биллинговой учетной записи для ссылки с Google Cloud Project.

Включить API

Google Cloud Console

  1. В Cloud Console Google включите API Google Chat, API Google Docs, Admin SDK API, Google Workspace SDK и API Vertex AI.

    Включить API

  2. Убедитесь, что вы включите API в правильном облачном проекте, затем нажмите Далее .

  3. Убедитесь, что вы включите правильные API, затем нажмите « Включить» .

Gcloud Cli

  1. При необходимости установите текущий облачный проект на тот, который вы создали с помощью команды gcloud config set project :

    gcloud config set project PROJECT_ID

    Замените PROJECT_ID на идентификатор проекта созданного вами облачного проекта.

  2. Включите API Google Chat API, Google Docs API, Admin SDK API, Google Workspace Marketplace SDK и API Vertex API с gcloud services enable :

    gcloud services enable chat.googleapis.com docs.googleapis.com admin.googleapis.com aiplatform.googleapis.com appsmarket-component.googleapis.com

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

Приложение Chat обращается к Google Chat API, используя учетные данные приложения Chat. Приложение получает доступ к API API Admin SDK и Google DOCS с учетными данными пользователя.

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

Аутентификация и авторизация позволяют ресурсам доступа к приложению в чате в Google Workspace и Google Cloud обрабатывать ответ инцидента. В частности, аутентификация пользователя используется для вызова API Google Docs и ADM SDK API.

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

  1. В консоли Cloud Google перейдите в меню > > Брендинг .

    Пойти на брендинг

  2. Если вы уже настроили, вы можете настроить следующие настройки экрана согласия OAuth в брендинге , аудитории и доступе к данным . Если вы видите сообщение, в котором говорится Еще не настроен , нажмите «Начни» :

    1. В разделе «Информация о приложении» , в названии приложения , тип Incident Management .
    2. В электронной почте пользователя выберите свой адрес электронной почты или подходящую группу Google.
    3. Нажмите Далее .
    4. Под аудиторией выберите внутренний . Если вы не можете выбрать Internal , выберите внешний .
    5. Нажмите Далее .
    6. В соответствии с контактной информацией введите адрес электронной почты , где вы можете быть уведомлены о любых изменениях в вашем проекте.
    7. Нажмите Далее .
    8. В соответствии с финишем просмотрите политику пользовательских данных Google API Services , и если вы согласны, выберите «Я согласен с службами Google API: Политика пользовательских данных» .
    9. Нажмите «Продолжить» .
    10. Нажмите «Создать» .
    11. Если вы выбрали внешний для типа пользователя, добавьте тестовые пользователи:
      1. Нажмите на аудиторию .
      2. Под тестируемыми пользователями нажмите «Добавить пользователей» .
      3. Введите свой адрес электронной почты и любых других авторизованных тестовых пользователей, затем нажмите « Сохранить» .
  3. Нажмите Доступ к данным > Добавить или удалить области . Панель появляется со списком областей применения для каждого API, который вы включили в своем Google Cloud Project.

    1. Под вручную добавить область , вставьте следующие прицелы:

      • https://www.googleapis.com/auth/documents
      • https://www.googleapis.com/auth/admin.directory.user.readonly
      • https://www.googleapis.com/auth/script.external_request
      • https://www.googleapis.com/auth/userinfo.email
      • https://www.googleapis.com/auth/cloud-platform
    2. Нажмите «Добавить в таблицу» .

    3. Нажмите обновление .

    4. После выбора областей, требуемых вашим приложением, на странице доступа к данным нажмите «Сохранить» .

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

Аутентификация приложения используется для вызова API Google Chat.

Создать учетную запись службы в Cloud Console Google

Чтобы создать учетную запись службы, выполните следующие действия:

Google Cloud Console

  1. В Cloud Console Google перейдите в меню > IAM & Admin > Сервисные учетные записи .

    Перейти к счетам обслуживания

  2. Нажмите «Создать учетную запись службы» .
  3. Заполните сведения об учетной записи службы, затем нажмите «Создать и продолжить» .
  4. Необязательно: назначьте роли вашей учетной записи службы, чтобы предоставить доступ к ресурсам вашего Google Cloud Project. Для получения более подробной информации обратитесь к предоставлению, изменению и отмене доступа к ресурсам .
  5. Нажмите «Продолжить» .
  6. Необязательно: введите пользователей или группы, которые могут управлять и выполнять действия с этой учетной записью службы. Для получения более подробной информации обратитесь к управлению подражанием учетной записи услуги .
  7. Нажмите «Готово» . Запишите адрес электронной почты для учетной записи службы.

Gcloud Cli

  1. Создайте учетную запись службы:
    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name="SERVICE_ACCOUNT_NAME"
  2. Необязательно: назначьте роли вашей учетной записи службы, чтобы предоставить доступ к ресурсам вашего Google Cloud Project. Для получения более подробной информации обратитесь к предоставлению, изменению и отмене доступа к ресурсам .

Сервисная учетная запись появляется на странице учетной записи службы. Далее создайте закрытый ключ для учетной записи службы.

Создать личный ключ

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

  1. В Cloud Console Google перейдите в меню > IAM & Admin > Сервисные учетные записи .

    Перейти к счетам обслуживания

  2. Выберите свою учетную запись службы.
  3. Щелкните клавиши > Добавить клавишу > Создать новый ключ .
  4. Выберите JSON , затем нажмите «Создать» .

    Your new public/private key pair is generated and downloaded to your machine as a new file. Save the downloaded JSON file as credentials.json in your working directory. This file is the only copy of this key. For information about how to store your key securely, see Managing service account keys .

  5. Click Close .

For more information about service accounts, see service accounts in the Google Cloud IAM documentation.

Create a Google Workspace Marketplace-compatible OAuth client

To create a Google Workspace Marketplace-compatible OAuth client, follow these steps:

  1. In the Google Cloud console, go to Menu > IAM & Admin > Service Accounts .

    Go to Service Accounts

  2. Click the service account you created for your Chat app.

  3. Click Advanced settings .

  4. Click Create Google Workspace Marketplace-compatible OAuth client .

  5. Click Continue .

A confirmation message appears that says a Google Workspace Marketplace-compatible OAuth client has been created.

Create and deploy the Chat app

In the following section, you copy and update an entire Apps Script project that contains all the required application code for your Chat app, so there's no need to copy and paste each file.

Some functions include underscores at the end of their names, like processSlashCommand_() from ChatApp.gs . The underscore hides the function from the incident initialization web page when it's open in a browser. For more information, see Private functions .

Apps Script supports two file types, .gs scripts and .html files. To abide by this support, the app's client-side JavaScript is included inside <script /> tags and its CSS is included inside <style /> tags inside an HTML file.

Optionally, you can view the entire project on GitHub.

View on GitHub

Here's an overview of each file:

Consts.gs

Defines constants referenced by other code files, including your Cloud project ID, Vertex AI location ID, app credentials for the service account and the slash command ID for closing an incident.

View Consts.gs code

apps-script/incident-response-app-auth/Consts.gs
const PROJECT_ID = 'replace-with-your-project-id';
const CLOSE_INCIDENT_COMMAND_ID = 1;
const APP_CREDENTIALS = 'replace-with-your-app-credentials';
const APP_CREDENTIALS_SCOPES = 'https://www.googleapis.com/auth/chat.bot https://www.googleapis.com/auth/chat.app.memberships https://www.googleapis.com/auth/chat.app.spaces.create';
const VERTEX_AI_LOCATION_ID = 'us-central1';
const MODEL_ID = 'gemini-1.5-flash-002';
ChatApp.gs

Handles Chat interaction events, including messages, card clicks, slash commands, and dialogs. Responds to the /closeIncident slash command by opening a dialog to gather incident resolution details. Reads messages in the space by calling the spaces.messages.list method in the Chat API. Gets user IDs using the Admin SDK Directory service in Apps Script.

View ChatApp.gs code

apps-script/incident-response-app-auth/ChatApp.gs
/**
 * Responds to a MESSAGE event in Google Chat.
 *
 * This app only responds to a slash command with the ID 1 ("/closeIncident").
 * It will respond to any other message with a simple "Hello" text message.
 *
 * @param {Object} event the event object from Google Chat
 */
function onMessage(event) {
  if (event.message.slashCommand) {
    return processSlashCommand_(event);
  }
  return { "text": "Hello from Incident Response app!" };
}

/**
 * Responds to a CARD_CLICKED event in Google Chat.
 *
 * This app only responds to one kind of dialog (Close Incident).
 *
 * @param {Object} event the event object from Google Chat
 */
function onCardClick(event) {
  if (event.isDialogEvent) {
    if (event.dialogEventType == 'SUBMIT_DIALOG') {
      return processSubmitDialog_(event);
    }
    return {
      actionResponse: {
        type: "DIALOG",
        dialogAction: {
          actionStatus: "OK"
        }
      }
    };
  }
}

/**
 * Responds to a MESSAGE event with a Slash command in Google Chat.
 *
 * This app only responds to a slash command with the ID 1 ("/closeIncident")
 * by returning a Dialog.
 *
 * @param {Object} event the event object from Google Chat
 */
function processSlashCommand_(event) {
  if (event.message.slashCommand.commandId != CLOSE_INCIDENT_COMMAND_ID) {
    return {
      "text": "Command not recognized. Use the command `/closeIncident` to close the incident managed by this space."
    };
  }
  const sections = [
    {
      header: "Close Incident",
      widgets: [
        {
          textInput: {
            label: "Please describe the incident resolution",
            type: "MULTIPLE_LINE",
            name: "description"
          }
        },
        {
          buttonList: {
            buttons: [
              {
                text: "Close Incident",
                onClick: {
                  action: {
                    function: "closeIncident"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  ];
  return {
    actionResponse: {
      type: "DIALOG",
      dialogAction: {
        dialog: {
          body: {
            sections,
          }
        }
      }
    }
  };
}

/**
 * Responds to a CARD_CLICKED event with a Dialog submission in Google Chat.
 *
 * This app only responds to one kind of dialog (Close Incident).
 * It creates a Doc with a summary of the incident information and posts a message
 * to the space with a link to the Doc.
 *
 * @param {Object} event the event object from Google Chat
 */
function processSubmitDialog_(event) {
  const resolution = event.common.formInputs.description[""].stringInputs.value[0];
  const chatHistory = concatenateAllSpaceMessages_(event.space.name);
  const chatSummary = summarizeChatHistory_(chatHistory);
  const docUrl = createDoc_(event.space.displayName, resolution, chatHistory, chatSummary);
  return {
    actionResponse: {
      type: "NEW_MESSAGE",
    },
    text: `Incident closed with the following resolution: ${resolution}\n\nHere is the automatically generated post-mortem:\n${docUrl}`
  };
}

/**
 * Lists all the messages in the Chat space, then concatenate all of them into
 * a single text containing the full Chat history.
 *
 * For simplicity for this demo, it only fetches the first 100 messages.
 *
 * Messages with slash commands are filtered out, so the returned history will
 * contain only the conversations between users and not app command invocations.
 *
 * @return {string} a text containing all the messages in the space in the format:
 *          Sender's name: Message
 */
function concatenateAllSpaceMessages_(spaceName) {
  // Call Chat API method spaces.messages.list
  const response = Chat.Spaces.Messages.list(spaceName, { 'pageSize': 100 });
  const messages = response.messages;
  // Fetch the display names of the message senders and returns a text
  // concatenating all the messages.
  let userMap = new Map();
  return messages
    .filter(message => message.slashCommand === undefined)
    .map(message => `${getUserDisplayName_(userMap, message.sender.name)}: ${message.text}`)
    .join('\n');
}

/**
 * Obtains the display name of a user by using the Admin Directory API.
 *
 * The fetched display name is cached in the provided map, so we only call the API
 * once per user.
 *
 * If the user does not have a display name, then the full name is used.
 *
 * @param {Map} userMap a map containing the display names previously fetched
 * @param {string} userName the resource name of the user
 * @return {string} the user's display name
 */
function getUserDisplayName_(userMap, userName) {
  if (userMap.has(userName)) {
    return userMap.get(userName);
  }
  let displayName = 'Unknown User';
  try {
    const user = AdminDirectory.Users.get(
      userName.replace("users/", ""),
      { projection: 'BASIC', viewType: 'domain_public' });
    displayName = user.name.displayName ? user.name.displayName : user.name.fullName;
  } catch (e) {
    // Ignore error if the API call fails (for example, because it's an
    // out-of-domain user or Chat app)) and just use 'Unknown User'.
  }
  userMap.set(userName, displayName);
  return displayName;
}
ChatSpaceCreator.gs

Receives form data users enter on the incident initialization web page, and uses it to set up a Chat space by creating and populating it, and then posts a message about the incident.

View ChatSpaceCreator.gs code

apps-script/incident-response-app-auth/ChatSpaceCreator.gs
/**
 * Handles an incident by creating a chat space, adding members, and posting a message.
 * All the actions are done using application credentials.
 *
 * @param {Object} formData - The data submitted by the user. It should contain the fields:
 *                           - title: The display name of the chat space.
 *                           - description: The description of the incident.
 *                           - users: A comma-separated string of user emails to be added to the space.
 * @return {string} The resource name of the new space.
 */
function handleIncident(formData) {
  const users = formData.users.trim().length > 0 ? formData.users.split(',') : [];
  const service = getService_();
  if (!service.hasAccess()) {
    console.error(service.getLastError());
    return;
   }
  const spaceName = createChatSpace_(formData.title, service);
  createHumanMembership_(spaceName, getUserEmail(), service);
  for (const user of users ){
    createHumanMembership_(spaceName, user, service);
  }
  createMessage_(spaceName, formData.description, service);
  return spaceName;
}
/**
 * Creates a chat space with application credentials.
 *
 * @param {string} displayName - The name of the chat space.
 * @param {object} service - The credentials of the service account.
 * @returns {string} The resource name of the new space.
*/
function createChatSpace_(displayName, service) {
  try {
    // For private apps, the alias can be used
    const my_customer_alias = "customers/my_customer";
    // Specify the space to create.
    const space = {
        displayName: displayName,
        spaceType: 'SPACE',                
        customer: my_customer_alias
    };
    // Call Chat API with a service account to create a message.
    const createdSpace = Chat.Spaces.create(
        space,
        {},
        // Authenticate with the service account token.
        {'Authorization': 'Bearer ' + service.getAccessToken()});
    return createdSpace.name;
  } catch (err) {
    // TODO (developer) - Handle exception.
    console.log('Failed to create space with error %s', err.message);
  }
}
/*
 * Creates a chat message with application credentials.
 *
 * @param {string} spaceName - The resource name of the space.
 * @param {string} message - The text to be posted.
 * @param {object} service - The credentials of the service account.
 * @return {string} the resource name of the new space.
 */
function createMessage_(spaceName, message, service) {
  try {
    // Call Chat API with a service account to create a message.
    const result = Chat.Spaces.Messages.create(
        {'text': message},
        spaceName,
        {},
        // Authenticate with the service account token.
        {'Authorization': 'Bearer ' + service.getAccessToken()});

  } catch (err) {
    // TODO (developer) - Handle exception.
    console.log('Failed to create message with error %s', err.message);
  }
}
/**
 * Creates a human membership in a chat space with application credentials.
 *
 * @param {string} spaceName - The resource name of the space.
 * @param {string} email - The email of the user to be added.
 * @param {object} service - The credentials of the service account.
 */
function createHumanMembership_(spaceName, email, service){
  try{
    const membership = {
      member: {
        name: 'users/'+email,
        // User type for the membership
        type: 'HUMAN'
      }
    };
    const result = Chat.Spaces.Members.create(
      membership,
      spaceName,
      {},
      {'Authorization': 'Bearer ' + service.getAccessToken()}
    );
  } catch (err){
    console.log('Failed to create membership with error %s', err.message)
  }

}

 /*
 * Creates a service for the service account.
 * @return {object}  - The credentials of the service account.
 */
function getService_() {
  return OAuth2.createService(APP_CREDENTIALS.client_email)
      .setTokenUrl('https://oauth2.googleapis.com/token')
      .setPrivateKey(APP_CREDENTIALS.private_key)
      .setIssuer(APP_CREDENTIALS.client_email)
      .setSubject(APP_CREDENTIALS.client_email)
      .setScope(APP_CREDENTIALS_SCOPES)
      .setPropertyStore(PropertiesService.getScriptProperties());
}
DocsApi.gs

Calls the Google Docs API to create a Google Docs document in a user's Google Drive and writes a summary of the incident information, created in VertexAiApi.gs , to the document.

View DocsApi.gs code

apps-script/incident-response-app-auth/DocsApi.gs
/**
 * Creates a Doc in the user's Google Drive and writes a summary of the incident information to it.
 *
 * @param {string} title The title of the incident
 * @param {string} resolution Incident resolution described by the user
 * @param {string} chatHistory The whole Chat history be included in the document
 * @param {string} chatSummary A summary of the Chat conversation to be included in the document
 * @return {string} the URL of the created Doc
 */
function createDoc_(title, resolution, chatHistory, chatSummary) {
  let doc = DocumentApp.create(title);
  let body = doc.getBody();
  body.appendParagraph(`Post-Mortem: ${title}`).setHeading(DocumentApp.ParagraphHeading.TITLE);
  body.appendParagraph("Resolution").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(resolution);
  body.appendParagraph("Summary of the conversation").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(chatSummary);
  body.appendParagraph("Full Chat history").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(chatHistory);
  return doc.getUrl();
}
VertexAiApi.gs

Summarizes the conversation in the Chat space using Vertex AI API. This summary is posted in a specially-created document in DocsAPI.gs .

View VertexAiApi.gs code

apps-script/incident-response-app-auth/VertexAiApi.gs
/**
 * Summarizes a Chat conversation using the Vertex AI text prediction API.
 *
 * @param {string} chatHistory The Chat history that will be summarized.
 * @return {string} The content from the text prediction response.
 */


function summarizeChatHistory_(chatHistory) {

  const API_ENDPOINT = `https://${VERTEX_AI_LOCATION_ID}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${VERTEX_AI_LOCATION_ID}/publishers/google/models/${MODEL_ID}:generateContent`;
  const prompt = "Summarize the following conversation between Engineers resolving an incident"
      + " in a few sentences. Use only the information from the conversation.\n\n" + chatHistory;
  // Get the access token.
  const accessToken = ScriptApp.getOAuthToken();

  const headers = {
    'Authorization': 'Bearer ' + accessToken,
    'Content-Type': 'application/json',
  };
  const payload = {
    'contents': {
      'role': 'user',
      'parts' : [
        {
          'text': prompt
        }
      ]
    }
  }
  const options = {
    'method': 'post',
    'headers': headers,
    'payload': JSON.stringify(payload),
    'muteHttpExceptions': true,
  };
  try {
    const response = UrlFetchApp.fetch(API_ENDPOINT, options);
    const responseCode = response.getResponseCode();
    const responseText = response.getContentText();

    if (responseCode === 200) {
      const jsonResponse = JSON.parse(responseText);
      console.log(jsonResponse)
      if (jsonResponse.candidates && jsonResponse.candidates.length > 0) {
        return jsonResponse.candidates[0].content.parts[0].text; // Access the summarized text
      } else {
        return "No summary found in response.";
      }

    } else {
      console.error("Vertex AI API Error:", responseCode, responseText);
      return `Error: ${responseCode} - ${responseText}`;
    }
  } catch (e) {
    console.error("UrlFetchApp Error:", e);
    return "Error: " + e.toString();
  }
}
WebController.gs

Serves the incident initialization website.

View WebController.gs code

apps-script/incident-response-app-auth/WebController.gs
/**
 * Serves the web page from Index.html.
 */
function doGet() {
  return HtmlService
    .createTemplateFromFile('Index')
    .evaluate();
}

/**
 * Serves the web content from the specified filename.
 */
function include(filename) {
  return HtmlService
    .createHtmlOutputFromFile(filename)
    .getContent();
}

/**
 * Returns the email address of the user running the script.
 */
function getUserEmail() {
  return Session.getActiveUser().getEmail();
}
Index.html

The HTML comprising the incident initialization website.

View Index.html code

apps-script/incident-response-app-auth/Index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
    <?!= include('Stylesheet'); ?>
  </head>
  <body>
    <div class="container">
      <div class="content">
        <h1>Incident Manager</h1>
        <form id="incident-form" onsubmit="handleFormSubmit(this)">
          <div id="form">
            <p>
              <label for="title">Incident title</label><br/>
              <input type="text" name="title" id="title" />
            </p>
            <p>
              <label for="users">Incident responders</label><br/>
              <small>
                Please enter a comma-separated list of email addresses of the users
                that should be added to the space.
                Do not include <?= getUserEmail() ?> as it will be added automatically.
              </small><br/>
              <input type="text" name="users" id="users" />
            </p>
            <p>
              <label for="description">Initial message</label></br>
              <small>This message will be posted after the space is created.</small><br/>
              <textarea name="description" id="description"></textarea>
            </p>
            <p class="text-center">
              <input type="submit" value="CREATE CHAT SPACE" />
            </p>
          </div>
          <div id="output" class="hidden"></div>
          <div id="clear" class="hidden">
            <input type="reset" value="CREATE ANOTHER INCIDENT" onclick="onReset()" />
          </div>
        </form>
      </div>
    </div>
    <?!= include('JavaScript'); ?>
  </body>
</html>
JavaScript.html

Handles form behavior including submits, errors, and clears, for the incident initialization website. It's included into Index.html by the custom include function in WebController.gs .

View JavaScript.html code

apps-script/incident-response-app-auth/JavaScript.html
<script>
  var formDiv = document.getElementById('form');
  var outputDiv = document.getElementById('output');
  var clearDiv = document.getElementById('clear');

  function handleFormSubmit(formObject) {
    event.preventDefault();
    outputDiv.innerHTML = 'Please wait while we create the space...';
    hide(formDiv);
    show(outputDiv);
    google.script.run
      .withSuccessHandler(updateOutput)
      .withFailureHandler(onFailure)
      .handleIncident(formObject);
  }

  function updateOutput(response) {
    var spaceId = response.replace('spaces/', '');
    outputDiv.innerHTML =
      '<p>Space created!</p><p><a href="https://mail.google.com/chat/#chat/space/'
        + spaceId
        + '" target="_blank">Open space</a></p>';
    show(outputDiv);
    show(clearDiv);
  }

  function onFailure(error) {
    outputDiv.innerHTML = 'ERROR: ' + error.message;
    outputDiv.classList.add('error');
    show(outputDiv);
    show(clearDiv);
  }

  function onReset() {
    outputDiv.innerHTML = '';
    outputDiv.classList.remove('error');
    show(formDiv);
    hide(outputDiv);
    hide(clearDiv);
  }

  function hide(element) {
    element.classList.add('hidden');
  }

  function show(element) {
    element.classList.remove('hidden');
  }
</script>
Stylesheet.html

The CSS for the incident initialization website. It's included into Index.html by the custom include function in WebController.gs .

View Stylesheet.html code

apps-script/incident-response-app-auth/Stylesheet.html
<style>
  * {
    box-sizing: border-box;
  }
  body {
    font-family: Roboto, Arial, Helvetica, sans-serif;
  }
  div.container {
    display: flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
  }
  div.content {
    width: 80%;
    max-width: 1000px;
    padding: 1rem;
    border: 1px solid #999;
    border-radius: 0.25rem;
    box-shadow: 0 2px 2px 0 rgba(66, 66, 66, 0.08), 0 2px 4px 2px rgba(66, 66, 66, 0.16);
  }
  h1 {
    text-align: center;
    padding-bottom: 1rem;
    margin: 0 -1rem 1rem -1rem;
    border-bottom: 1px solid #999;
  }
 #output {
    text-align: center;
    min-height: 250px;
  }
  div#clear {
    text-align: center;
    padding-top: 1rem;
    margin: 1rem -1rem 0 -1rem;
    border-top: 1px solid #999;
  }
  input[type=text], textarea {
    width: 100%;
    padding: 1rem 0.5rem;
    margin: 0.5rem 0;
    border: 0;
    border-bottom: 1px solid #999;
    background-color: #f0f0f0;
  }
  textarea {
    height: 5rem;
  }
  small {
    color: #999;
  }
  input[type=submit], input[type=reset] {
    padding: 1rem;
    border: none;
    background-color: #6200ee;
    color: #fff;
    border-radius: 0.25rem;
    width: 25%;
  }
  .hidden {
    display: none;
  }
  .text-center {
    text-align: center;
  }
  .error {
    color: red;
  }
</style>

Find your Cloud project number and ID

  1. In the Google Cloud console, go to your Cloud project.

    Go to Google Cloud console

  2. Click Settings and Utilities > Project settings .

  3. Note the values in the Project number and Project ID fields. You use them in the following sections.

Create the Apps Script project

To create an Apps Script project and connect it with your Cloud project:

  1. Click the following button to open the Respond to incidents with Google Chat Apps Script project.
    Open the project
  2. Click Overview .
  3. On the overview page, click The icon for making a copy Make a copy .
  4. Name your copy of the Apps Script project:

    1. Click Copy of Respond to incidents with Google Chat .

    2. In Project title , type Incident Management Chat app .

    3. Click Rename .

  5. In your copy of the Apps Script project, go to the Consts.gs file and replace YOUR_PROJECT_ID with the ID of your Cloud project.

Set the Apps Script project's Cloud project

  1. In your Apps Script project, click The icon for project settings Project Settings .
  2. Under Google Cloud Platform (GCP) Project , click Change project .
  3. In GCP project number , paste the project number of your Cloud project.
  4. Click Set project . The Cloud project and Apps Script project are now connected.

Create an Apps Script deployment

Now that all the code is in place, deploy the Apps Script project. You use the deployment ID when you configure the Chat app in the Google Cloud.

  1. In Apps Script, open the incident response app's project.

    Go to Apps Script

  2. Click Deploy > New deployment .

  3. If Add-on and Web app aren't already selected, next to Select type , click deployment types The icon for project settings and select Add-on and Web app .

  4. In Description , enter a description for this version, like Complete version of incident management app .

  5. In Execute as , select User accessing the web app

  6. In Who has access , select Anyone within your Workspace organization , where "your Workspace organization" is the name of your Google Workspace organization.

  7. Click Deploy . Apps Script reports successful deployment and provides a deployment ID and a URL for the incident initialization web page.

  8. Make note of the Web app URL to visit later when you start an incident. Copy the Deployment ID . You use this ID while configuring the Chat app in Google Cloud console.

  9. Click Done .

Configure the Chat app in the Google Cloud console

This section shows how to configure the Google Chat API in the Google Cloud console with information about your Chat app, including the ID of the deployment that you just created from your Apps Script project.

  1. In the Google Cloud console, click Menu > More products > Google Workspace > Product Library > Google Chat API > Manage > Configuration .

    Go to Chat API configuration

  2. In App name , type Incident Management .

  3. In Avatar URL , type https://developers.google.com/chat/images/quickstart-app-avatar.png .

  4. In Description , type Responds to incidents. .

  5. Click the Enable Interactive features toggle to the on position.

  6. Under Functionality , select Receive 1:1 messages , Join spaces and group conversations .

  7. Under Connection settings , select Apps Script .

  8. In Deployment ID , paste the Apps Script Deployment ID that you copied earlier from the Apps Script project deployment.

  9. Register a slash command that the fully implemented Chat app uses:

    1. Under Commands , click Add a command .

    2. In Command ID , type 1 .

    3. In Description , type Closes the incident being discussed in the space.

    4. Under Command type , select Slash command .

    5. In Slash command name , type /closeIncident .

    6. Select Opens a dialog .

    7. Click Done . The slash command is registered and listed.

  10. Under Visibility , select Make this Chat app available to specific people and groups in Your Workspace Domain and enter your email address.

  11. Under Logs , select Log errors to Logging .

  12. Click Save . A configuration saved message appears, meaning the app is ready to test.

Receive administrator approval

To receive administrator approval, you must configure the Chat app in the Google Workspace Marketplace SDK.

Configure the Chat app in the Google Workspace Marketplace SDK

To configure the Chat app in the Google Workspace Marketplace SDK, follow these steps:

  1. In the Google Cloud console, go to go to Menu > APIs & Services > Enabled APIs & services > Google Workspace Marketplace SDK > App Configuration .

    Go to App Configuration

  2. Complete the App Configuration page. How you configure your Chat app depends on who your intended audience is and other factors. For help completing the app configuration page, see Configure your app in the Google Workspace Marketplace SDK . For the purposes of this guide, enter the following information:

    1. Under App visibility , select Private .
    2. Under Installation settings , select Admin install .
    3. Under App integrations , select Chat app .
    4. Under OAuth scopes , enter the following scopes:
      • https://www.googleapis.com/auth/chat.app.spaces
      • https://www.googleapis.com/auth/chat.app.memberships
    5. Under Developer information , enter your Developer name , Developer website URL , and Developer email .
    6. Click Save draft .

After configuring the app, update the store listing:

  1. In the Google Cloud console, go to go to Menu > APIs & Services > Enabled APIs & services > Google Workspace Marketplace SDK > Store Listing .
  2. In App details , select Web Development as a Category.
  3. In Graphic Assets , upload applications icons in requested formats.
  4. In Screenshots , upload a screenshot of the application.
  5. In Support Links , populate a Terms of Service URL, Privacy URL and Support URL.
  6. In Distribution , Select the regions where this application will be available.
  7. Click Publish .

Get administrator approval

Now that your service account is configured to receive administrator approval, obtain it from a Google Workspace administrator who can grant approval by following the steps in Set up authorization for Chat apps .

Test the Chat app

To test the incident management Chat app, initiate an incident from the web page and verify that the Chat app works as expected:

  1. Go to the Apps Script deployment web app URL.

  2. When Apps Script asks permission to access your data, click Review permissions , sign in with an appropriate Google Account in your Google Workspace domain, and click Allow .

  3. The incident initialization web page opens. Enter test information:

    1. In Incident title , type The First Incident .
    2. Optionally, in Incident responders , enter the email addresses of your fellow incident responders. They must be users with a Google Chat account in your Google Workspace organization or space creation fails. Don't enter your own email address because it's included automatically.
    3. In Initial message , type Testing the incident management Chat app.
  4. Click Create Chat Space . A creating space message appears.

  5. After the space is created, a Space created! message appears. Click Open space , which opens the space in Chat in a new tab.

  6. Optionally, you and the other incident responders can send messages in the space. The app summarizes these messages using Vertex AI and shares a retrospective document.

  7. To end the incident response and begin the resolution process, in the Chat space, type /closeIncident . An incident management dialog opens.

  8. In Close incident , enter a description for the incident resolution, like Test complete .

  9. Click Close Incident .

The Incident Management app lists the messages in the space, summarizes them with Vertex AI, pastes the summary in a Google Docs document, and shares the document in the space.

Очистить

To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, we recommend that you delete the Cloud project.

  1. In the Google Cloud console, go to the Manage resources page. Click Menu > IAM & Admin > Manage Resources .

    Go to Resource Manager

  2. In the project list, select the project you want to delete and then click Delete .
  3. In the dialog, type the project ID and then click Shut down to delete the project.
,

This tutorial uses authorization scopes that begins with https://www.googleapis.com/auth/chat.app.* , which are available as part of a Developer Preview, your Chat app must get a one-time administrator approval .

This tutorial shows how to make a Google Chat app that responds to incidents in real time. When responding to an incident, the app creates and populates a Chat space, facilitates incident resolution with messages, slash commands, and dialogs, and uses AI to summarize the incident response in a Google Docs document.

An incident is an event that requires the immediate attention of a team of people to resolve. Examples of incidents include:

  • A time-sensitive case is created in a Customer Relationship Management (CRM) platform, requiring a service team to collaborate on a resolution.
  • A system goes offline, alerting a group of site reliability engineers (SREs) so that they can work together to bring it back online.
  • A high magnitude earthquake occurs, and emergency workers need to coordinate their response.

For the purposes of this tutorial, the incident alert starts when someone reports the incident with a button click from a web page. The web page simulates an incident by asking users to enter basic incident information: title, description, and email addresses of the responders.

See the incident management Chat app in action:

  • The website that starts an incident.
    Figure 1. The website where someone can report an incident.
  • Notification that the incident Chat space is created.
    Figure 2. Notification that the incident Chat space is created.
  • The incident response Chat space.
    Figure 3. The incident response Chat space.
  • Resolving the incident with a slash command.
    Figure 4. Resolving the incident with a slash command.
  • Incident resolution dialog.
    Figure 5. Incident resolution dialog.
  • Incident resolution Google Docs document shared in space.
    Figure 6. Incident resolution Google Docs document shared in space.
  • The AI summary incident resolution Google Doc.
    Figure 7. The AI summary incident resolution Google Docs document.

Предварительные условия

If you need any of these prerequisites turned on for your organization, ask your Google Workspace administrator to turn them on:

  • A Business or Enterprise Google Workspace account with access to Google Chat .
  • To have Directory (contact sharing) turned on for Google Workspace. The incident app uses the directory to look up the incident responders' contact info, like name and email address. Incident responders must be users with a Google Chat account in your Google Workspace organization.

Цели

  • Build a Chat app that responds to incidents.
  • Help users respond to incidents by doing the following:
    • Creating incident response spaces.
    • Posting messages summarizing incidents and responses.
    • Supporting collaboration with interactive Chat app features.
  • Summarize conversations and resolutions with Vertex AI.

Архитектура

The following diagram shows the architecture of the Google Workspace and Google Cloud resources used by the incident response Google Chat app.

Architecture of the incident response Google Chat app

The architecture shows how the incident response Google Chat app processes an incident and resolution.

  1. A user starts an incident from an external website hosted on Apps Script.

  2. The website sends an asynchronous HTTP request to the Google Chat app, also hosted on Apps Script.

  3. The incident response Google Chat app processes the request:

    1. The Apps Script Admin SDK service gets team member information, like user ID and email address.

    2. With a set of HTTP requests to Chat API using the Apps Script Advanced Chat service, the incident response Google Chat app creates an incident Chat space, populates it with team members, and sends a message to the space.

  4. Team members discuss the incident in the Chat space.

  5. A team member invokes a slash command to signal a resolution to the incident.

    1. An HTTP call to Chat API using the Apps Script Advanced Chat service lists all the Chat space's messages.

    2. Vertex AI receives the listed messages and generates a summary.

    3. The Apps Script DocumentApp service creates a Docs document and adds Vertex AI's summary to the document.

    4. The incident response Google Chat app calls Chat API to send a message sharing a link to the summary Docs document.

Prepare the environment

This section shows how to create and configure a Google Cloud project for the Chat app.

Create a Google Cloud project

Google Cloud console

  1. In the Google Cloud console, go to Menu > IAM & Admin > Create a Project .

    Go to Create a Project

  2. In the Project Name field, enter a descriptive name for your project.

    Optional: To edit the Project ID , click Edit . The project ID can't be changed after the project is created, so choose an ID that meets your needs for the lifetime of the project.

  3. In the Location field, click Browse to display potential locations for your project. Then, click Select .
  4. Click Create . The Google Cloud console navigates to the Dashboard page and your project is created within a few minutes.

gcloud CLI

In one of the following development environments, access the Google Cloud CLI ( gcloud ):

  • Cloud Shell : To use an online terminal with the gcloud CLI already set up, activate Cloud Shell.
    Activate Cloud Shell
  • Local Shell : To use a local development environment, install and initialize the gcloud CLI.
    To create a Cloud project, use the gcloud projects create command:
    gcloud projects create PROJECT_ID
    Replace PROJECT_ID by setting the ID for the project you want to create.

Enable billing for the Cloud project

Google Cloud console

  1. In the Google Cloud console, go to Billing . Click Menu > Billing > My Projects .

    Go to Billing for My Projects

  2. In Select an organization , choose the organization associated with your Google Cloud project.
  3. In the project row, open the Actions menu ( ), click Change billing , and choose the Cloud Billing account.
  4. Click Set account .

gcloud CLI

  1. To list available billing accounts, run:
    gcloud billing accounts list
  2. Link a billing account with a Google Cloud project:
    gcloud billing projects link PROJECT_ID --billing-account=BILLING_ACCOUNT_ID

    Replace the following:

    • PROJECT_ID is the Project ID for the Cloud project for which you want to enable billing.
    • BILLING_ACCOUNT_ID is the billing account ID to link with the Google Cloud project.

Enable the APIs

Google Cloud console

  1. In the Google Cloud console, enable the Google Chat API, the Google Docs API, the Admin SDK API, the Google Workspace Marketplace SDK, and the Vertex AI API.

    Enable the APIs

  2. Confirm that you're enabling the APIs in the correct Cloud project, then click Next .

  3. Confirm that you're enabling the correct APIs, then click Enable .

gcloud CLI

  1. If necessary, set the current Cloud project to the one you created with the gcloud config set project command:

    gcloud config set project PROJECT_ID

    Replace PROJECT_ID with the Project ID of the Cloud project you created.

  2. Enable the Google Chat API, Google Docs API, Admin SDK API, Google Workspace Marketplace SDK, and Vertex AI API with the gcloud services enable command:

    gcloud services enable chat.googleapis.com docs.googleapis.com admin.googleapis.com aiplatform.googleapis.com appsmarket-component.googleapis.com

Set up authentication and authorization

The Chat app accesses Google Chat API using the Chat app's credentials. The app accesses the Admin SDK API and Google Docs API with user credentials.

Set up user authentication and authorization

Authentication and authorization lets the Chat app access resources in Google Workspace and Google Cloud to process an incident response. specifically, user authentication is used to call Google Docs API and Admin SDK API.

In this tutorial, you publish the app internally to your Workspace domain, so it's acceptable to use placeholder information. Before publishing the app externally, replace placeholder information with real information in the consent screen.

  1. In the Google Cloud console, go to Menu > > Branding .

    Go to Branding

  2. If you have already configured the, you can configure the following OAuth Consent Screen settings in Branding , Audience , and Data Access . If you see a message that says not configured yet , click Get Started :

    1. Under App Information , in App name , type Incident Management .
    2. In User support email , select your email address or an appropriate Google group.
    3. Нажмите Далее .
    4. Under Audience , select Internal . If you can't select Internal , select External .
    5. Нажмите Далее .
    6. Under Contact Information , enter an Email address where you can be notified about any changes to your project.
    7. Нажмите Далее .
    8. Under Finish , review the Google API Services User Data Policy and if you agree, select I agree to the Google API Services: User Data Policy .
    9. Click Continue .
    10. Click Create .
    11. If you selected External for user type, add test users:
      1. Click Audience .
      2. Under Test users , click Add users .
      3. Enter your email address and any other authorized test users, then click Save .
  3. Click Data Access > Add or Remove Scopes . A panel appears with a list of scopes for each API that you've enabled in your Google Cloud project.

    1. Under Manually add scopes , paste the following scopes:

      • https://www.googleapis.com/auth/documents
      • https://www.googleapis.com/auth/admin.directory.user.readonly
      • https://www.googleapis.com/auth/script.external_request
      • https://www.googleapis.com/auth/userinfo.email
      • https://www.googleapis.com/auth/cloud-platform
    2. Click Add to Table .

    3. Click Update .

    4. After selecting the scopes required by your app, on the Data Access page, click Save .

Set up app authentication and authorization

App Authentication is used to call Google Chat API.

Create a service account in Google Cloud console

To create a service account, follow these steps:

Google Cloud console

  1. In the Google Cloud console, go to Menu > IAM & Admin > Service Accounts .

    Go to Service Accounts

  2. Click Create service account .
  3. Fill in the service account details, then click Create and continue .
  4. Optional: Assign roles to your service account to grant access to your Google Cloud project's resources. For more details, refer to Granting, changing, and revoking access to resources .
  5. Click Continue .
  6. Optional: Enter users or groups that can manage and perform actions with this service account. For more details, refer to Managing service account impersonation .
  7. Click Done . Make a note of the email address for the service account.

gcloud CLI

  1. Create the service account:
    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name="SERVICE_ACCOUNT_NAME"
  2. Optional: Assign roles to your service account to grant access to your Google Cloud project's resources. For more details, refer to Granting, changing, and revoking access to resources .

The service account appears on the service account page. Next, create a private key for the service account.

Create a private key

To create and download a private key for the service account, follow these steps:

  1. In the Google Cloud console, go to Menu > IAM & Admin > Service Accounts .

    Go to Service Accounts

  2. Select your service account.
  3. Click Keys > Add key > Create new key .
  4. Select JSON , then click Create .

    Your new public/private key pair is generated and downloaded to your machine as a new file. Save the downloaded JSON file as credentials.json in your working directory. This file is the only copy of this key. For information about how to store your key securely, see Managing service account keys .

  5. Click Close .

For more information about service accounts, see service accounts in the Google Cloud IAM documentation.

Create a Google Workspace Marketplace-compatible OAuth client

To create a Google Workspace Marketplace-compatible OAuth client, follow these steps:

  1. In the Google Cloud console, go to Menu > IAM & Admin > Service Accounts .

    Go to Service Accounts

  2. Click the service account you created for your Chat app.

  3. Click Advanced settings .

  4. Click Create Google Workspace Marketplace-compatible OAuth client .

  5. Click Continue .

A confirmation message appears that says a Google Workspace Marketplace-compatible OAuth client has been created.

Create and deploy the Chat app

In the following section, you copy and update an entire Apps Script project that contains all the required application code for your Chat app, so there's no need to copy and paste each file.

Some functions include underscores at the end of their names, like processSlashCommand_() from ChatApp.gs . The underscore hides the function from the incident initialization web page when it's open in a browser. For more information, see Private functions .

Apps Script supports two file types, .gs scripts and .html files. To abide by this support, the app's client-side JavaScript is included inside <script /> tags and its CSS is included inside <style /> tags inside an HTML file.

Optionally, you can view the entire project on GitHub.

View on GitHub

Here's an overview of each file:

Consts.gs

Defines constants referenced by other code files, including your Cloud project ID, Vertex AI location ID, app credentials for the service account and the slash command ID for closing an incident.

View Consts.gs code

apps-script/incident-response-app-auth/Consts.gs
const PROJECT_ID = 'replace-with-your-project-id';
const CLOSE_INCIDENT_COMMAND_ID = 1;
const APP_CREDENTIALS = 'replace-with-your-app-credentials';
const APP_CREDENTIALS_SCOPES = 'https://www.googleapis.com/auth/chat.bot https://www.googleapis.com/auth/chat.app.memberships https://www.googleapis.com/auth/chat.app.spaces.create';
const VERTEX_AI_LOCATION_ID = 'us-central1';
const MODEL_ID = 'gemini-1.5-flash-002';
ChatApp.gs

Handles Chat interaction events, including messages, card clicks, slash commands, and dialogs. Responds to the /closeIncident slash command by opening a dialog to gather incident resolution details. Reads messages in the space by calling the spaces.messages.list method in the Chat API. Gets user IDs using the Admin SDK Directory service in Apps Script.

View ChatApp.gs code

apps-script/incident-response-app-auth/ChatApp.gs
/**
 * Responds to a MESSAGE event in Google Chat.
 *
 * This app only responds to a slash command with the ID 1 ("/closeIncident").
 * It will respond to any other message with a simple "Hello" text message.
 *
 * @param {Object} event the event object from Google Chat
 */
function onMessage(event) {
  if (event.message.slashCommand) {
    return processSlashCommand_(event);
  }
  return { "text": "Hello from Incident Response app!" };
}

/**
 * Responds to a CARD_CLICKED event in Google Chat.
 *
 * This app only responds to one kind of dialog (Close Incident).
 *
 * @param {Object} event the event object from Google Chat
 */
function onCardClick(event) {
  if (event.isDialogEvent) {
    if (event.dialogEventType == 'SUBMIT_DIALOG') {
      return processSubmitDialog_(event);
    }
    return {
      actionResponse: {
        type: "DIALOG",
        dialogAction: {
          actionStatus: "OK"
        }
      }
    };
  }
}

/**
 * Responds to a MESSAGE event with a Slash command in Google Chat.
 *
 * This app only responds to a slash command with the ID 1 ("/closeIncident")
 * by returning a Dialog.
 *
 * @param {Object} event the event object from Google Chat
 */
function processSlashCommand_(event) {
  if (event.message.slashCommand.commandId != CLOSE_INCIDENT_COMMAND_ID) {
    return {
      "text": "Command not recognized. Use the command `/closeIncident` to close the incident managed by this space."
    };
  }
  const sections = [
    {
      header: "Close Incident",
      widgets: [
        {
          textInput: {
            label: "Please describe the incident resolution",
            type: "MULTIPLE_LINE",
            name: "description"
          }
        },
        {
          buttonList: {
            buttons: [
              {
                text: "Close Incident",
                onClick: {
                  action: {
                    function: "closeIncident"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  ];
  return {
    actionResponse: {
      type: "DIALOG",
      dialogAction: {
        dialog: {
          body: {
            sections,
          }
        }
      }
    }
  };
}

/**
 * Responds to a CARD_CLICKED event with a Dialog submission in Google Chat.
 *
 * This app only responds to one kind of dialog (Close Incident).
 * It creates a Doc with a summary of the incident information and posts a message
 * to the space with a link to the Doc.
 *
 * @param {Object} event the event object from Google Chat
 */
function processSubmitDialog_(event) {
  const resolution = event.common.formInputs.description[""].stringInputs.value[0];
  const chatHistory = concatenateAllSpaceMessages_(event.space.name);
  const chatSummary = summarizeChatHistory_(chatHistory);
  const docUrl = createDoc_(event.space.displayName, resolution, chatHistory, chatSummary);
  return {
    actionResponse: {
      type: "NEW_MESSAGE",
    },
    text: `Incident closed with the following resolution: ${resolution}\n\nHere is the automatically generated post-mortem:\n${docUrl}`
  };
}

/**
 * Lists all the messages in the Chat space, then concatenate all of them into
 * a single text containing the full Chat history.
 *
 * For simplicity for this demo, it only fetches the first 100 messages.
 *
 * Messages with slash commands are filtered out, so the returned history will
 * contain only the conversations between users and not app command invocations.
 *
 * @return {string} a text containing all the messages in the space in the format:
 *          Sender's name: Message
 */
function concatenateAllSpaceMessages_(spaceName) {
  // Call Chat API method spaces.messages.list
  const response = Chat.Spaces.Messages.list(spaceName, { 'pageSize': 100 });
  const messages = response.messages;
  // Fetch the display names of the message senders and returns a text
  // concatenating all the messages.
  let userMap = new Map();
  return messages
    .filter(message => message.slashCommand === undefined)
    .map(message => `${getUserDisplayName_(userMap, message.sender.name)}: ${message.text}`)
    .join('\n');
}

/**
 * Obtains the display name of a user by using the Admin Directory API.
 *
 * The fetched display name is cached in the provided map, so we only call the API
 * once per user.
 *
 * If the user does not have a display name, then the full name is used.
 *
 * @param {Map} userMap a map containing the display names previously fetched
 * @param {string} userName the resource name of the user
 * @return {string} the user's display name
 */
function getUserDisplayName_(userMap, userName) {
  if (userMap.has(userName)) {
    return userMap.get(userName);
  }
  let displayName = 'Unknown User';
  try {
    const user = AdminDirectory.Users.get(
      userName.replace("users/", ""),
      { projection: 'BASIC', viewType: 'domain_public' });
    displayName = user.name.displayName ? user.name.displayName : user.name.fullName;
  } catch (e) {
    // Ignore error if the API call fails (for example, because it's an
    // out-of-domain user or Chat app)) and just use 'Unknown User'.
  }
  userMap.set(userName, displayName);
  return displayName;
}
ChatSpaceCreator.gs

Receives form data users enter on the incident initialization web page, and uses it to set up a Chat space by creating and populating it, and then posts a message about the incident.

View ChatSpaceCreator.gs code

apps-script/incident-response-app-auth/ChatSpaceCreator.gs
/**
 * Handles an incident by creating a chat space, adding members, and posting a message.
 * All the actions are done using application credentials.
 *
 * @param {Object} formData - The data submitted by the user. It should contain the fields:
 *                           - title: The display name of the chat space.
 *                           - description: The description of the incident.
 *                           - users: A comma-separated string of user emails to be added to the space.
 * @return {string} The resource name of the new space.
 */
function handleIncident(formData) {
  const users = formData.users.trim().length > 0 ? formData.users.split(',') : [];
  const service = getService_();
  if (!service.hasAccess()) {
    console.error(service.getLastError());
    return;
   }
  const spaceName = createChatSpace_(formData.title, service);
  createHumanMembership_(spaceName, getUserEmail(), service);
  for (const user of users ){
    createHumanMembership_(spaceName, user, service);
  }
  createMessage_(spaceName, formData.description, service);
  return spaceName;
}
/**
 * Creates a chat space with application credentials.
 *
 * @param {string} displayName - The name of the chat space.
 * @param {object} service - The credentials of the service account.
 * @returns {string} The resource name of the new space.
*/
function createChatSpace_(displayName, service) {
  try {
    // For private apps, the alias can be used
    const my_customer_alias = "customers/my_customer";
    // Specify the space to create.
    const space = {
        displayName: displayName,
        spaceType: 'SPACE',                
        customer: my_customer_alias
    };
    // Call Chat API with a service account to create a message.
    const createdSpace = Chat.Spaces.create(
        space,
        {},
        // Authenticate with the service account token.
        {'Authorization': 'Bearer ' + service.getAccessToken()});
    return createdSpace.name;
  } catch (err) {
    // TODO (developer) - Handle exception.
    console.log('Failed to create space with error %s', err.message);
  }
}
/*
 * Creates a chat message with application credentials.
 *
 * @param {string} spaceName - The resource name of the space.
 * @param {string} message - The text to be posted.
 * @param {object} service - The credentials of the service account.
 * @return {string} the resource name of the new space.
 */
function createMessage_(spaceName, message, service) {
  try {
    // Call Chat API with a service account to create a message.
    const result = Chat.Spaces.Messages.create(
        {'text': message},
        spaceName,
        {},
        // Authenticate with the service account token.
        {'Authorization': 'Bearer ' + service.getAccessToken()});

  } catch (err) {
    // TODO (developer) - Handle exception.
    console.log('Failed to create message with error %s', err.message);
  }
}
/**
 * Creates a human membership in a chat space with application credentials.
 *
 * @param {string} spaceName - The resource name of the space.
 * @param {string} email - The email of the user to be added.
 * @param {object} service - The credentials of the service account.
 */
function createHumanMembership_(spaceName, email, service){
  try{
    const membership = {
      member: {
        name: 'users/'+email,
        // User type for the membership
        type: 'HUMAN'
      }
    };
    const result = Chat.Spaces.Members.create(
      membership,
      spaceName,
      {},
      {'Authorization': 'Bearer ' + service.getAccessToken()}
    );
  } catch (err){
    console.log('Failed to create membership with error %s', err.message)
  }

}

 /*
 * Creates a service for the service account.
 * @return {object}  - The credentials of the service account.
 */
function getService_() {
  return OAuth2.createService(APP_CREDENTIALS.client_email)
      .setTokenUrl('https://oauth2.googleapis.com/token')
      .setPrivateKey(APP_CREDENTIALS.private_key)
      .setIssuer(APP_CREDENTIALS.client_email)
      .setSubject(APP_CREDENTIALS.client_email)
      .setScope(APP_CREDENTIALS_SCOPES)
      .setPropertyStore(PropertiesService.getScriptProperties());
}
DocsApi.gs

Calls the Google Docs API to create a Google Docs document in a user's Google Drive and writes a summary of the incident information, created in VertexAiApi.gs , to the document.

View DocsApi.gs code

apps-script/incident-response-app-auth/DocsApi.gs
/**
 * Creates a Doc in the user's Google Drive and writes a summary of the incident information to it.
 *
 * @param {string} title The title of the incident
 * @param {string} resolution Incident resolution described by the user
 * @param {string} chatHistory The whole Chat history be included in the document
 * @param {string} chatSummary A summary of the Chat conversation to be included in the document
 * @return {string} the URL of the created Doc
 */
function createDoc_(title, resolution, chatHistory, chatSummary) {
  let doc = DocumentApp.create(title);
  let body = doc.getBody();
  body.appendParagraph(`Post-Mortem: ${title}`).setHeading(DocumentApp.ParagraphHeading.TITLE);
  body.appendParagraph("Resolution").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(resolution);
  body.appendParagraph("Summary of the conversation").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(chatSummary);
  body.appendParagraph("Full Chat history").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(chatHistory);
  return doc.getUrl();
}
VertexAiApi.gs

Summarizes the conversation in the Chat space using Vertex AI API. This summary is posted in a specially-created document in DocsAPI.gs .

View VertexAiApi.gs code

apps-script/incident-response-app-auth/VertexAiApi.gs
/**
 * Summarizes a Chat conversation using the Vertex AI text prediction API.
 *
 * @param {string} chatHistory The Chat history that will be summarized.
 * @return {string} The content from the text prediction response.
 */


function summarizeChatHistory_(chatHistory) {

  const API_ENDPOINT = `https://${VERTEX_AI_LOCATION_ID}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${VERTEX_AI_LOCATION_ID}/publishers/google/models/${MODEL_ID}:generateContent`;
  const prompt = "Summarize the following conversation between Engineers resolving an incident"
      + " in a few sentences. Use only the information from the conversation.\n\n" + chatHistory;
  // Get the access token.
  const accessToken = ScriptApp.getOAuthToken();

  const headers = {
    'Authorization': 'Bearer ' + accessToken,
    'Content-Type': 'application/json',
  };
  const payload = {
    'contents': {
      'role': 'user',
      'parts' : [
        {
          'text': prompt
        }
      ]
    }
  }
  const options = {
    'method': 'post',
    'headers': headers,
    'payload': JSON.stringify(payload),
    'muteHttpExceptions': true,
  };
  try {
    const response = UrlFetchApp.fetch(API_ENDPOINT, options);
    const responseCode = response.getResponseCode();
    const responseText = response.getContentText();

    if (responseCode === 200) {
      const jsonResponse = JSON.parse(responseText);
      console.log(jsonResponse)
      if (jsonResponse.candidates && jsonResponse.candidates.length > 0) {
        return jsonResponse.candidates[0].content.parts[0].text; // Access the summarized text
      } else {
        return "No summary found in response.";
      }

    } else {
      console.error("Vertex AI API Error:", responseCode, responseText);
      return `Error: ${responseCode} - ${responseText}`;
    }
  } catch (e) {
    console.error("UrlFetchApp Error:", e);
    return "Error: " + e.toString();
  }
}
WebController.gs

Serves the incident initialization website.

View WebController.gs code

apps-script/incident-response-app-auth/WebController.gs
/**
 * Serves the web page from Index.html.
 */
function doGet() {
  return HtmlService
    .createTemplateFromFile('Index')
    .evaluate();
}

/**
 * Serves the web content from the specified filename.
 */
function include(filename) {
  return HtmlService
    .createHtmlOutputFromFile(filename)
    .getContent();
}

/**
 * Returns the email address of the user running the script.
 */
function getUserEmail() {
  return Session.getActiveUser().getEmail();
}
Index.html

The HTML comprising the incident initialization website.

View Index.html code

apps-script/incident-response-app-auth/Index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
    <?!= include('Stylesheet'); ?>
  </head>
  <body>
    <div class="container">
      <div class="content">
        <h1>Incident Manager</h1>
        <form id="incident-form" onsubmit="handleFormSubmit(this)">
          <div id="form">
            <p>
              <label for="title">Incident title</label><br/>
              <input type="text" name="title" id="title" />
            </p>
            <p>
              <label for="users">Incident responders</label><br/>
              <small>
                Please enter a comma-separated list of email addresses of the users
                that should be added to the space.
                Do not include <?= getUserEmail() ?> as it will be added automatically.
              </small><br/>
              <input type="text" name="users" id="users" />
            </p>
            <p>
              <label for="description">Initial message</label></br>
              <small>This message will be posted after the space is created.</small><br/>
              <textarea name="description" id="description"></textarea>
            </p>
            <p class="text-center">
              <input type="submit" value="CREATE CHAT SPACE" />
            </p>
          </div>
          <div id="output" class="hidden"></div>
          <div id="clear" class="hidden">
            <input type="reset" value="CREATE ANOTHER INCIDENT" onclick="onReset()" />
          </div>
        </form>
      </div>
    </div>
    <?!= include('JavaScript'); ?>
  </body>
</html>
JavaScript.html

Handles form behavior including submits, errors, and clears, for the incident initialization website. It's included into Index.html by the custom include function in WebController.gs .

View JavaScript.html code

apps-script/incident-response-app-auth/JavaScript.html
<script>
  var formDiv = document.getElementById('form');
  var outputDiv = document.getElementById('output');
  var clearDiv = document.getElementById('clear');

  function handleFormSubmit(formObject) {
    event.preventDefault();
    outputDiv.innerHTML = 'Please wait while we create the space...';
    hide(formDiv);
    show(outputDiv);
    google.script.run
      .withSuccessHandler(updateOutput)
      .withFailureHandler(onFailure)
      .handleIncident(formObject);
  }

  function updateOutput(response) {
    var spaceId = response.replace('spaces/', '');
    outputDiv.innerHTML =
      '<p>Space created!</p><p><a href="https://mail.google.com/chat/#chat/space/'
        + spaceId
        + '" target="_blank">Open space</a></p>';
    show(outputDiv);
    show(clearDiv);
  }

  function onFailure(error) {
    outputDiv.innerHTML = 'ERROR: ' + error.message;
    outputDiv.classList.add('error');
    show(outputDiv);
    show(clearDiv);
  }

  function onReset() {
    outputDiv.innerHTML = '';
    outputDiv.classList.remove('error');
    show(formDiv);
    hide(outputDiv);
    hide(clearDiv);
  }

  function hide(element) {
    element.classList.add('hidden');
  }

  function show(element) {
    element.classList.remove('hidden');
  }
</script>
Stylesheet.html

The CSS for the incident initialization website. It's included into Index.html by the custom include function in WebController.gs .

View Stylesheet.html code

apps-script/incident-response-app-auth/Stylesheet.html
<style>
  * {
    box-sizing: border-box;
  }
  body {
    font-family: Roboto, Arial, Helvetica, sans-serif;
  }
  div.container {
    display: flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
  }
  div.content {
    width: 80%;
    max-width: 1000px;
    padding: 1rem;
    border: 1px solid #999;
    border-radius: 0.25rem;
    box-shadow: 0 2px 2px 0 rgba(66, 66, 66, 0.08), 0 2px 4px 2px rgba(66, 66, 66, 0.16);
  }
  h1 {
    text-align: center;
    padding-bottom: 1rem;
    margin: 0 -1rem 1rem -1rem;
    border-bottom: 1px solid #999;
  }
 #output {
    text-align: center;
    min-height: 250px;
  }
  div#clear {
    text-align: center;
    padding-top: 1rem;
    margin: 1rem -1rem 0 -1rem;
    border-top: 1px solid #999;
  }
  input[type=text], textarea {
    width: 100%;
    padding: 1rem 0.5rem;
    margin: 0.5rem 0;
    border: 0;
    border-bottom: 1px solid #999;
    background-color: #f0f0f0;
  }
  textarea {
    height: 5rem;
  }
  small {
    color: #999;
  }
  input[type=submit], input[type=reset] {
    padding: 1rem;
    border: none;
    background-color: #6200ee;
    color: #fff;
    border-radius: 0.25rem;
    width: 25%;
  }
  .hidden {
    display: none;
  }
  .text-center {
    text-align: center;
  }
  .error {
    color: red;
  }
</style>

Find your Cloud project number and ID

  1. In the Google Cloud console, go to your Cloud project.

    Go to Google Cloud console

  2. Click Settings and Utilities > Project settings .

  3. Note the values in the Project number and Project ID fields. You use them in the following sections.

Create the Apps Script project

To create an Apps Script project and connect it with your Cloud project:

  1. Click the following button to open the Respond to incidents with Google Chat Apps Script project.
    Open the project
  2. Click Overview .
  3. On the overview page, click The icon for making a copy Make a copy .
  4. Name your copy of the Apps Script project:

    1. Click Copy of Respond to incidents with Google Chat .

    2. In Project title , type Incident Management Chat app .

    3. Click Rename .

  5. In your copy of the Apps Script project, go to the Consts.gs file and replace YOUR_PROJECT_ID with the ID of your Cloud project.

Set the Apps Script project's Cloud project

  1. In your Apps Script project, click The icon for project settings Project Settings .
  2. Under Google Cloud Platform (GCP) Project , click Change project .
  3. In GCP project number , paste the project number of your Cloud project.
  4. Click Set project . The Cloud project and Apps Script project are now connected.

Create an Apps Script deployment

Now that all the code is in place, deploy the Apps Script project. You use the deployment ID when you configure the Chat app in the Google Cloud.

  1. In Apps Script, open the incident response app's project.

    Go to Apps Script

  2. Click Deploy > New deployment .

  3. If Add-on and Web app aren't already selected, next to Select type , click deployment types The icon for project settings and select Add-on and Web app .

  4. In Description , enter a description for this version, like Complete version of incident management app .

  5. In Execute as , select User accessing the web app

  6. In Who has access , select Anyone within your Workspace organization , where "your Workspace organization" is the name of your Google Workspace organization.

  7. Click Deploy . Apps Script reports successful deployment and provides a deployment ID and a URL for the incident initialization web page.

  8. Make note of the Web app URL to visit later when you start an incident. Copy the Deployment ID . You use this ID while configuring the Chat app in Google Cloud console.

  9. Click Done .

Configure the Chat app in the Google Cloud console

This section shows how to configure the Google Chat API in the Google Cloud console with information about your Chat app, including the ID of the deployment that you just created from your Apps Script project.

  1. In the Google Cloud console, click Menu > More products > Google Workspace > Product Library > Google Chat API > Manage > Configuration .

    Go to Chat API configuration

  2. In App name , type Incident Management .

  3. In Avatar URL , type https://developers.google.com/chat/images/quickstart-app-avatar.png .

  4. In Description , type Responds to incidents. .

  5. Click the Enable Interactive features toggle to the on position.

  6. Under Functionality , select Receive 1:1 messages , Join spaces and group conversations .

  7. Under Connection settings , select Apps Script .

  8. In Deployment ID , paste the Apps Script Deployment ID that you copied earlier from the Apps Script project deployment.

  9. Register a slash command that the fully implemented Chat app uses:

    1. Under Commands , click Add a command .

    2. In Command ID , type 1 .

    3. In Description , type Closes the incident being discussed in the space.

    4. Under Command type , select Slash command .

    5. In Slash command name , type /closeIncident .

    6. Select Opens a dialog .

    7. Click Done . The slash command is registered and listed.

  10. Under Visibility , select Make this Chat app available to specific people and groups in Your Workspace Domain and enter your email address.

  11. Under Logs , select Log errors to Logging .

  12. Click Save . A configuration saved message appears, meaning the app is ready to test.

Receive administrator approval

To receive administrator approval, you must configure the Chat app in the Google Workspace Marketplace SDK.

Configure the Chat app in the Google Workspace Marketplace SDK

To configure the Chat app in the Google Workspace Marketplace SDK, follow these steps:

  1. In the Google Cloud console, go to go to Menu > APIs & Services > Enabled APIs & services > Google Workspace Marketplace SDK > App Configuration .

    Go to App Configuration

  2. Complete the App Configuration page. How you configure your Chat app depends on who your intended audience is and other factors. For help completing the app configuration page, see Configure your app in the Google Workspace Marketplace SDK . For the purposes of this guide, enter the following information:

    1. Under App visibility , select Private .
    2. Under Installation settings , select Admin install .
    3. Under App integrations , select Chat app .
    4. Under OAuth scopes , enter the following scopes:
      • https://www.googleapis.com/auth/chat.app.spaces
      • https://www.googleapis.com/auth/chat.app.memberships
    5. Under Developer information , enter your Developer name , Developer website URL , and Developer email .
    6. Click Save draft .

After configuring the app, update the store listing:

  1. In the Google Cloud console, go to go to Menu > APIs & Services > Enabled APIs & services > Google Workspace Marketplace SDK > Store Listing .
  2. In App details , select Web Development as a Category.
  3. In Graphic Assets , upload applications icons in requested formats.
  4. In Screenshots , upload a screenshot of the application.
  5. In Support Links , populate a Terms of Service URL, Privacy URL and Support URL.
  6. In Distribution , Select the regions where this application will be available.
  7. Click Publish .

Get administrator approval

Now that your service account is configured to receive administrator approval, obtain it from a Google Workspace administrator who can grant approval by following the steps in Set up authorization for Chat apps .

Test the Chat app

To test the incident management Chat app, initiate an incident from the web page and verify that the Chat app works as expected:

  1. Go to the Apps Script deployment web app URL.

  2. When Apps Script asks permission to access your data, click Review permissions , sign in with an appropriate Google Account in your Google Workspace domain, and click Allow .

  3. The incident initialization web page opens. Enter test information:

    1. In Incident title , type The First Incident .
    2. Optionally, in Incident responders , enter the email addresses of your fellow incident responders. They must be users with a Google Chat account in your Google Workspace organization or space creation fails. Don't enter your own email address because it's included automatically.
    3. In Initial message , type Testing the incident management Chat app.
  4. Click Create Chat Space . A creating space message appears.

  5. After the space is created, a Space created! message appears. Click Open space , which opens the space in Chat in a new tab.

  6. Optionally, you and the other incident responders can send messages in the space. The app summarizes these messages using Vertex AI and shares a retrospective document.

  7. To end the incident response and begin the resolution process, in the Chat space, type /closeIncident . An incident management dialog opens.

  8. In Close incident , enter a description for the incident resolution, like Test complete .

  9. Click Close Incident .

The Incident Management app lists the messages in the space, summarizes them with Vertex AI, pastes the summary in a Google Docs document, and shares the document in the space.

Очистить

To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, we recommend that you delete the Cloud project.

  1. In the Google Cloud console, go to the Manage resources page. Click Menu > IAM & Admin > Manage Resources .

    Go to Resource Manager

  2. In the project list, select the project you want to delete and then click Delete .
  3. In the dialog, type the project ID and then click Shut down to delete the project.