Кастомні канали · Webhooks

Кастомні канали

Підключіть до Pager будь-яку платформу повідомлень: повідомлення клієнтів потраплять у спільний інбокс, а відповіді менеджерів — назад на вашу платформу.

Початок роботи

Огляд

Кастомний канал підключає до Pager платформу, для якої немає готової інтеграції: власний месенджер, чат на сайті, мобільний застосунок чи сторонній сервіс. Менеджери працюють із такими розмовами так само, як з Instagram чи Telegram.

Ваш сервер
Вхідні події

Клієнт написав на вашій платформі — ви надсилаєте message.created на вебхук Pager.

Вихідні повідомлення

Менеджер відповів у Pager — Pager надсилає POST на URL вашого сервера.

Pager
  • Обмін іде JSON-ом через HTTPS, обидва напрямки підписано одним ключем каналу.
  • Клієнтів і повідомлення ви ідентифікуєте своїми ідентифікаторами — externalId. Клієнта й розмову Pager створює сам під час першого повідомлення.
  • Нові повідомлення враховуються в ліміті повідомлень організації, як і в інших каналах.

Початок роботи

Підключення каналу

Канал підключає адміністратор організації в кабінеті Pager.

  1. 1

    Відкрийте Налаштування → Канали і натисніть Підключити власний канал.

  2. 2

    Вкажіть назву каналу — її бачитимуть менеджери в інбоксі — і URL для відправки повідомлень: адресу вашого сервера, на яку Pager надсилатиме відповіді менеджерів.

  3. 3

    Після підключення в картці каналу з'явиться API Key виду chan_sk_live_… — це ключ каналу. Додайте його в налаштування свого сервера.

Ключ каналу діє лише для одного каналу й не пов'язаний із ключем Pager API (pgr_live_…). У кожного кастомного каналу свій ключ.
Ключ каналу дозволяє писати повідомлення від імені ваших клієнтів. Зберігайте його на сервері й не додавайте в код, що виконується в браузері чи мобільному застосунку.

Початок роботи

Автентифікація

Обидва напрямки підписуються ключем каналу в заголовку x-channel-key.

  • Ваш сервер → Pager. Передавайте ключ у x-channel-key кожного запиту до вебхука. За ключем Pager визначає канал і організацію.
  • Pager → ваш сервер. Pager передає той самий ключ у x-channel-key. Порівнюйте його зі своїм і відхиляйте запити з іншим ключем — інакше будь-хто, хто знає ваш URL, зможе надіслати вашим клієнтам повідомлення від імені менеджера.

Вхідні: ваш сервер → Pager

Вебхук Pager

Усі вхідні події надсилайте запитом POST на одну адресу. Тип події задає поле event: message.created, message.edited або message.deleted.

POSThttps://api.pager.co.ua/api/webhooks/custom

Заголовки

  • x-channel-keyheader

    Ключ каналу.

  • Content-Typeheader

    application/json.

  • Одна подія — один запит. Пакетної відправки немає.
  • Успішна обробка — завжди 200 з полем action, що показує, що саме зроблено — див. Відповіді та помилки.

Нове повідомленняmessage.created

Додає повідомлення в розмову з клієнтом. Якщо клієнт пише вперше, Pager створює клієнта й розмову.

Тіло запиту

  • eventstringобов'язковий

    message.created.

  • client.externalIdstringобов'язковий

    Ідентифікатор клієнта на вашій платформі, до 255 символів. За ним Pager знаходить клієнта в цьому каналі.

  • client.namestring | nullнеобов'язковий

    Ім'я клієнта, до 100 символів. Не передано — лишається як було; null — стерти.

  • client.imageUrlstring | nullнеобов'язковий

    Посилання на аватар. Не передано — лишається як було.

  • message.externalIdstringобов'язковий

    Ідентифікатор повідомлення на вашій платформі, до 255 символів.

  • message.directionenumобов'язковий

    incoming — повідомлення від клієнта. outgoing — повідомлення, яке ваш оператор надіслав поза Pager: так історія в Pager лишається повною.

  • message.textstring | nullнеобов'язковий

    Текст, до 8000 символів.

  • message.attachmentsobject[]необов'язковий

    До 20 вкладень — див. Вкладення.

  • Повторна подія з тим самим message.externalId не створює дубль: Pager оновлює текст і вкладення наявного повідомлення. Тож запит можна безпечно повторити, якщо ви не отримали відповіді.
  • Вхідне повідомлення позначає розмову непрочитаною. Вихідне зберігається прочитаним і стану розмови не змінює.
  • Пробіли на початку й у кінці тексту обрізаються, переноси \r\n замінюються на \n.
  • Нове повідомлення враховується в ліміті повідомлень організації; повтор того самого externalId — ні.
