Criar um app do Google Chat como um webhook

Nesta página, descrevemos como configurar um webhook para enviar mensagens assíncronas a um espaço do Chat usando gatilhos externos. Por exemplo, é possível configurar um aplicativo de monitoramento para notificar os funcionários de plantão no Chat quando um servidor ficar inativo. Para enviar uma mensagem síncrona com um app de chat, consulte Enviar uma mensagem.

Com esse tipo de arquitetura, os usuários não podem interagir com o webhook ou o aplicativo externo conectado porque a comunicação é unidirecional. Os webhooks não são conversacionais. Eles não podem responder nem receber mensagens de usuários ou eventos de interação do app Chat. Para responder a mensagens, crie um app do Chat em vez de um webhook.

Embora um webhook não seja tecnicamente um app do Chat (ele conecta aplicativos usando solicitações HTTP padrão), esta página se refere a ele como um app do Chat para simplificar. Cada webhook funciona apenas no espaço do Chat em que foi registrado. Os webhooks recebidos funcionam em mensagens diretas, mas apenas quando todos os usuários têm apps do Chat ativados. Não é possível publicar webhooks no Google Workspace Marketplace.

O diagrama a seguir mostra a arquitetura de um webhook conectado ao Chat:

Arquitetura para webhooks de entrada que enviam mensagens assíncronas ao Chat.

No diagrama anterior, um app de chat tem o seguinte fluxo de informações:

  1. A lógica do app Chat recebe informações de serviços externos de terceiros, como um sistema de gerenciamento de projetos ou uma ferramenta de emissão de tíquetes.
  2. A lógica do app Chat é hospedada em um sistema na nuvem ou local que pode enviar mensagens usando um URL de webhook para um espaço específico do Chat.
  3. Os usuários podem receber mensagens do app Chat no espaço específico, mas não podem interagir com ele.

Pré-requisitos

Python

Node.js

Java

Apps Script

Criar um webhook

Para criar um webhook, registre-o no espaço do Chat em que você quer receber mensagens e escreva um script que as envie.

Registrar o webhook de entrada

  1. Em um navegador, abra o Chat. Não é possível configurar webhooks no app Google Chat para dispositivos móveis.
  2. Acesse o espaço onde você quer adicionar um webhook.
  3. Ao lado do título do espaço, clique na seta para expandir e em Apps e integrações.
  4. Clique em Adicionar webhooks.

  5. No campo Nome, use Quickstart Webhook.

  6. No campo URL do avatar, insira https://developers.google.com/chat/images/chat-product-icon.png.

  7. Clique em Salvar.

  8. Para copiar o URL do webhook, clique em Mais e em Copiar link.

Escrever o script do webhook

O script de webhook de exemplo envia uma mensagem para o espaço em que o webhook está registrado ao enviar uma solicitação POST para o URL do webhook. A API Chat responde com uma instância de Message.

Selecione um idioma para aprender a criar um script de webhook:

Python

  1. No diretório de trabalho, crie um arquivo chamado quickstart.py.

  2. Em quickstart.py, cole o seguinte código:

    python/webhook/quickstart.py
    from json import dumps
    from httplib2 import Http
    
    # Copy the webhook URL from the Chat space where the webhook is registered.
    # The values for SPACE_ID, KEY, and TOKEN are set by Chat, and are included
    # when you copy the webhook URL.
    
    def main():
        """Google Chat incoming webhook quickstart."""
        url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN"
        app_message = {"text": "Hello from a Python script!"}
        message_headers = {"Content-Type": "application/json; charset=UTF-8"}
        http_obj = Http()
        response = http_obj.request(
            uri=url,
            method="POST",
            headers=message_headers,
            body=dumps(app_message),
        )
        print(response)
    
    
    if __name__ == "__main__":
        main()
  3. Substitua o valor da variável url pelo URL do webhook que você copiou ao registrar o webhook.

