WhatsApp Business API для подтверждения успешного выполнения действия
Сценарий отправляет клиенту персонализированный шаблон WhatsApp сразу после того, как он завершит важное действие.
Обзор сценария
Сценарий отправляет клиенту персонализированный шаблон WhatsApp сразу после того, как он завершит важное действие. В сообщении указываются имя клиента, выполненное действие и что произойдёт дальше. Кнопка со статическим URL открывает сайт компании или аккаунт.
Пример шаблона
Здравствуйте, {{1}}! Действие «{{2}}» выполнено успешно. {{3}} Спасибо, что выбрали наш сервис.
- {{1}}имя клиента
- {{2}}завершённое действие (например, оплата, активация подписки, обновление профиля)
- {{3}}следующий шаг или результат (например, доступ активирован, квитанция отправлена по электронной почте)
- “Открыть сайт”кнопка — исправлена в шаблоне Meta

Когда использовать это
Используйте этот сценарий, когда клиент завершает важный этап в портале, приложении или при оформлении заказа и должен сразу узнать, что всё прошло успешно — до того, как он напишет в поддержку или обновит страницу. Это подходит для команд SaaS, подтверждающих подписку или изменения настроек, e-commerce, которые подтверждают оплату или этапы заказа, а также агентств, передающих события завершения из CRM, биллинга или пользовательского backend.
Как это работает
- Действия клиента
Клиент выполняет действие в портале, приложении или при оформлении заказа.
user action - Захватить событие
Система фиксирует завершение и определяет номер телефона получателя.
phone:"+…" - Создать и отправить
Персонализированное сообщение по шаблону строится с тремя переменными в теле и статической кнопкой URL.
POST/sendTemplate - Доставлено
Клиент получает подтверждение WhatsApp с описанием действия и следующими шагами.
delivered - Отслеживание статуса
Результат доставки фиксируется; ошибки обрабатываются по правилам платформы.
status:"read"

Техническая реализация
Предварительные требования
- Ключ API 1MSG · Как получить ключ API
- Аккаунт WhatsApp Business · Как подключить WABA
- Шаблон WhatsApp · Как одобрить шаблон WABA
- Согласие клиента на получение сообщений · Как управлять согласием клиентов
Примеры кода
#!/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_NEXTSTEP="___" # {{3}} next step
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_NEXTSTEP=$TEST_NEXTSTEP"; 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}} next step → ${TEST_NEXTSTEP}
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_NEXTSTEP}" }
]
}
]
}
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
Статус ответа и доставки
HTTP 2xx and JSON "sent": true mean 1MSG accepted the message for sending — not that it already reached the customer's phone. Save the id field (looks like wamid.…) to correlate delivery callbacks.
{
"sent": true,
"id": "wamid.HBgLMzgwNjM5...",
"message": "Message accepted for delivery"
}sentПринято для отправки — ещё не доставлено на телефон клиента
idХраните это — обратные вызовы доставки и
hookInfoпривязаны к этому ключу
Доставка поступает позже, через отдельный callback. Зарегистрируйте вебхук (POST …/webhook), и 1MSG будет отправлять обновления статуса на ваш HTTPS-эндпоинт в hooks[] верхнеуровневом payload.
{
"hooks": [
{
"id": "gBGGeSaGViBfAgnlzOSHEwK9O6F",
"type": "message",
"status": "sent",
"timestamp": "1654864094",
"recipient_id": "556123122026"
}
]
}statussent,delivered,read— или статус сбоя, если применимоidСоотносит callback с
idрезультатом вызова метода отправкиtimestampСекунды Unix в виде строки
Если вы предпочитаете не получать обратные вызовы, используйте опрос GET {base}/{channel}/hookInfo?messageId=<id> вместо них. На практике доставка часто завершается за считанные секунды, но контракт API этого не гарантирует, поэтому никогда не блокируйте процесс, ожидая её завершения.
Распространённые ошибки
| Статус | Ответ | Причина |
|---|---|---|
| 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. |

