WhatsApp Business API для меню поддержки — интерактивные кнопки
Этот сценарий отправляет интерактивное сообщение с кнопкой с помощью sendButton в 24-часовое окно обслуживания клиентов.
Обзор сценария
Этот сценарий отправляет интерактивное сообщение с кнопкой sendButton в течение 24-часового окна обслуживания клиентов. Три быстрых ответа позволяют клиенту выбрать главное меню, статус заказа или передать чат оператору без ввода текста.
Пример шаблона
Чем мы можем вам помочь сегодня?

Когда использовать
Используйте этот сценарий, когда сообщение клиента открывает или продолжает сессию поддержки в WhatsApp, и ему нужен быстрый путь самообслуживания до того, как агент прочитает свободный текст. Это подходит для очередей первого уровня поддержки, где повторяющиеся запросы о статусе заказа, меню и эскалации замедляют первый ответ в 24-часовом окне обслуживания клиентов.
Как это работает
- Статус отслеживается
Сообщение клиента поступает через вебхук и оставляет сессию открытой.
status:"read" - Собрать и отправить
Ваш бэкенд отправляет интерактивное кнопочное меню с подсказками внизу.
POST/send_button - Действия клиента
Клиент нажимает на один из трёх вариантов.
user action - Доставлено
Вебхук передаёт id кнопки для маршрутизации в меню, статус или потоки агентов.
delivered

Техническая реализация
Предварительные условия
- Ключ API 1MSG · Как получить ключ API
- Аккаунт WhatsApp Business · Как подключить WABA
- Открыть 24-часовое окно сеанса · Как работает 24-часовое окно
- Согласие клиента на участие · Как управлять согласием клиентов
- Конечная точка вебхука · Как настроить вебхуки
Примеры кода
#!/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)
# === Test data ===
TEST_PHONE="___" # client phone in international format
PHONE_NORM="$(printf '%s' "$TEST_PHONE" | tr -cd '0-9')"
URL="${API_BASE_URL%/}/${CHANNEL_ID}/sendButton"
read -r -d '' PAYLOAD <<JSON || true
{
"phone": "${PHONE_NORM}",
"body": "How can we help you today?",
"footer": "Choose an option",
"sections": [
{ "type": "reply", "reply": { "id": "menu", "title": "Main menu" } },
{ "type": "reply", "reply": { "id": "status", "title": "Order status" } },
{ "type": "reply", "reply": { "id": "agent", "title": "Talk to agent" } }
]
}
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."
else
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ориентированы на это
Сама доставка поступает позже, в виде отдельного callback. Зарегистрируйте вебхук (POST …/webhook), и 1MSG будет отправлять обновления статуса на ваш HTTPS endpoint в основном hooks[] payload.
{
"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: empty body | No body in the request. |
| 200 | Message was not sent: provide chatId, phone, bsuid, or username | No recipient the channel could resolve. |
| 200 | wrong file | The media could not be fetched or uploaded — not a reachable URL, not valid base64. |
| 403 | access denied | The token is wrong, or belongs to a different channel than the URL. |
| 200 | Message was not sent: filename | sendFile called without a filename, so the media has no extension to send. |

