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

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

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

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

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

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

Посмотрите, как работает приложение для чата в системе управления инцидентами:

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

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

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

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

Цели

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

Архитектура

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

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

Архитектура демонстрирует, как приложение чата для реагирования на инциденты обрабатывает инцидент и устраняет его.

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

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

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

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

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

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

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

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

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

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

    4. Приложение «Чат» для реагирования на инциденты вызывает API чата для отправки сообщения, содержащего ссылку на сводный документ Docs.

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

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

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

Консоль Google API

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

    Перейдите в раздел «Создать проект».

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

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

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

gcloud CLI

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

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

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

Консоль Google API

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

    Перейдите в раздел «Оплата моих проектов».

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

gcloud CLI

  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 API

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

    Включите API

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

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

gcloud CLI

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

    gcloud config set project PROJECT_ID

    Замените PROJECT_ID на идентификатор проекта Cloud, который вы создали.

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

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

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

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

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

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

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

  1. В консоли Google API перейдите в > Платформа аутентификации Google > Брендинг .

    Перейти к разделу «Брендинг»

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

    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 Cloud.

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

Консоль Google Cloud

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

    Перейдите в раздел «Учетные записи служб».

    Оставшиеся шаги отображаются в консоли Google Cloud.

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

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

gcloud CLI

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

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

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

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

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

    Перейдите в раздел «Учетные записи служб».

    Оставшиеся шаги отображаются в консоли Google Cloud.

  2. Выберите проект Google Cloud.
  3. Щелкните по адресу электронной почты учетной записи службы, для которой вы хотите создать ключ.
  4. Нажмите вкладку « Клавиши» .
  5. Щелкните раскрывающееся меню «Добавить ключ» , затем выберите «Создать новый ключ» .
  6. Выберите JSON в качестве типа ключа и нажмите «Создать» .

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

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

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

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

  1. В консоли Google API перейдите в > IAM и администрирование > Сервисные учетные записи .

    Перейдите в раздел «Учетные записи служб».

  2. Щёлкните по учетной записи службы, которую вы создали для своего приложения «Чат».

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

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

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

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

Создайте и разверните приложение «Чат».

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

Некоторые функции содержат подчеркивания в конце своих имен, например, 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 в 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 Docs для создания документа Docs в 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

Обобщает ход беседы в чате с помощью API Vertex AI. Это резюме публикуется в специально созданном документе в 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 API перейдите к своему проекту в облаке.

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

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

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

Создайте проект Apps Script.

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

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

    1. Нажмите «Копировать» в документе «Реагировать на инциденты с помощью Google Chat» .

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

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

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

Установите проект Cloud для проекта Apps Script.

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

Создайте развертывание Apps Script.

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

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

    Перейдите в раздел Apps Script.

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

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

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

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

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

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

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

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

Настройте приложение «Чат» в консоли Google API.

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

  1. В консоли Google API перейдите > API и сервисы > Включенные API и сервисы > Google Chat API > Конфигурация .

    Перейдите в раздел «Настройка API чата».

  2. Нажмите «Отключить ». Создайте это приложение чата как надстройку для Google Workspace . Откроется диалоговое окно с запросом подтверждения. В диалоговом окне нажмите «Отключить» .

  3. В поле «Название приложения» введите Incident Management .

  4. В поле "URL аватара" введите https://developers.google.com/chat/images/quickstart-app-avatar.png .

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

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

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

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

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

  10. Зарегистрируйте команду со слэшем , которую будет использовать полностью реализованное приложение чата:

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

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

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

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

    5. В командной строке (слэш-команде) введите /closeIncident .

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

    7. Нажмите «Готово» . Команда слэша зарегистрирована и отображается в списке.

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

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

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

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

Для получения подтверждения от администратора необходимо настроить приложение «Чат» в SDK Google Workspace Marketplace.

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

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

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

    Перейдите в раздел «Настройки приложения».

  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 SDK . For the purposes of this guide, enter the following information:

    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, который может предоставить подтверждение, выполнив действия, описанные в разделе «Настройка авторизации для приложений чата» .

Протестируйте приложение для чата

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

  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 API перейдите на страницу «Управление ресурсами» > IAM и администрирование > Управление ресурсами .

    Перейдите в Диспетчер ресурсов

  2. В списке проектов выберите проект, который хотите удалить, и нажмите кнопку «Удалить .
  3. В диалоговом окне введите идентификатор проекта, а затем нажмите «Завершить» , чтобы удалить проект.
  • Приложение для реагирования на инциденты использует учетные данные пользователя для вызова API и обращения к сервисам Google Cloud, таким как Chat API и Vertex AI API. Это означает, что пользователь, инициирующий инцидент, должен иметь доступ к этим сервисам. Для повышения надежности приложения рекомендуется вызывать Vertex AI API с использованием учетной записи службы вместо учетных данных пользователя, выполняющего команду /closeIncident . Инструкции по настройке учетной записи службы для Vertex AI API см. в разделе «Использование пользовательской учетной записи службы» .