Integração

API de WhatsApp para Google Sheets

Dispare mensagens a partir de planilhas com Apps Script.

function enviarWhatsApp(telefone, mensagem) {
  const url = "https://zapixo.com.br/api/v1/messages/text";
  const options = {
    method: "post",
    headers: {
      "Authorization": "Bearer SUA_CHAVE",
      "Content-Type": "application/json"
    },
    payload: JSON.stringify({
      instance: "planilha",
      number: telefone,
      text: mensagem
    })
  };
  UrlFetchApp.fetch(url, options);
}

Com o Apps Script, a própria planilha conversa com o Zapixo: UrlFetchApp envia, e um app da Web com doPost recebe as mensagens e grava em linhas. Não precisa de servidor.

O tutorial do blog cobre o disparo a partir da planilha, passo a passo. Aqui estão os dois sentidos da integração e as regras do Apps Script que costumam derrubar o script depois que ele entra em uso.

O que dá para fazer com Google Sheets e WhatsApp

  • Lista de avisos

    Cada linha da aba vira uma mensagem, e o script marca a linha como enviada para não repetir.

  • Registro do que chega

    Cada mensagem recebida vira uma linha com data, número, nome e texto.

  • Lembrete de agenda

    Uma aba de horários dispara o lembrete na véspera, por gatilho de tempo.

  • Planilha como CRM simples

    A resposta do cliente é escrita na mesma linha do contato, ao lado do que foi enviado.

Enviar mensagens pelo Google Sheets

  1. Guarde a chave nas propriedades do script

    No editor do Apps Script, em Configurações do projeto › Propriedades do script, crie ZAPIXO_API_KEY. Chave colada no código fica visível para qualquer pessoa que edite a planilha.

  2. Função de envio

    muteHttpExceptions faz o erro voltar como resposta, em vez de derrubar o script no meio da lista:

    function enviarWhatsApp(numero, texto) {
      const chave = PropertiesService.getScriptProperties().getProperty("ZAPIXO_API_KEY");
      const resp = UrlFetchApp.fetch("https://zapixo.com.br/api/v1/messages/text", {
        method: "post",
        contentType: "application/json",
        headers: { Authorization: "Bearer " + chave },
        payload: JSON.stringify({
          instance: "planilha",
          number: String(numero).replace(/\D/g, ""),
          text: texto,
        }),
        muteHttpExceptions: true,
      });
      return { status: resp.getResponseCode(), corpo: resp.getContentText() };
    }
  3. Percorra a aba e marque o que saiu

    Com a coluna de status preenchida, rodar de novo não reenvia o que já foi. A pausa mantém o ritmo abaixo de 60 por minuto:

    function enviarPendentes() {
      const aba = SpreadsheetApp.openById("ID_DA_PLANILHA").getSheetByName("Envios");
      const linhas = aba.getDataRange().getValues(); // A: número, B: mensagem, C: status
    
      for (let i = 1; i < linhas.length; i++) {
        const [numero, texto, status] = linhas[i];
        if (!numero || status === "enviado") continue;
    
        const r = enviarWhatsApp(numero, texto);
        aba.getRange(i + 1, 3).setValue(r.status === 200 ? "enviado" : "erro " + r.status);
        Utilities.sleep(1100);
      }
    }
  4. Rode com gatilho instalável

    Para rodar sozinho, crie o gatilho em Acionadores (o ícone de relógio no editor), por tempo ou por edição da planilha. Tem que ser gatilho instalável: o onEdit simples não tem permissão para chamar URL externa, e o envio falha.

Receber mensagens no Google Sheets

  1. Escreva o doPost

    O doPost recebe o webhook do Zapixo. O ID da planilha está na URL dela, entre /d/ e /edit:

    function doPost(e) {
      const segredo = PropertiesService.getScriptProperties().getProperty("WEBHOOK_SECRET");
      if (e.parameter.chave !== segredo) return ContentService.createTextOutput("ignorado");
    
      const payload = JSON.parse(e.postData.contents);
      const data = payload.data || {};
      const key = data.key || {};
      if (payload.event !== "messages.upsert" || key.fromMe) {
        return ContentService.createTextOutput("ok");
      }
    
      const msg = data.message || {};
      const texto = msg.conversation || (msg.extendedTextMessage || {}).text || "";
    
      SpreadsheetApp.openById("ID_DA_PLANILHA").getSheetByName("Recebidas").appendRow([
        new Date(),
        String(key.remoteJid).split("@")[0],
        data.pushName || "",
        texto,
        key.id,
      ]);
      return ContentService.createTextOutput("ok");
    }
  2. Implante como app da Web

    Em Implantar › Nova implantação, escolha App da Web, executar como você e acesso para qualquer pessoa. O Apps Script devolve uma URL terminada em /exec. Cole no painel do Zapixo, em Webhook de mensagens, com o segredo no fim: .../exec?chave=SEU_SEGREDO.

  3. Reimplante a cada mudança

    Salvar o código não muda o que está no ar. Em Gerenciar implantações, edite a implantação atual e publique uma nova versão: a URL continua a mesma e o painel não precisa ser mexido.

Erros comuns e como resolver

onEdit que não envia
Gatilho simples não chama URL externa. Crie o gatilho instalável em Acionadores com a mesma função.
Mudei o código e nada mudou
O app da Web roda a versão implantada, não a salva. Publique uma nova versão da implantação.
Não dá para devolver 401
App da Web do Apps Script responde sempre com sucesso. Por isso o doPost confere o segredo e só ignora a requisição que não bate.
Lista grande não termina
Cada execução do Apps Script tem limite de tempo (6 minutos), e a pausa entre envios consome esse tempo. Processe em lotes e deixe o gatilho de tempo continuar de onde parou — a coluna de status diz onde.
Mensagem gravada duas vezes
Se o doPost não responder em até 10 segundos, o Zapixo tenta de novo, até 3 vezes. A última coluna do exemplo guarda key.id: confira antes de gravar.
Telefone virou número estranho
A planilha trata telefone como número e pode exibir em notação científica. Formate a coluna como texto antes de colar a lista.

Perguntas frequentes

Precisa de servidor para ligar o Google Sheets ao WhatsApp?

Não. O Apps Script roda no Google: envia com UrlFetchApp e recebe com um app da Web.

Quantas mensagens dá para enviar de uma vez?

A API aceita 60 requisições por minuto por chave, e cada execução do Apps Script tem limite de tempo. Para listas grandes, envie em lotes com gatilho de tempo.

Funciona em conta Google gratuita?

Funciona. As cotas diárias do Apps Script são menores na conta gratuita do que no Google Workspace.

Dá para gravar a resposta do cliente na linha do envio?

Dá. No doPost, procure o número na aba de envios e escreva a resposta na coluna ao lado.

O trial tem limite de mensagens?

Tem. Ao atingir o limite, a API responde 402 com o link para assinar, e a coluna de status registra o erro.

Leia também