Responda a incidentes com o Google Chat, a Vertex AI e o Apps Script

Este tutorial usa escopos de autorização que começam com https://www.googleapis.com/auth/chat.app.*, que estão disponíveis como parte de uma prévia para desenvolvedores. O app Chat precisa receber uma aprovação do administrador única.

Neste tutorial, mostramos como criar um app do Google Chat que responda a incidentes em tempo real. Ao responder a um incidente, o app cria e preenche um espaço do Chat, facilita a resolução de incidentes com mensagens, comandos de barra e caixas de diálogo e usa a IA para resumir a resposta a incidentes em um documento do Documentos Google.

Um incidente é um evento que requer a atenção imediata de uma equipe para ser resolvido. Exemplos de incidentes:

  • Um caso urgente é criado em uma plataforma de gestão de relacionamento com o cliente (CRM), exigindo que uma equipe de serviço colabore para uma resolução.
  • Um sistema fica off-line, alertando um grupo de engenheiros de confiabilidade do site (SREs) para que eles trabalhem juntos e o recoloquem on-line.
  • Um terremoto de grande magnitude ocorre, e os trabalhadores de emergência precisam coordenar a resposta.

Para fins deste tutorial, o alerta de incidente começa quando alguém informa o incidente com um clique em um botão em uma página da Web. A página da Web simula um incidente pedindo aos usuários que insiram informações básicas sobre o incidente: título, descrição e endereços de e-mail dos participantes.

Confira o app do Chat para gerenciamento de incidentes em ação:

  • O site que inicia um incidente.
    Figura 1. O site em que alguém pode denunciar um incidente.
  • Notificação de que o espaço do Chat do incidente foi criado.
    Figura 2. Notificação de que o espaço do Chat do incidente foi criado.
  • O espaço do Chat de resposta a incidentes.
    Figura 3. O espaço de chat de resposta a incidentes.
  • Resolva o incidente com um comando de barra.
    Figura 4. Resolva o incidente com um comando de barra.
  • Caixa de diálogo de resolução de incidentes.
    Figura 5. Caixa de diálogo de resolução de incidentes.
  • Documento do Google Docs de resolução de incidentes compartilhado no espaço.
    Figura 6. Documento do Google Docs de resolução de incidentes compartilhado no espaço.
  • O documento do Google com a resolução do incidente de resumo de IA.
    Figura 7. O documento de resumo do incidente de IA nos Documentos Google.

Pré-requisitos

Se você precisar ativar algum desses pré-requisitos na sua organização, peça ao administrador do Google Workspace para fazer isso:

  • Uma conta do Google Workspace para empresas ou empresas com acesso ao Google Chat.
  • Ative o Diretório (compartilhamento de contatos) no Google Workspace. O app de incidentes usa o diretório para procurar as informações de contato dos respondentes, como nome e endereço de e-mail. Os participantes do incidente precisam ser usuários com uma conta do Google Chat na sua organização do Google Workspace.

Objetivos

  • Crie um app de chat que responda a incidentes.
  • Ajude os usuários a responder a incidentes fazendo o seguinte:
    • Criação de espaços de resposta a incidentes.
    • Publicar mensagens que resumam incidentes e respostas.
    • Suporte à colaboração com recursos interativos do app Chat.
  • Resuma conversas e resoluções com a Vertex AI.

Arquitetura

O diagrama a seguir mostra a arquitetura dos recursos do Google Workspace e do Google Cloud usados pelo app do Google Chat para resposta a incidentes.

Arquitetura do app do Google Chat para resposta a incidentes

