Скилл WhatsApp API для ИИ агентаЕщё
1msg official logo

WhatsApp Business API для пост-опроса тикета

Сценарий отправляет клиенту персонализированный шаблон WhatsApp после завершения обращения или тикета, приглашая пройти короткий опрос и оставить отзыв.

Обзор сценария

Сценарий отправляет клиенту персонализированный шаблон WhatsApp после завершения обращения в поддержку или тикета, приглашая оставить отзыв в коротком опросе. Сообщение включает имя клиента, номер тикета и строку темы опроса. Статичная кнопка с URL открывает форму опроса.

Пример шаблона

Здравствуйте, {{1}}! Заявка №{{2}} выполнена.{{3}} Пожалуйста, пройдите наш короткий опрос — это займет около минуты.

Пройти опрос
  • {{1}}
    имя клиента
  • {{2}}
    номер тикета или дела
  • {{3}}
    Расскажите, как мы обработали ваш запрос. Это займет 1 минуту
  • “Пройти опрос”
    кнопка — исправлена в шаблоне Meta
WhatsApp Business API for post-ticket survey

Когда использовать это

Используйте этот сценарий, когда дело или тикет поддержки завершен, и команде требуется структурированный опрос в WhatsApp вместо сообщения от агента или формы только по электронной почте. Подходит для служб поддержки, которые приглашают клиентов пройти краткие опросы после закрытия дела, контакт-центров, собирающих стандартизованные отзывы после тикета, а также агентств, подключающих запуск опросов из Zendesk, Freshdesk или пользовательских Как это работает CRM.

Более высокие показатели заполнения опросов
Приглашение принять участие в опросе приходит в WhatsApp с именем, номером тикета и темой опроса в трех переменных сообщения. Так запрос на обратную связь поступает в канал, который клиент уже использует, вместо опроса по электронной почте, который они никогда не открывают.
Сообщение после завершения отправлено успешно
Служба поддержки отправляет утвержденный шаблон, когда случай подходит, поэтому приглашение на опрос доходит до клиента, даже если нет открытой переписки и ответы в свободной форме не разрешены.
Без последующих сообщений после опроса вручную
Триггер после завершения заполняет поля с телефонами получателей и опросами, создает шаблон с тремя переменными в теле и кнопкой со статическим URL, поэтому агентам не нужно повторно вводить контекст тикета или помнить об отправке ссылки на опрос.
Контекст тикета до их ответа
Имя клиента и номер обращения появляются в теле сообщения, чтобы клиент знал, к какому завершенному тикету относится опрос, прежде чем нажать кнопку «Пройти опрос», которая открывает форму.
Доставка зафиксирована для дальнейшего анализа
Результат доставки записывается обратно в хелпдеск или CRM, а завершение опроса отслеживается на связанной форме, чтобы отзыв оставался привязанным к тому же тикету.

Как это работает

  1. Собрать и отправить

    Служба поддержки отправляет триггер на опрос после завершения, когда обращение или тикет подлежат.

    POST /sendTemplate

  2. Захват события

    Система определяет телефон получателя и поля опроса.

    phone: "+…"

  3. Персонализированное сообщение по шаблону

    Персонализированное сообщение по шаблону создается с тремя переменными в теле и статической кнопкой URL.

    POST /sendTemplate

  4. Доставлено

    Клиент получает приглашение на опрос WhatsApp с данными по тикету.

    delivered

  5. Статус отслежен

    Результат доставки фиксируется; завершение опроса отслеживается вне WhatsApp.

    status: "read"

WhatsApp Business API for post-ticket survey

Техническая реализация

Предварительные условия

  1. Ключ 1MSG API · Как получить API-ключ
  2. Аккаунт WhatsApp Business · Подключение WABA
  3. Шаблон WhatsApp · Как одобрить шаблон WABA
  4. Согласие клиента · Как управлять согласием клиентов

Примеры кода

#!/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_TICKETNUMBER="___"         # {{2}} ticket number
TEST_TOPIC="___"         # {{3}} topic or subject

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_TICKETNUMBER=$TEST_TICKETNUMBER" \
            "TEST_TOPIC=$TEST_TOPIC"; 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}} ticket number → ${TEST_TICKETNUMBER}
