API de WhatsApp com Google Sheets: enviar da planilha e registrar respostas
Com Google Apps Script, uma planilha envia mensagens pela D-API e recebe as respostas de volta em outra aba. O envio usa UrlFetchApp, o recebimento usa um Web App com doPost, e nada disso depende de conector pronto.
Quando a planilha é a ferramenta certa
Muita operação pequena vive no Google Sheets: a lista de alunos da turma, os clientes com parcela vencendo, os participantes de um evento. Mandar WhatsApp para essa lista a partir da própria planilha evita exportar CSV para outra ferramenta e mantém o controle de quem já recebeu no mesmo lugar.
Não existe integração nativa entre D-API e Google Sheets. A ligação é feita com o Apps Script que já vem com toda planilha: ele chama a API de WhatsApp por HTTP e publica uma URL para receber o webhook. Serve bem para dezenas ou poucas centenas de envios por dia. Acima disso, os limites do Apps Script começam a atrapalhar, e falamos deles mais abaixo.
Monte a planilha antes do código
Crie duas abas. A primeira, chamada Envios, com estas colunas na linha 1:
| Coluna | Conteúdo | Exemplo |
|---|---|---|
| A: telefone | Só dígitos, com código do país | 5511999999999 |
| B: nome | Primeiro nome para personalizar | Carla |
| C: mensagem | Texto a enviar | Sua inscrição no workshop está confirmada. |
| D: optin | SIM quando a pessoa autorizou | SIM |
| E: status | Preenchido pelo script | enviado |
| F: enviado_em | Preenchido pelo script | data e hora |
A segunda aba, Respostas, recebe o que as pessoas escreverem de volta. Depois abra Extensões, Apps Script e, em Configurações do projeto, crie as propriedades do script DAPI_KEY com a sua API Key e DAPI_SESSION com o id da conexão.
Enviar com UrlFetchApp
A função abaixo percorre a aba Envios, pula quem não tem opt-in ou já recebeu, envia em lotes pequenos e grava o resultado de cada linha. O muteHttpExceptions faz o erro virar texto na planilha em vez de derrubar a execução inteira:
const LOTE = 40 // cabe com folga nos 6 minutos de uma execução
function enviarPendentes() {
const props = PropertiesService.getScriptProperties()
const aba = SpreadsheetApp.getActive().getSheetByName('Envios')
const linhas = aba.getDataRange().getValues()
let enviados = 0
for (let i = 1; i < linhas.length && enviados < LOTE; i++) {
const [telefone, nome, mensagem, optin, status] = linhas[i]
if (optin !== 'SIM' || status) continue
const resp = UrlFetchApp.fetch('https://api.d-api.cloud/api/v1/messages/send/text', {
method: 'post',
contentType: 'application/json',
headers: { Authorization: props.getProperty('DAPI_KEY') },
payload: JSON.stringify({
sessionId: props.getProperty('DAPI_SESSION'),
to: String(telefone),
text: 'Oi, ' + nome + '! ' + mensagem,
}),
muteHttpExceptions: true,
})
const ok = resp.getResponseCode() < 300
aba.getRange(i + 1, 5, 1, 2).setValues([[ok ? 'enviado' : 'erro ' + resp.getContentText(), new Date()]])
enviados++
Utilities.sleep(4000 + Math.random() * 4000) // intervalo irregular entre envios
}
}Para rodar sozinho, crie em Acionadores um acionador baseado em tempo que chama enviarPendentes a cada 15 minutos. Cada execução pega o próximo lote de linhas sem status, então uma lista grande vai sendo consumida ao longo do dia, sem estourar o tempo de uma execução.
Receber respostas com doPost
No mesmo projeto, adicione a função que o Google chama quando alguém faz POST na URL do Web App. Ela registra só mensagens recebidas de contatos, fora de grupos, e ignora ids repetidos:
function doPost(e) {
const evento = JSON.parse(e.postData.contents)
const d = evento.data
if (evento.event !== 'messages.received' || d.fromMe || d.is_group) return ok()
const cache = CacheService.getScriptCache()
if (cache.get(d.id)) return ok()
cache.put(d.id, '1', 21600) // 6 horas
SpreadsheetApp.getActive().getSheetByName('Respostas').appendRow([
new Date(d.timestamp),
d.from.jid.split('@')[0],
d.from_name,
d.type === 'text' ? d.message : '[' + d.type + ']',
])
return ok()
}
function ok() {
return ContentService.createTextOutput('ok')
}Publique em Implantar, Nova implantação, tipo App da Web, executando como você e com acesso para qualquer pessoa, já que a D-API chama a URL sem login do Google. Copie a URL que termina em /exec e registre como webhook da conexão:
curl -X POST https://api.d-api.cloud/api/v1/sessions/SUA_SESSAO/webhook \
-H "Authorization: SUA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "webhookUrl": "https://script.google.com/macros/s/SEU_ID/exec" }'O webhook da D-API não tem assinatura, então a proteção aqui é a URL não ser divulgada. Se quiser ir além, confira no doPost se o sessionId do evento é o da sua conexão. O formato completo do evento está no guia de webhook de WhatsApp.
Cotas do Apps Script e cuidados com volume
- Tempo por execução: 6 minutos. Por isso o envio é em lotes com acionador, e não um laço sobre a planilha inteira.
- Chamadas UrlFetch: numa conta pessoal, 20 mil por dia, somando tudo o que seus scripts fazem. Contas Google Workspace têm cota maior.
- Acionadores: contas pessoais têm um limite diário de tempo total de execução por acionadores. Intervalos longos entre envios consomem esse tempo.
- Escrita concorrente: se muitas respostas chegam ao mesmo tempo, o
appendRowem paralelo pode ficar lento. Para volume alto, a planilha deixa de ser o banco certo.
O limite que mais importa, porém, é o do WhatsApp. Intervalo irregular entre envios, mensagem personalizada e só para quem pediu são o que mantém o número de pé. O assunto tem guia próprio em como evitar banimento.
Quando sair da planilha
Se a lista passou de alguns milhares de contatos ou se o envio precisa acontecer no segundo em que algo muda no seu sistema, a planilha virou gargalo. Para envios grandes e recorrentes, veja disparo em massa pela API. Para lembretes que dependem de data, como vencimento, o guia de cobrança pelo WhatsApp mostra o desenho com o sistema de origem. E se você prefere fluxos visuais sem código, o n8n combina o node da D-API com o nó de Google Sheets que ele já traz.
Perguntas frequentes
Preciso de alguma extensão ou complemento no Google Sheets?
Não. Tudo roda no Google Apps Script, que já vem com a planilha em Extensões, Apps Script. O envio usa UrlFetchApp para chamar a API da D-API, e o recebimento usa um Web App com a função doPost.
Quantas mensagens consigo enviar por dia pela planilha?
O limite prático vem do Apps Script, não da planilha: numa conta Google pessoal a cota atual é de 20 mil chamadas UrlFetch por dia e cada execução para em 6 minutos. Confira a tabela oficial de cotas, porque o Google revisa esses números.
Onde guardo a API Key com segurança?
Nas propriedades do script, em Configurações do projeto. Assim a chave não fica numa célula que qualquer pessoa com acesso à planilha consegue ler, nem no código que alguém pode copiar.
Por que uma resposta apareceu duas vezes na aba de respostas?
Porque a D-API tenta de novo quando não recebe confirmação a tempo, e o Web App pode demorar. O exemplo desta página guarda o id de cada mensagem no cache do script por algumas horas e ignora repetições.
Posso mandar para uma lista de contatos que comprei?
Não deveria. Mensagem para quem não pediu gera denúncia, e denúncia leva o número a ser bloqueado. Envie só para quem autorizou o contato pelo WhatsApp e registre esse consentimento na própria planilha.
Continue lendo
Teste a API de WhatsApp da D-API
Trial de 3 dias com acesso completo. Sem cartão, sem fidelidade.