A arquitetura mostra como o app do Google Chat de resposta a incidentes processa um incidente e a resolução.

  1. Um usuário inicia um incidente em um site externo hospedado no Apps Script.

  2. O site envia uma solicitação HTTP assíncrona para o app Google Chat, também hospedado no Apps Script.

  3. O app do Google Chat de resposta a incidentes processa a solicitação:

    1. O serviço do SDK Admin do Apps Script recebe informações dos membros da equipe, como ID do usuário e endereço de e-mail.

    2. Com um conjunto de solicitações HTTP para a API Chat usando o serviço avançado de chat do Apps Script, o app Google Chat de resposta a incidentes cria um espaço de chat de incidentes, preenche-o com membros da equipe e envia uma mensagem para o espaço.

  4. Os membros da equipe discutem o incidente no espaço do Chat.

  5. Um membro da equipe invoca um comando de barra para sinalizar uma resolução do incidente.

    1. Uma chamada HTTP para a API Chat usando o serviço de chat avançado do Apps Script lista todas as mensagens do espaço do Chat.

    2. A Vertex AI recebe as mensagens listadas e gera um resumo.

    3. O serviço DocumentApp do Apps Script cria um documento do Documentos e adiciona o resumo da Vertex AI ao documento.

    4. O app de resposta a incidentes do Google Chat chama a API Chat para enviar uma mensagem compartilhando um link para o documento de resumo do Documentos Google.

Prepare o ambiente

Esta seção mostra como criar e configurar um projeto do Google Cloud para o app Chat.

Criar um projeto do Google Cloud

Console do Google Cloud

  1. No console do Google Cloud, acesse Menu > IAM e administrador > Criar um projeto.

    Acessar "Criar um projeto"

  2. No campo Nome do projeto, insira um nome descritivo.

    Opcional: para editar o ID do projeto, clique em Editar. O ID do projeto não pode ser alterado após a criação do projeto. Portanto, escolha um ID que atenda às suas necessidades durante a vida útil do projeto.

  3. No campo Local, clique em Procurar para mostrar possíveis locais para seu projeto. Em seguida, clique em Selecionar.
  4. Clique em Criar. O console do Google Cloud navega até a página "Painel", e seu projeto é criado em alguns minutos.

CLI da gcloud

Em um dos seguintes ambientes de desenvolvimento, acesse a CLI do Google Cloud (gcloud):

  • Cloud Shell: para usar um terminal on-line com a CLI gcloud já configurada, ative o Cloud Shell.
    Ativar o Cloud Shell
  • Shell local: para usar um ambiente de desenvolvimento local, instale e inicialize a CLI gcloud.
    Para criar um projeto do Cloud, use o comando gcloud projects create:
    gcloud projects create PROJECT_ID
    Substitua PROJECT_ID definindo o ID do projeto que você quer criar.

Ativar o faturamento para o projeto do Cloud

Console do Google Cloud

  1. No console do Google Cloud, acesse Faturamento. Clique em Menu > Faturamento > Meus projetos.

    Acessar "Faturamento" em "Meus projetos"

  2. Em Selecionar uma organização, escolha a organização associada ao seu projeto do Google Cloud.
  3. Na linha do projeto, abra o menu Ações (), clique em Alterar faturamento e escolha a conta do Cloud Billing.
  4. Clique em Definir conta.

CLI da gcloud

  1. Para listar as contas de faturamento disponíveis, execute:
    gcloud billing accounts list
  2. Vincular uma conta de faturamento a um projeto do Google Cloud:
    gcloud billing projects link PROJECT_ID --billing-account=BILLING_ACCOUNT_ID

    Substitua:

    • PROJECT_ID é o ID do projeto do projeto do Cloud para o qual você quer ativar o faturamento.
    • BILLING_ACCOUNT_ID é o ID da conta de faturamento a ser vinculado ao projeto do Google Cloud.

Ative as APIs

Console do Google Cloud

  1. No console do Google Cloud, ative a API Google Chat, a API Google Docs, a API Admin SDK, o SDK do Google Workspace Marketplace e a API Vertex AI.

    Ativar as APIs

  2. Confirme que você está ativando as APIs no projeto correto do Cloud e clique em Next.

  3. Confirme se você está ativando as APIs corretas e clique em Ativar.

CLI da gcloud

  1. Se necessário, defina o projeto atual do Cloud como o que você criou com o comando gcloud config set project:

    gcloud config set project PROJECT_ID

    Substitua PROJECT_ID pelo ID do projeto do projeto do Cloud que você criou.

  2. Ative as APIs Google Chat, Google Docs, Admin SDK, Google Workspace Marketplace e Vertex AI com o comando gcloud services enable:

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

Configurar a autenticação e a autorização

O app Chat acessa a API Google Chat usando as credenciais dele. O app acessa a API Admin SDK e a API Google Docs com as credenciais do usuário.

Configurar a autenticação e a autorização do usuário