curl -X POST "https://api.pager.co.ua/api/webhooks/custom" \
  -H "x-channel-key: $PAGER_CHANNEL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event":"message.created","client":{"externalId":"user_58213","name":"Олена Коваль","imageUrl":"https://cdn.example.com/avatars/58213.jpg"},"message":{"externalId":"msg_90412","direction":"incoming","text":"Добрий день! Чи є доставка у Львів?","attachments":[]}}'
Відповідь · 200
{
  "ok": true,
  "action": "created_or_deduped"
}

Редагуванняmessage.edited

Змінює текст або вкладення повідомлення, яке Pager уже отримав, і позначає його відредагованим.

Тіло запиту

  • eventstringобов'язковий

    message.edited.

  • message.externalIdstringобов'язковий

    Ідентифікатор повідомлення, яке треба змінити.

  • message.textstring | nullнеобов'язковий

    Новий текст, до 8000 символів. Не передано, null або порожній рядок — текст не змінюється.

  • message.attachmentsobject[]необов'язковий

    Новий список вкладень, який повністю замінює попередній. Не передано — вкладення не змінюються; [] — прибрати всі.

  • Pager шукає повідомлення з цим externalId у вашому каналі — і вхідне, і вихідне. Повідомлення менеджерів мають externalId, лише якщо ваш сервер повернув його у відповіді на вихідне повідомлення.
  • Якщо повідомлення не знайдено, Pager відповідає 200 з action: "edit_ignored_not_found".
curl -X POST "https://api.pager.co.ua/api/webhooks/custom" \
  -H "x-channel-key: $PAGER_CHANNEL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event":"message.edited","message":{"externalId":"msg_90412","text":"Добрий день! Чи є доставка у Львів і скільки вона коштує?"}}'
Відповідь · 200
{
  "ok": true,
  "action": "edited"
}

Видаленняmessage.deleted

Видаляє повідомлення з Pager назавжди — менеджери більше його не бачать.

Тіло запиту

  • eventstringобов'язковий

    message.deleted.

  • message.externalIdstringобов'язковий

    Ідентифікатор повідомлення, яке треба видалити.

  • Як і редагування, працює для вхідних і вихідних повідомлень із відомим externalId.
  • Якщо повідомлення не знайдено, Pager відповідає 200 з action: "delete_ignored_not_found".
curl -X POST "https://api.pager.co.ua/api/webhooks/custom" \
  -H "x-channel-key: $PAGER_CHANNEL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event":"message.deleted","message":{"externalId":"msg_90412"}}'
Відповідь · 200
{
  "ok": true,
  "action": "deleted"
}

Вхідні: ваш сервер → Pager

Відповіді та помилки

Успішна обробка — завжди 200 з ok: true. Поле action показує, що зроблено:

actionЩо означає
created_or_dedupedПовідомлення створено або вже існувало й було оновлене (повтор message.created).
editedПовідомлення змінено.
edit_ignored_not_foundПовідомлення з таким externalId не знайдено — нічого не змінено.
deletedПовідомлення видалено.
delete_ignored_not_foundПовідомлення з таким externalId не знайдено — нічого не видалено.

Помилки повертаються з полем error:

HTTPerrorЩо означає
400Invalid payloadТіло не відповідає схемі. Поле details.fieldErrors показує, які поля не пройшли перевірку.
401Missing x-channel-keyЗаголовок x-channel-key не передано.
401Invalid channel keyКлюча не існує — можливо, канал видалено.
403Channel is not CustomКлюч належить каналу іншого типу.
403Inbound disabledПрийом вхідних повідомлень для каналу вимкнено.
500Server errorВнутрішня помилка Pager.
Відповідь · 400
{
  "error": "Invalid payload",
  "details": {
    "formErrors": [],
    "fieldErrors": {
      "client": [
        "Invalid input: expected string, received undefined"
      ]
    }
  }
}
На 500 і мережеві помилки повторіть запит із паузою — завдяки externalId повтор не створить дублів. Помилки 4xx повтор не виправить: перевірте ключ і тіло запиту.

Вихідні: Pager → ваш сервер

Запит від Pager

Коли менеджер надсилає повідомлення в розмові цього каналу, Pager одразу робить POST на URL, вказаний під час підключення. Так само приходять повідомлення, надіслані через Pager API. Формат тіла той самий, що й у вхідної події message.created.

Заголовки

  • x-channel-keystring

    Ключ каналу — перевіряйте його, див. Автентифікація.

  • Content-Typestring

    application/json.

