WhatsApp Business API для приветственного сообщения при регистрации
Сценарий отправляет персонализированный шаблон WhatsApp, когда пользователь завершает регистрацию.
Обзор сценария
Сценарий отправляет персонализированный шаблон WhatsApp, когда пользователь завершает регистрацию. Сообщение включает имя клиента и сервис или приложение, на которые он зарегистрировался. Статическая кнопка URL открывает страницу аккаунта или страницу начала работы.
Пример шаблона
Добро пожаловать {{1}}! Спасибо за регистрацию в {{2}}. Мы рады, что вы с нами. Нажмите кнопку ниже, чтобы открыть свой аккаунт и выполнить первые шаги. Если вам нужна помощь, просто ответьте на это сообщение.
- {{1}}имя клиента
- {{2}}название сервиса или приложения, на которое пользователь подписался
- “Открыть аккаунт”кнопка — исправлено в шаблоне Meta

Когда использовать
Используйте этот сценарий, когда пользователь завершает регистрацию, и бизнесу нужно срочно поприветствовать его — до того, как он отдалится от онбординга. Это подходит для SaaS и мобильных приложений, приветствующих новых подписчиков, порталов и маркетплейсов, побуждающих завершить профиль, и агентств, подключающих вебхуки регистрации клиентов к автоматическому онбордингу через WhatsApp.
Как это работает
- Фиксировать событие
Приложение или портал отправляет событие о завершении регистрации с телефоном пользователя.
phone:"+…" - Извлечь имя клиента
Система получает имя клиента и контекст сервиса или приложения из данных регистрации.
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_SERVICE="___" # {{2}} service name
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_SERVICE=$TEST_SERVICE"; 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}} service name → ${TEST_SERVICE}
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_SERVICE}" }
]
}
]
}
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привязываются к этому ключу
Delivery itself arrives later, as a separate callback. Register a webhook (POST …/webhook) and 1MSG POSTs status updates to your HTTPS endpoint in a top-level hooks[] payload.
{
"hooks": [
{
"id": "gBGGeSaGViBfAgnlzOSHEwK9O6F",
"type": "message",
"status": "sent",
"timestamp": "1654864094",
"recipient_id": "556123122026"
}
]
}statussent,delivered,read— или статус сбоя при необходимостиidСоотносит обратный вызов с
idзначением, возвращённым вызовом sendtimestampСтрока с Unix-секундами
If you would rather not receive callbacks, poll GET {base}/{channel}/hookInfo?messageId=<id> instead. In practice delivery often completes within seconds — but the API contract does not guarantee it, so never block a flow waiting on it.
Распространённые ошибки
| Статус | Ответ | Причина |
|---|---|---|
| 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. |