A autenticação e a autorização permitem que o app Chat acesse recursos no Google Workspace e no Google Cloud para processar uma resposta a incidentes. Especificamente, a autenticação do usuário é usada para chamar a API Google Docs e a API Admin SDK.

Neste tutorial, você publica o app internamente no seu domínio do Workspace. Portanto, é aceitável usar informações de marcador de posição. Antes de publicar o app externamente, substitua as informações de marcador de posição por informações reais na tela de consentimento.

  1. No console do Google Cloud, acesse Menu > > Branding.

    Acessar "Branding"

  2. Se você já tiver configurado o , poderá configurar as seguintes configurações da tela de consentimento do OAuth em Marca, Público-alvo e Acesso a dados. Se aparecer uma mensagem informando que ainda não está configurado, clique em Começar:

    1. Em Informações do app, em Nome do app, digite Incident Management.
    2. Em E-mail para suporte do usuário, selecione seu endereço de e-mail ou um Grupo do Google apropriado.
    3. Clique em Próxima.
    4. Em Público, selecione Interno. Se não for possível selecionar Interno, selecione Externo.
    5. Clique em Próxima.
    6. Em Dados de contato, insira um endereço de e-mail para receber notificações sobre qualquer mudança no projeto.
    7. Clique em Próxima.
    8. Em Concluir, analise a Política de dados do usuário dos serviços de API do Google e, se concordar, selecione Concordo com a política de dados do usuário dos serviços de API do Google.
    9. Clique em Continuar.
    10. Clique em Criar.
    11. Se você selecionou Externo como tipo de usuário, adicione usuários de teste:
      1. Clique em Público-alvo.
      2. Em Test users, clique em Add users.
      3. Insira seu endereço de e-mail e os outros usuários de teste autorizados. Depois, clique em Salvar.
  3. Clique em Acesso a dados > Adicionar ou remover escopos. Um painel aparece com uma lista de escopos para cada API que você ativou no projeto do Google Cloud.

    1. Em Adicionar escopos manualmente, cole os seguintes escopos:

      • 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. Clique em Adicionar à tabela.

    3. Clique em Atualizar.

    4. Depois de selecionar os escopos necessários para o app, na página Acesso a dados, clique em Salvar.

Configurar a autenticação e a autorização do app

A autenticação de app é usada para chamar a API do Google Chat.

Criar uma conta de serviço no console do Google Cloud

Para criar uma conta de serviço, siga estas etapas:

Console do Google Cloud

  1. No console do Google Cloud, acesse Menu > IAM e administrador > Contas de serviço.

    Acessar a página "Contas de serviço"

  2. Clique em Criar conta de serviço.
  3. Preencha os detalhes da conta de serviço e clique em Criar e continuar.
  4. Opcional: atribua papéis à sua conta de serviço para conceder acesso aos recursos do projeto do Google Cloud. Para mais detalhes, consulte Como conceder, alterar e revogar o acesso a recursos.
  5. Clique em Continuar.
  6. Opcional: insira usuários ou grupos que podem gerenciar e realizar ações com essa conta de serviço. Para mais detalhes, consulte Como gerenciar a representação da conta de serviço.
  7. Clique em Concluído. Anote o endereço de e-mail da conta de serviço.

CLI da gcloud

  1. Crie a conta de serviço:
    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name="SERVICE_ACCOUNT_NAME"
  2. Opcional: atribua papéis à sua conta de serviço para conceder acesso aos recursos do projeto do Google Cloud. Para mais detalhes, consulte Como conceder, alterar e revogar o acesso a recursos.

A conta de serviço aparece na página de contas de serviço. Em seguida, crie uma chave particular para a conta de serviço.

Criar uma chave privada

Para criar e fazer o download de uma chave privada para a conta de serviço, siga estas etapas:

  1. No console do Google Cloud, acesse Menu > IAM e administrador > Contas de serviço.

    Acessar a página "Contas de serviço"

  2. Selecione sua conta de serviço.
  3. Clique em Chaves > Adicionar chave > Criar nova chave.
  4. Selecione JSON e clique em Criar.

    Seu novo par de chave pública/privada é gerado e transferido por download para sua máquina como um novo arquivo. Salve o arquivo JSON baixado como credentials.json no seu diretório de trabalho. Esse arquivo é a única cópia dessa chave. Para saber como armazenar sua chave com segurança, consulte Como gerenciar chaves de conta de serviço.

  5. Clique em Fechar.