Тіло запиту

  • eventstring

    Завжди message.created.

  • client.externalIdstring

    Ідентифікатор клієнта на вашій платформі — той, що ви передали у вхідних подіях.

  • message.pagerMessageIdstring

    Ідентифікатор повідомлення в Pager. За ним відкидайте повторні доставки.

  • message.directionenum

    Завжди outgoing.

  • message.textstring | null

    Текст або null, якщо менеджер надіслав лише файли.

  • message.attachmentsobject[]

    Вкладення — див. Вкладення.

POSTЗапит від Pager
{
  "event": "message.created",
  "client": {
    "externalId": "user_58213"
  },
  "message": {
    "pagerMessageId": "c9d8e7f6-a5b4-4c3d-9e2f-1a0b9c8d7e6f",
    "direction": "outgoing",
    "text": "Так, відправляємо Новою поштою, доставка 1–2 дні. Ось тарифи:",
    "attachments": [
      {
        "type": "image",
        "payload": {
          "url": "https://files.pager.co.ua/…/tariffs.png?X-Amz-Expires=86400&…"
        }
      }
    ]
  }
}

Вихідні: Pager → ваш сервер

Відповідь вашого сервера

Відповідайте кодом 2xx, щойно прийняли повідомлення, і поверніть у JSON ідентифікатор повідомлення на вашій платформі.

Ваша відповідь · 200
{
  "externalMessageId": "msg_90415"
}
  • externalMessageId (або externalId) Pager зберігає як ідентифікатор повідомлення. Без нього ви не зможете потім відредагувати чи видалити це повідомлення.
  • Повідомлення враховується в ліміті повідомлень організації, лише якщо ви відповіли 2xx і повернули externalMessageId.
  • Менеджер бачить повідомлення надісланим лише після вашої відповіді, тож відповідайте швидко, а важку обробку робіть уже після неї.

Доставка й повтори

  • Якщо ваш сервер відповів не 2xx або не відповів зовсім, Pager повторює запит ще двічі — через 0,2 і 0,6 секунди.
  • Якщо всі три спроби невдалі, повідомлення зберігається в Pager із позначкою «не доставлено», і менеджер це бачить. Пізніше Pager його автоматично не надсилає.
Через повтори той самий запит може прийти кілька разів — наприклад, якщо ви обробили повідомлення, але ваша відповідь не дійшла. Відкидайте дублікати за message.pagerMessageId.

Вихідні: Pager → ваш сервер

Приклад обробника

Мінімальний обробник: перевіряє ключ, відкидає повтори, передає повідомлення на вашу платформу й повертає його ідентифікатор.

import express from "express"

const app = express()
app.use(express.json())

// pagerMessageId -> externalMessageId. У продакшні — база або Redis
const processed = new Map()

app.post("/pager/outbound", async (req, res) => {
  // 1. Запит справді від Pager
  if (req.get("x-channel-key") !== process.env.PAGER_CHANNEL_KEY) {
    return res.status(401).end()
  }

  const { client, message } = req.body

  // 2. Повтор уже обробленого повідомлення
  if (processed.has(message.pagerMessageId)) {
    return res.json({ externalMessageId: processed.get(message.pagerMessageId) })
  }

  // 3. Відправка клієнту на вашій платформі
  const sent = await platform.sendMessage({
    to: client.externalId,
    text: message.text,
    attachments: message.attachments,
  })

  processed.set(message.pagerMessageId, sent.id)
  res.json({ externalMessageId: sent.id })
})
platform.sendMessage — ваш код відправки. Решту можна брати як є.

Довідка

Вкладення

Вкладення передаються масивом об'єктів { type, payload: { url } } — однаково у вхідних подіях і в запитах від Pager.

Поля

  • typeenumобов'язковий

    image, video, audio, document або file.

  • payload.urlstringобов'язковий

    Публічне посилання http(s) на файл, до 2000 символів.

attachments
[
  {
    "type": "image",
    "payload": {
      "url": "https://cdn.example.com/uploads/photo.jpg"
    }
  },
  {
    "type": "document",
    "payload": {
      "url": "https://cdn.example.com/uploads/invoice.pdf"
    }
  }
]
  • Pager зберігає посилання, а не копію файлу, тож воно має лишатися доступним, поки менеджерам потрібна історія розмови.
  • Посилання на localhost і внутрішні мережі (127.*, 10.*, 192.168.*) Pager мовчки відкидає, решта повідомлення зберігається.
  • До 20 вкладень в одному повідомленні.
  • У запитах від Pager посилання тимчасові й діють 24 години — завантажуйте файли одразу.
Не знайшли відповіді?Напишіть нам
Кастомні канали — документація Pager