WhatsApp Business API para solicitação de confirmação
O cenário envia ao cliente um modelo personalizado de WhatsApp pedindo para confirmar ou cancelar uma ação planejada.
Visão geral do caso de uso
O cenário envia ao cliente um template personalizado de WhatsApp pedindo para que confirme ou cancele uma ação planejada. A mensagem inclui o nome do cliente, etiqueta da ação, data e hora, e endereço. Os botões de resposta rápida «Confirmar» e «Cancelar» encaminham a escolha do cliente via webhook para o seu backend.
Exemplo de modelo
Olá, {{1}}! Por favor, confirme {{2}}. Data e horário: {{3}}. Endereço: {{4}}. Se precisar de ajuda — é só responder a esta mensagem e nós iremos ajudar.
- {{1}}nome do cliente
- {{2}}ação ou assunto a confirmar (por exemplo, agendamento de consulta, entrega em casa)
- {{3}}data e hora (por exemplo, 15 de julho, 14:00)
- {{4}}endereço ou localização (por exemplo, endereço de rua ou ponto de coleta)
- “Confirmar”botão — fixo no modelo Meta

Quando usar isso
Abrace este cenário quando uma visita, janela de entrega ou outra ação planejada precisar de confirmação explícita do cliente antes de você despachar ou comprometer recursos — e o cliente pode não ter uma conversa aberta no WhatsApp, então apenas um template aprovado pode ser enviado primeiro. Isso se encaixa em equipes de serviço externo e de agendamento que precisam confirmar data, hora e endereço antes que o caminhão saia, fluxos logísticos que precisam de um slot de entrega ou retirada confirmado, e agências conectando webhooks de CRM ou agendamento aos botões de confirmação e cancelamento do WhatsApp.
Fluxo de trabalho
- Gatilho
O sistema de agendamento, CRM ou fluxo de trabalho emite um evento de solicitação de confirmação.
event·triggered - Atos do cliente
O sistema resolve o número de telefone do destinatário e os campos de confirmação.
user action - Construir e enviar
Uma mensagem de modelo personalizada é construída com quatro variáveis de corpo e dois botões de resposta rápida.
POST/sendTemplate - Entregue
O cliente recebe a solicitação de confirmação pelo WhatsApp.
delivered - Status monitorado
Quando o cliente toca em Confirmar ou Cancelar, o webhook entrega o evento para processamento no backend.
status:"read"