Para mais informações sobre contas de serviço, consulte contas de serviço na documentação do IAM do Google Cloud.

Criar um cliente OAuth compatível com o Google Workspace Marketplace

Para criar um cliente OAuth compatível com o Google Workspace Marketplace, siga estas etapas:

  1. No console do Google Cloud, acesse Menu > IAM e administrador > Contas de serviço.

    Acessar a página "Contas de serviço"

  2. Clique na conta de serviço que você criou para o app Chat.

  3. Clique em Configurações avançadas.

  4. Clique em Criar um cliente OAuth compatível com o Google Workspace Marketplace.

  5. Clique em Continuar.

Uma mensagem de confirmação informando que um cliente OAuth compatível com o Google Workspace Marketplace foi criado.

Criar e implantar o app Chat

Na próxima seção, você vai copiar e atualizar um projeto inteiro do Apps Script que contém todo o código de aplicativo necessário para o app de chat. Assim, não é necessário copiar e colar cada arquivo.

Algumas funções incluem sublinhados no final dos nomes, como processSlashCommand_() de ChatApp.gs. O sublinhado oculta a função da página da Web de inicialização do incidente quando ela está aberta em um navegador. Para mais informações, consulte Funções privadas.

O Apps Script oferece suporte a dois tipos de arquivos: scripts .gs e arquivos .html. Para obedecer a esse suporte, o JavaScript do lado do cliente do app é incluído em tags <script />, e o CSS é incluído em tags <style /> em um arquivo HTML.

Você também pode conferir o projeto inteiro no GitHub.

Ver no GitHub

Confira uma visão geral de cada arquivo:

Consts.gs

Define constantes referenciadas por outros arquivos de código, incluindo o ID do projeto do Cloud, o ID de local da Vertex AI, as credenciais do app para a conta de serviço e o ID do comando de barra para fechar um incidente.

Mostrar código 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

Processa eventos de interação do Chat, como mensagens, cliques em cards, comandos de barra e diálogos. Responde ao comando de barra /closeIncident abrindo uma caixa de diálogo para coletar detalhes da resolução do incidente. Lê mensagens no espaço chamando o método spaces.messages.list na API Chat. Extrai IDs de usuário usando o serviço de diretório do SDK Admin no Apps Script.

Mostrar código 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

Recebe os dados de formulário que os usuários inserem na página da Web de inicialização do incidente e os usa para configurar um espaço de chat, criando e preenchendo-o, e depois publica uma mensagem sobre o incidente.

Mostrar código 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

Chama a API Documentos Google para criar um documento do Documentos Google no Google Drive de um usuário e grava um resumo das informações do incidente, criado em VertexAiApi.gs, no documento.

Mostrar código 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

Resume a conversa no espaço de chat usando a API Vertex AI. Esse resumo é postado em um documento criado especialmente em DocsAPI.gs.

Mostrar código 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

Fornece o site de inicialização do incidente.

Mostrar código 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

O HTML que compreende o site de inicialização do incidente.

Mostrar código 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

Processa o comportamento do formulário, incluindo envios, erros e exclusões, para o site de inicialização de incidentes. Ele é incluído em Index.html pela função include personalizada em WebController.gs.

Mostrar código 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

O CSS do site de inicialização do incidente. Ela é incluída em Index.html pela função include personalizada em WebController.gs.

Mostrar código 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>

Encontrar o número e o ID do projeto do Cloud

  1. No console do Google Cloud, acesse seu projeto do Cloud.

    Acessar o Console do Google Cloud

  2. Clique em Configurações e utilitários > Configurações do projeto.

  3. Anote os valores nos campos Número do projeto e ID do projeto. Você vai usá-los nas seções a seguir.

Criar o projeto do Apps Script

