Сценарий отправляет клиенту персонализированный шаблон WhatsApp с вопросом, примет ли он участие в запланированном визите. Две кнопки быстрых ответов позволяют клиенту подтвердить участие или отменить его; вебхук направляет выбор в вашу backend-систему.
Пример шаблона
Здравствуйте, {{1}}! Вы придёте на своё {{2}}{{3}} в {{4}}?
Я приму участие
{{1}}
имя клиента
{{2}}
тип услуги или записи
{{3}}
дата бронирования
{{4}}
время бронирования
“Я приму участие”
кнопка — исправлено в шаблоне Meta
Когда использовать его
Используйте этот сценарий, когда визит уже запланирован, но посещение всё ещё под вопросом, и бизнесу нужен чёткий ответ до назначенного времени. Он подходит для клиник и салонов, которые теряют оплаченные часы из-за неявок, выездных сервисных команд, где напрасная поездка обходится потерей маршрута, и интеграторов, которые направляют подтверждение или отмену из вебхука в API для расписания.
Меньше пустых слотов
Имя, услуга, дата и время приходят как четыре переменные в теле, и две кнопки быстрых ответов предлагают клиенту подтвердить или отменить визит, чтобы время не оставалось неопределённым.
Меньше потраченного впустую времени сотрудников
Система планирования запускает шаблон при событии подтверждения посещаемости, чтобы полевые команды или сотрудники салона знали, нужно ли готовиться до времени приёма.
Без ручных подтверждающих звонков
Подтверждения и отмены приходят через вебхук и обновляют статус бронирования в расписании или CRM, так что никому не приходится звонить клиенту по телефону.
Работает за пределами 24-часового окна
Утверждённый шаблон доходит до клиента, когда нет открытой переписки — для этого первого исходящего сообщения нельзя использовать произвольный текст.
Как это работает
Триггер
Система планирования вызывает событие подтверждения присутствия.
event · triggered
Событие захвата
Система определяет номер телефона клиента и данные о встрече.
phone: "+…"
Собрать и отправить
Персонализированное сообщение по шаблону создаётся с четырьмя переменными в теле и двумя кнопками быстрых ответов.
POST/sendTemplate
Доставлено
Клиент получает сообщение в WhatsApp и нажимает «Подтвердить» или «Отменить».
delivered
Статус отслеживается
Вебхук обновляет статус бронирования в расписании или в CRM.
#!/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
TEST_BOOKINGDATE="___" # {{3}} booking date
TEST_BOOKINGTIME="___" # {{4}} booking time
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" \
"TEST_BOOKINGDATE=$TEST_BOOKINGDATE" \
"TEST_BOOKINGTIME=$TEST_BOOKINGTIME"; 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}
# {{3}} booking date → ${TEST_BOOKINGDATE}
# {{4}} booking time → ${TEST_BOOKINGTIME}
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}" },
{ "type": "text", "text": "${TEST_BOOKINGDATE}" },
{ "type": "text", "text": "${TEST_BOOKINGTIME}" }
]
}
]
}
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.
Сохраните это; обратные вызовы доставки и hookInfo настраиваются на этом
Доставка поступает позже в виде отдельного обратного вызова. Зарегистрируйте вебхук (POST …/webhook), и 1MSG отправляет обновления статуса на ваш HTTPS-адрес в корневом hooks[]payload-е.
200 OKВебхук статуса доставки — получаемый payload
sent, delivered, read — или статус ошибки, если это подходит
id
Соотносит обратный вызов с idвозвращаемым вызовом send
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.
ЧАСТО ЗАДАВАЕМЫЕ ВОПРОСЫ (FAQ)
Да, для холодных сообщений WhatsApp нужен одобренный Meta шаблон.