Implementação técnica
Pré-requisitos
- 1MSG Chave da API · Como obter a Chave da API
- Conta do WhatsApp Business · Como Conectar WABA
- Modelo do WhatsApp · Como Aprovar o Modelo do WABA
- Consentimento do Cliente · Como Gerenciar o Consentimento
- Endpoint de Webhook · Como Configurar Webhooks
Exemplos de código
#!/usr/bin/env bash
set -euo pipefail
# === Configuration (replace "___" placeholders) ===
API_BASE_URL="https://api.1msg.io" # production 1MSG API base URL
CHANNEL_ID="___" # channel ID from 1MSG dashboard
API_TOKEN="___" # channel JWT token (Bearer)
TEMPLATE_NAME="___" # approved template name
TEMPLATE_NAMESPACE="___" # template namespace (required — send fails without it)
TEMPLATE_LANGUAGE="___" # template language code, e.g. "en"
# === Test data ===
TEST_PHONE="___" # client phone in international format
TEST_CUSTOMERNAME="___" # {{1}} customer name
TEST_ACTION="___" # {{2}} action name
TEST_DATE="___" # {{3}} date or time
TEST_ADDRESS="___" # {{4}} address or location
PHONE_NORM="$(printf '%s' "$TEST_PHONE" | tr -cd '0-9')"
for pair in "CHANNEL_ID=$CHANNEL_ID" "API_TOKEN=$API_TOKEN" \
"TEMPLATE_NAME=$TEMPLATE_NAME" "TEMPLATE_NAMESPACE=$TEMPLATE_NAMESPACE" \
"TEMPLATE_LANGUAGE=$TEMPLATE_LANGUAGE" "TEST_PHONE=$TEST_PHONE" \
"TEST_CUSTOMERNAME=$TEST_CUSTOMERNAME" \
"TEST_ACTION=$TEST_ACTION" \
"TEST_DATE=$TEST_DATE" \
"TEST_ADDRESS=$TEST_ADDRESS"; do
val="${pair#*=}"
if [ -z "$val" ] || [ "$val" = "___" ]; then
echo "Missing configuration value: ${pair%%=*}" >&2
exit 1
fi
done
if [ -z "$PHONE_NORM" ]; then
echo "Error: phone number has no digits after normalization" >&2
exit 1
fi
URL="${API_BASE_URL%/}/${CHANNEL_ID}/sendTemplate"
# params carries body ONLY. Button text is fixed in the Meta template — no button param.
# {{1}} customer name → ${TEST_CUSTOMERNAME}
# {{2}} action name → ${TEST_ACTION}
# {{3}} date or time → ${TEST_DATE}
# {{4}} address or location → ${TEST_ADDRESS}
read -r -d '' PAYLOAD <<JSON || true
{
"phone": "${PHONE_NORM}",
"template": "${TEMPLATE_NAME}",
"namespace": "${TEMPLATE_NAMESPACE}",
"language": { "policy": "deterministic", "code": "${TEMPLATE_LANGUAGE}" },
"params": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "${TEST_CUSTOMERNAME}" },
{ "type": "text", "text": "${TEST_ACTION}" },
{ "type": "text", "text": "${TEST_DATE}" },
{ "type": "text", "text": "${TEST_ADDRESS}" }
]
}
]
}
JSON
RESPONSE="$(curl -s -w '\n%{http_code}' -X POST "$URL" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${API_TOKEN}" \
-d "$PAYLOAD")"
HTTP_CODE="$(printf '%s' "$RESPONSE" | tail -n1)"
BODY="$(printf '%s' "$RESPONSE" | sed '$d')"
case "$BODY" in
*'"sent":true'*) ok=1 ;;
*) ok=0 ;;
esac
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ] && [ "$ok" -eq 1 ]; then
echo "Message sent to client."
echo "API response: $BODY"
else
echo "Send failed. HTTP status: $HTTP_CODE" >&2
echo "$BODY" >&2
exit 1
fi
Status de resposta e entrega
HTTP 2xx e JSON "sent": true significam que 1MSG aceitou a mensagem para envio — não que ela já chegou ao telefone do cliente. Salve o campo id (parece com wamid.…) para correlacionar os callbacks de entrega.
{
"sent": true,
"id": "wamid.HBgLMzgwNjM5...",
"message": "Message accepted for delivery"
}sentAceito para envio — não ainda no telefone do cliente
idArmazene isso; os retornos de chamada de entrega e
hookInfoestão vinculados a isso
A entrega em si chega mais tarde, como um callback separado. Registre um webhook (POST …/webhook) e a 1MSG envia atualizações de status para seu endpoint HTTPS em uma carga útil de nível superior hooks[].
{
"hooks": [
{
"id": "gBGGeSaGViBfAgnlzOSHEwK9O6F",
"type": "message",
"status": "sent",
"timestamp": "1654864094",
"recipient_id": "556123122026"
}
]
}statusenviado,entregue,lido— ou um status de falha quando aplicávelidCorrela o callback com o
idretornado pela chamada de envio.timestampSegundos Unix, como uma string
Se você prefere não receber retornos de chamada, consulte GET {base}/{channel}/hookInfo?messageId=<id> em vez disso. Na prática, a entrega geralmente é concluída em segundos — mas o contrato da API não garante isso, então nunca bloqueie um fluxo aguardando por isso.
Erros comuns
| Status | Resposta | Causa |
|---|---|---|
| 200 | Message was not sent: template is not defined | namespace, template or language missing from the request body. |
| 200 | template name (…) does not exist in <language> | The template is approved in a different language than the one requested. |
| 200 | Message was not sent: provide chatId, phone, bsuid, or username | No recipient the channel could resolve. |
| 403 | access denied | The token is wrong, or belongs to a different channel than the URL. |
| 429 | too many requests. please try later | The channel is over its send rate. |