Para criar um projeto do Apps Script e conectá-lo ao seu projeto do Cloud:

  1. Clique no botão a seguir para abrir o projeto do Apps Script Respond to incidents with Google Chat.
    Abrir o projeto
  2. Clique em Visão geral.
  3. Na página de visão geral, clique em O ícone para fazer uma cópia Fazer uma cópia.
  4. Nomeie sua cópia do projeto do Apps Script:

    1. Clique em Copiar a opção "Responder a incidentes com o Google Chat".

    2. Em Título do projeto, digite Incident Management Chat app.

    3. Clique em Renomear.

  5. Na sua cópia do projeto do Apps Script, acesse o arquivo Consts.gs e substitua YOUR_PROJECT_ID pelo ID do seu projeto do Cloud.

Definir o projeto do Cloud do projeto do Apps Script

  1. No projeto do Apps Script, clique em Ícone das configurações do projeto Project Settings.
  2. Em Projeto do Google Cloud Platform (GCP), clique em Mudar projeto.
  3. Em Número do projeto do GCP, cole o número do seu projeto do Cloud.
  4. Clique em Configurar projeto. O projeto do Cloud e do Apps Script agora estão conectados.

Criar uma implantação do Apps Script

Agora que todo o código está em vigor, implante o projeto do Apps Script. Use o ID de implantação ao configurar o app Chat no Google Cloud.

  1. No Apps Script, abra o projeto do app de resposta a incidentes.

    Acessar o Apps Script

  2. Clique em Implantar > Nova implantação.

  3. Se Complemento e Aplicativo da Web ainda não estiverem selecionados, ao lado de Selecionar tipo, clique em tipos de implantação Ícone das configurações do projeto e selecione Complemento e Aplicativo da Web.

  4. Em Descrição, insira uma descrição para essa versão, como Complete version of incident management app.

  5. Em Executar como, selecione Usuário acessando o app da Web.

  6. Em Quem tem acesso, selecione Qualquer pessoa na sua organização do Workspace, em que "sua organização do Workspace" é o nome da sua organização do Google Workspace.

  7. Clique em Implantar. O Apps Script informa a implantação sucedida e fornece um ID de implantação e um URL para a página da Web de inicialização do incidente.

  8. Anote o URL do app da Web para acessar mais tarde quando iniciar um incidente. Copie o ID da implantação. Use esse ID ao configurar o app Chat no console do Google Cloud.

  9. Clique em Concluído.

Configurar o app Chat no console do Google Cloud

Esta seção mostra como configurar a API Google Chat no console do Google Cloud com informações sobre seu app do Chat, incluindo o ID da implantação que você acabou de criar no projeto do Apps Script.

  1. No console do Google Cloud, clique em Menu > Mais produtos > Google Workspace > Biblioteca de produtos > API Google Chat > Gerenciar > Configuração.

    Acessar a configuração da API Chat

  2. Em Nome do app, digite Incident Management.

  3. Em URL do avatar, digite https://developers.google.com/chat/images/quickstart-app-avatar.png.

  4. Em Descrição, digite Responds to incidents..

  5. Clique no botão Ativar recursos interativos para a posição ativada.

  6. Em Funcionalidade, selecione Receber mensagens individuais, Participar de espaços e conversas em grupo.

  7. Em Configurações de conexão, selecione Apps Script.

  8. Em Deployment ID, cole o ID de implantação do Apps Script que você copiou anteriormente da implantação do projeto do Apps Script.

  9. Registre um comando de barra que o app de chat totalmente implementado usa:

    1. Em Comandos, clique em Adicionar um comando.

    2. Em ID do comando, digite 1.

    3. Em Description, digite Closes the incident being discussed in the space.

    4. Em Tipo de comando, selecione Comando de barra.

    5. Em Nome do comando de barra, digite /closeIncident.

    6. Selecione Abre uma caixa de diálogo.

    7. Clique em Concluído. O comando de barra é registrado e listado.

  10. Em Visibilidade, selecione Disponibilidade do app de chat para pessoas e grupos específicos no seu domínio do Workspace e digite seu endereço de e-mail.

  11. Em Registros, selecione Registrar erros no Logging.

  12. Clique em Salvar. Uma mensagem de configuração salva aparece, o que significa que o app está pronto para teste.

Receber aprovação do administrador

Para receber a aprovação do administrador, configure o app de chat no SDK do Google Workspace Marketplace.

Configurar o app de chat no SDK do Google Workspace Marketplace

