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

Когда использовать это
Обратитесь к этому сценарию, когда клиент начинает оформлять заказ, проходить онбординг или верификацию, но прерывает процесс, не завершив его, — и вам нужно вернуть его на тот самый шаг, на котором он остановился. Это подходит командам, работающим с электронной коммерцией, восстанавливающим неоплаченные корзины, продуктовым командам, напоминающим о необходимости прохождения KYC или завершения профиля, и агентствам, которые настраивают триггеры для брошенных корзин или сохранённых черновиков из CRM или аналитической системы клиента.
Как это работает
- Действия клиента
Клиент начинает действие, но уходит, не завершив его.
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_INCOMPLETEACTION="___" # {{2}} incomplete action
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_INCOMPLETEACTION=$TEST_INCOMPLETEACTION" \
"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}} incomplete action → ${TEST_INCOMPLETEACTION}
# {{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_INCOMPLETEACTION}" },
{ "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 и JSON "sent": true означают, что 1MSG принял сообщение для отправки, но не то, что оно уже доставлено на телефон клиента. Сохраните id поле (выглядит как wamid.…), чтобы соотносить обратные вызовы доставки.
{
"sent": true,
"id": "wamid.HBgLMzgwNjM5...",
"message": "Message accepted for delivery"
}sentПринято для отправки — ещё не доставлено на телефон клиента
idСохраните это; обратные вызовы доставки и
hookInfoоснованы на этом
Сама доставка приходит позже, в виде отдельного обратного вызова. Зарегистрируйте вебхук (POST …/webhook), и 1MSG отправит обновления статуса на ваш HTTPS-эндпоинт в корневом hooks[] сообщении.
{
"hooks": [
{
"id": "gBGGeSaGViBfAgnlzOSHEwK9O6F",
"type": "message",
"status": "sent",
"timestamp": "1654864094",
"recipient_id": "556123122026"
}
]
}statussent,delivered,read— или статус ошибки, если это применимоidСоотносит обратный вызов с
idрезультатом вызова sendtimestampстрока с секундами 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. |

