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

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

Техническая реализация
Предварительные условия
- Ключ API 1MSG · Как получить API Key
- Бизнес-аккаунт WhatsApp · Как подключить 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_PRODUCTORSERVICENAME="___" # {{2}} product or service 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_PRODUCTORSERVICENAME=$TEST_PRODUCTORSERVICENAME" \
"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}} product or service name → ${TEST_PRODUCTORSERVICENAME}
# {{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_PRODUCTORSERVICENAME}" },
{ "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зависят от этого
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Соотносит callback с
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. |