Node.js

  1. No diretório de trabalho, crie um arquivo chamado index.js.

  2. Em index.js, cole o seguinte código:

    node/webhook/index.js
    /**
     * Sends asynchronous message to Google Chat
     * @return {Object} response
     */
    async function webhook() {
      const url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages"
      const res = await fetch(url, {
        method: "POST",
        headers: {"Content-Type": "application/json; charset=UTF-8"},
        body: JSON.stringify({text: "Hello from a Node script!"})
      });
      return await res.json();
    }
    
    webhook().then(res => console.log(res));
  3. Substitua o valor da variável url pelo URL do webhook que você copiou ao registrar o webhook.

Java

  1. No diretório de trabalho, crie um arquivo chamado pom.xml.

  2. Em pom.xml, copie e cole o seguinte:

    java/webhook/pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.google.chat.webhook</groupId>
      <artifactId>java-webhook-app</artifactId>
      <version>0.1.0</version>
    
      <name>java-webhook-app</name>
      <url>https://github.com/googleworkspace/google-chat-samples/tree/main/java/webhook</url>
    
      <properties>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.source>11</maven.compiler.source>
      </properties>
    
      <dependencies>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.9.1</version>
        </dependency>
      </dependencies>
    
      <build>
        <pluginManagement>
          <plugins>
            <plugin>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>3.8.0</version>
            </plugin>
          </plugins>
        </pluginManagement>
      </build>
    </project>
  3. No diretório de trabalho, crie a seguinte estrutura de diretório src/main/java.

  4. No diretório src/main/java, crie um arquivo chamado App.java.

  5. Em App.java, cole o seguinte código:

    java/webhook/src/main/java/com/google/chat/webhook/App.java
    import com.google.gson.Gson;
    import java.net.http.HttpClient;
    import java.net.http.HttpRequest;
    import java.net.http.HttpResponse;
    import java.util.Map;
    import java.net.URI;
    
    public class App {
      private static final String URL = "https://chat.googleapis.com/v1/spaces/AAAAGCYeSRY/messages";
      private static final Gson gson = new Gson();
      private static final HttpClient client = HttpClient.newHttpClient();
    
      public static void main(String[] args) throws Exception {
        String message = gson.toJson(Map.of("text", "Hello from Java!"));
    
        HttpRequest request = HttpRequest.newBuilder(URI.create(URL))
          .header("accept", "application/json; charset=UTF-8")
          .POST(HttpRequest.BodyPublishers.ofString(message)).build();
    
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    
        System.out.println(response.body());
      }
    }
  6. Substitua o valor da variável URL pelo URL do webhook que você copiou ao registrar o webhook.

Apps Script

  1. Em um navegador, acesse Apps Script.

  2. Clique em Novo projeto.

  3. Cole o seguinte código:

    apps-script/webhook/webhook.gs
    function webhook() {
      const url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages"
      const options = {
        "method": "post",
        "headers": {"Content-Type": "application/json; charset=UTF-8"},
        "payload": JSON.stringify({"text": "Hello from Apps Script!"})
      };
      const response = UrlFetchApp.fetch(url, options);
      console.log(response);
    }
  4. Substitua o valor da variável url pelo URL do webhook que você copiou ao registrar o webhook.

Executar o script de webhook

Em uma CLI, execute o script:

Python

  python3 quickstart.py

Node.js

  node index.js

Java

  mvn compile exec:java -Dexec.mainClass=App

Apps Script

  • Clique em Executar.

Quando você executa o código, o webhook envia uma mensagem para o espaço em que você o registrou.

Iniciar ou responder a uma conversa

  1. Especifique spaces.messages.thread.threadKey como parte do corpo da solicitação de mensagem. Dependendo se você está iniciando ou respondendo a uma conversa, use os seguintes valores para threadKey:

    • Se você estiver iniciando uma conversa, defina o threadKey como uma string arbitrária, mas anote esse valor para postar uma resposta na conversa.

    • Se você estiver respondendo a uma conversa, especifique o threadKey definido quando ela foi iniciada. Por exemplo, para postar uma resposta na conversa em que a mensagem inicial usou MY-THREAD, defina MY-THREAD.

  2. Defina o comportamento da linha de execução se o threadKey especificado não for encontrado:

    • Responda a uma conversa ou inicie uma nova. Adicione o parâmetro messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD ao URL do webhook. Ao transmitir esse parâmetro de URL, o Chat procura uma conversa usando o threadKey especificado. Se uma for encontrada, a mensagem será postada como uma resposta a essa conversa. Se nenhuma for encontrada, a mensagem vai iniciar uma nova conversa correspondente a esse threadKey.

    • Responder a uma conversa ou não fazer nada. Adicione o parâmetro messageReplyOption=REPLY_MESSAGE_OR_FAIL ao URL do webhook. Ao transmitir esse parâmetro de URL, o Chat procura uma conversa usando o threadKey especificado. Se uma for encontrada, a mensagem será postada como uma resposta a essa conversa. Se nenhum for encontrado, a mensagem não será enviada.

    Para saber mais, consulte messageReplyOption.