# {{3}} topic or subject → ${TEST_TOPIC}
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_TICKETNUMBER}" },
        { "type": "text", "text": "${TEST_TOPIC}" }
      ]
    }

  ]
}
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.

200 OKОтвет
{
  "sent": true,
  "id": "wamid.HBgLMzgwNjM5...",
  "message": "Message accepted for delivery"
}
  • sent

    Принято для отправки — еще не на телефоне клиента

  • id

    Храните это; обратные вызовы доставки и hookInfo привязываются к этому ключу

Доставка поступает позже, отдельным обратным вызовом. Зарегистрируйте вебхук (POST …/webhook), и 1MSG отправит обновления статуса на ваш HTTPS-эндпоинт в верхнем уровне hooks[] данных.

200 OKВебхук статуса доставки — данные, которые вы получаете
{
  "hooks": [
    {
      "id": "gBGGeSaGViBfAgnlzOSHEwK9O6F",
      "type": "message",
      "status": "sent",
      "timestamp": "1654864094",
      "recipient_id": "556123122026"
    }
  ]
}
  • status

    sent, delivered, read — или статус ошибки, если это подходит

  • id

    Соотносит колбэк с idвозвращенным вызовом send

  • timestamp

    Строка с Unix-временем в секундах

Если вы предпочитаете не использовать обратные вызовы, вместо этого используйте GET {base}/{channel}/hookInfo?messageId=<id> опрос. На практике доставка часто завершается за считанные секунды — однако это не гарантируется контрактом API, поэтому не следует блокировать поток, ожидая ее.

Частые ошибки

СтатусОтветПричина
200Message was not sent: template is not definednamespace, template or language missing from the request body.
200template name (…) does not exist in <language>The template is approved in a different language than the one requested.
200Message was not sent: provide chatId, phone, bsuid, or usernameNo recipient the channel could resolve.
403access deniedThe token is wrong, or belongs to a different channel than the URL.
429too many requests. please try laterThe channel is over its send rate.

ЧАСТЫЕ ВОПРОСЫ

Да, для холодных сообщений в WhatsApp нужен одобренный Meta шаблон.

Связанные

Опросы и отзывы
WhatsApp Business API для обработки негативных отзывов
Сценарий отправляет клиенту персонализированный шаблон WhatsApp после отправки нейтральной или низкой оценки удовлетворенности.
Опросы и отзывы
WhatsApp Business API для уведомления новой команды по отзывам
Сценарий отправляет менеджеру команды персонализированный шаблон WhatsApp, когда получена новая отзыв от клиента.
Опросы и отзывы
WhatsApp Business API для отзывов о стадии обслуживания
Сценарий отправляет клиенту персонализированный шаблон WhatsApp, когда завершается определенный этап услуги, и предлагает оценить, как он прошел.
Опросы и отзывы
WhatsApp Business API для подтверждения удовлетворенности
Этот сценарий отправляет клиенту короткий персонализированный шаблон WhatsApp с просьбой подтвердить, довольны ли они.
Опросы и отзывы
WhatsApp Business API для запроса рецензии текста
Сценарий отправляет клиенту персонализированный шаблон WhatsApp после завершения взаимодействия, с просьбой оставить письменный отзыв или рекомендацию.
Опросы и отзывы
WhatsApp Business API для напоминания заполнить опрос
Сценарий отправляет клиенту персонализированный шаблон WhatsApp, когда запрос на опрос все еще не выполнен после первой просьбы.
Опросы и отзывы
WhatsApp Business API для запроса отзыва после визита
Сценарий отправляет клиенту персонализированный шаблон WhatsApp после визита или встречи, предлагая оставить отзыв о впечатлениях.
Опросы и отзывы
WhatsApp Business API для опроса после доставки
Сценарий отправляет клиенту персонализированный шаблон WhatsApp после доставки заказа с просьбой оценить качество доставки.

Интегрируйте WhatsApp за часы
без проблем с инфраструктурой