Para configurar o app Chat no SDK do Google Workspace Marketplace, siga estas etapas:

  1. No console do Google Cloud, acesse Menu > APIs e serviços > APIs e serviços ativados > SDK do Google Workspace Marketplace > Configuração do app.

    Acessar a configuração do app

  2. Conclua a página "Configuração do app". A forma de configurar o app de chat depende do público-alvo e de outros fatores. Para ajudar a preencher a página de configuração do app, consulte Configurar seu app no SDK do Google Workspace Marketplace. Para os fins deste guia, insira as seguintes informações:

    1. Em Visibilidade do app, selecione Particular.
    2. Em Configurações de instalação, selecione Instalação de administrador.
    3. Em Integrações de apps, selecione App do Chat.
    4. Em Escopos do OAuth, insira os seguintes escopos:
      • https://www.googleapis.com/auth/chat.app.spaces
      • https://www.googleapis.com/auth/chat.app.memberships
    5. Em Informações do desenvolvedor, insira seu nome, o URL do site do desenvolvedor e o e-mail do desenvolvedor.
    6. Clique em Salvar rascunho.

Depois de configurar o app, atualize a página "Detalhes do app":

  1. No console do Google Cloud, acesse Menu > APIs e serviços > APIs e serviços ativados > SDK do Google Workspace Marketplace > Listagem da loja.
  2. Em Detalhes do app, selecione "Desenvolvimento da Web" como categoria.
  3. Em Recursos gráficos, faça upload dos ícones dos aplicativos nos formatos solicitados.
  4. Em Capturas de tela, faça upload de uma captura de tela do aplicativo.
  5. Em Links de suporte, preencha um URL dos Termos de Serviço, um URL da Política de Privacidade e um URL de suporte.
  6. Em Distribuição, selecione as regiões em que o aplicativo vai estar disponível.
  7. Clique em Publicar.

Receber a aprovação do administrador

Agora que a conta de serviço está configurada para receber a aprovação do administrador, peça a um administrador do Google Workspace que pode conceder a aprovação seguindo as etapas em Configurar a autorização para apps de chat.

Teste o app do Chat

Para testar o app Chat de gerenciamento de incidentes, inicie um incidente na página da Web e verifique se o app Chat funciona conforme o esperado:

  1. Acesse o URL do app da Web de implantação do Apps Script.

  2. Quando o Apps Script solicitar permissão para acessar seus dados, clique em Revisar permissões, faça login com uma Conta do Google adequada no seu domínio do Google Workspace e clique em Permitir.

  3. A página da Web de inicialização do incidente é aberta. Insira as informações do teste:

    1. Em Título do incidente, digite The First Incident.
    2. Opcionalmente, em Respostas a incidentes, insira os endereços de e-mail dos outros participantes. Eles precisam ser usuários com uma conta do Google Chat na sua organização do Google Workspace. Caso contrário, a criação do espaço vai falhar. Não insira seu próprio endereço de e-mail, porque ele é incluído automaticamente.
    3. Em Mensagem inicial, digite Testing the incident management Chat app.
  4. Clique em Criar espaço de chat. Uma mensagem creating space aparece.

  5. Depois que o espaço é criado, uma mensagem Space created! aparece. Clique em Abrir espaço, que abre o espaço no Chat em uma nova guia.

  6. Opcionalmente, você e os outros participantes da resposta a incidentes podem enviar mensagens no espaço. O app resume essas mensagens usando a Vertex AI e compartilha um documento retrospectivo.

  7. Para encerrar a resposta ao incidente e iniciar o processo de resolução, no espaço de chat, digite /closeIncident. Uma caixa de diálogo de gerenciamento de incidentes é aberta.

  8. Em Fechar incidente, insira uma descrição da resolução do incidente, como Test complete.

  9. Clique em Fechar incidente.

O app Gerenciamento de incidentes lista as mensagens no espaço, as resume com o Vertex AI, cola o resumo em um documento do Documentos Google e compartilha o documento no espaço.

Limpar

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados neste tutorial, recomendamos que você exclua o projeto do Cloud.

  1. No console do Google Cloud, acesse a página Gerenciar recursos. Clique em Menu > IAM e administrador > Gerenciar recursos.

    Acesse o Resource Manager

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluir o projeto.