O exemplo de código a seguir inicia ou responde a uma conversa por mensagem:

Python

python/webhook/thread-reply.py
from json import dumps
from httplib2 import Http

# Copy the webhook URL from the Chat space where the webhook is registered.
# The values for SPACE_ID, KEY, and TOKEN are set by Chat, and are included
# when you copy the webhook URL.
#
# Then, append messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD to the
# webhook URL.


def main():
    """Google Chat incoming webhook that starts or replies to a message thread."""
    url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD"
    app_message = {
        "text": "Hello from a Python script!",
        # To start a thread, set threadKey to an arbitratry string.
        # To reply to a thread, specify that thread's threadKey value.
        "thread": {"threadKey": "THREAD_KEY_VALUE"},
    }
    message_headers = {"Content-Type": "application/json; charset=UTF-8"}
    http_obj = Http()
    response = http_obj.request(
        uri=url,
        method="POST",
        headers=message_headers,
        body=dumps(app_message),
    )
    print(response)


if __name__ == "__main__":
    main()

Node.js

node/webhook/thread-reply.js
/**
 * Sends asynchronous message to Google Chat
 * @return {Object} response
 */
async function webhook() {
  const url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD"
  const res = await fetch(url, {
    method: "POST",
    headers: {"Content-Type": "application/json; charset=UTF-8"},
    body: JSON.stringify({
      text: "Hello from a Node script!",
      thread: {threadKey: "THREAD_KEY_VALUE"}
    })
  });
  return await res.json();
}

webhook().then(res => console.log(res));

Apps Script

apps-script/webhook/thread-reply.gs
function webhook() {
  const url = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD"
  const options = {
    "method": "post",
    "headers": {"Content-Type": "application/json; charset=UTF-8"},
    "payload": JSON.stringify({
      "text": "Hello from Apps Script!",
      "thread": {"threadKey": "THREAD_KEY_VALUE"}
    })
  };
  const response = UrlFetchApp.fetch(url, options);
  console.log(response);
}

Solucionar erros

As solicitações de webhook podem falhar por vários motivos, incluindo:

  • Solicitação inválida.
  • O webhook ou o espaço que o hospeda é excluído.
  • Problemas intermitentes, como conectividade de rede ou limites de cota.

Ao criar o webhook, é necessário processar os erros de maneira adequada:

  • Registrando a falha.
  • Para erros de tempo, cota ou conectividade de rede, tente novamente com espera exponencial.
  • Não fazer nada, o que é adequado se o envio da mensagem do webhook não for importante.

A API Google Chat retorna erros como um google.rpc.Status, que inclui um erro HTTP code que indica o tipo de erro encontrado: um erro do cliente (série 400) ou um erro do servidor (série 500). Para revisar todos os mapeamentos HTTP, consulte google.rpc.Code.

{
    "code": 503,
    "message": "The service is currently unavailable.",
    "status": "UNAVAILABLE"
}

Para saber como interpretar códigos de status HTTP e lidar com erros, consulte Erros.

Limitações e considerações

  • Ao criar uma mensagem com um webhook na API Google Chat, a resposta não contém a mensagem completa. A resposta só preenche os campos name e thread.name.
  • Os webhooks estão sujeitos à cota por espaço para spaces.messages.create: uma solicitação por segundo, compartilhada entre todos os webhooks no espaço. O Chat também pode rejeitar solicitações de webhook que excedam uma consulta por segundo no mesmo espaço. Para mais informações sobre as cotas da API Chat, consulte Limites de uso.