Центр допомоги Інтеграція Meta & Instagram API

Інтеграція Meta & Instagram API

Довідка для створення програми Instagram на платформі SMSBAT ChatHub: автентифікація, Бесіди в Instagram Direct, коментарі до публікацій і барабанів, відповіді на історії, веб-хуки та опитування.

Джерела

Ця сторінка об’єднує внутрішню специфікацію Meta Comments API з живим OpenAPI визначення на https://chatapi.smsbat.com/swagger/v1/swagger.json і https://restapi.smsbat.com/swagger/v1/swagger.json. Там, де обидва не згодні, відмінність викликається в рядку та перераховується під Відкритими запитаннями.


1. Базові URL-адреси

ПризначенняURL
API чату + API метаhttps://chatapi.smsbat.com
Swagger UI / OpenAPIhttps://chatapi.smsbat.com/index.html · …/swagger/v1/swagger.json
REST API (організації, URL-адреси зворотного виклику)https://restapi.smsbat.com
REST API Swaggerhttps://restapi.smsbat.com/swagger/v1/swagger.json
Веб-панель оператораhttps://chat.smsbat.com

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

Схема авторизації залежить від групи кінцевих точок. Їх змішування є найпоширенішою причиною 401.

ГрупаЗаголовок
chatapi.smsbat.com/api/meta/* (дописи, коментарі)X-Authorization-Key: <organization token>
chatapi.smsbat.com/api/chat/*, /api/company/*, /api/operator/*Authorization: Bearer <JWT>
restapi.smsbat.com/*X-Authorization-Key · Authorization: Bearer · Основна авторизація

Маркер організації для X-Authorization-Key видається на панелі в розділі Профіль. JWT компанії та оператора походять із /api/company/get-token та /api/operator/get-token.

Невідповідність

Документ chatapi OpenAPI оголошує єдину схему безпеки — Bearer — і застосовує її глобально. X-Authorization-Key там взагалі не оголошено, хоча внутрішній Meta Специфікація API коментарів називає його /api/meta/*. Це, швидше за все, обробляється проміжне програмне забезпечення, яке не відображається в Swagger. Підтвердьте емпірично перед відправкою.

2.1 Маркер компанії

POST https://chatapi.smsbat.com/api/company/get-token
Content-Type: application/json

{ "login": "company_login", "password": "company_password" }

200 OK повертає голий рядок маркера.

2.2 Організації

GET https://chatapi.smsbat.com/api/company/organization
Authorization: Bearer <company_token>
[ { "id": 24, "name": "My Instagram Store" } ]

2.3 Оператори в організації

GET https://chatapi.smsbat.com/api/operator?organizationId=24
Authorization: Bearer <company_token>
[
  {
    "id": 21,
    "name": "Jane Doe",
    "status": 0,
    "organization": { "id": 24, "name": "My Instagram Store" }
  }
]

Статуси оператора: 0 Активний, 1 Неактивний, 2 Видалений.

2.4 Додати/синхронізувати оператори

POST https://chatapi.smsbat.com/api/operator/synchronize
Authorization: Bearer <company_token>
Content-Type: application/json

[ { "organizationId": 24, "name": "John Operator" } ]

200 OK → [ { "id": 21, "status": 0, "name": "John Operator" } ]

2.5 Оператор JWT

POST https://chatapi.smsbat.com/api/operator/get-token
Authorization: Bearer <company_token>
Content-Type: application/json

{ "id": 21, "expiresAt": "2026-12-31T23:59:59.000Z" }

200 OK повертає JWT як рядок.

2.6 Перевірте маркер оператора

POST https://chatapi.smsbat.com/api/operator/validate-token
Authorization: Bearer <company_token>
Content-Type: application/json

"eyJhbGciOi..."
{
  "isValid": true,
  "operatorId": 21,
  "clientId": 0,
  "expiresAt": "2026-12-31T23:59:59.000Z",
  "error": null
}

Якщо недійсний: { "isValid": false, "error": "Invalid token" }.

2.7 Вставте панель чату оператора

<script type="module" id="operator-chat-panel-script"
  src="https://widget.smsbat.com/operator-chat-panel/widget-script.js"
  token="YOUR_OPERATOR_JWT_TOKEN"></script>

3. Посилання на панель чату

Зовнішня система (CRM, ERP, веб-сайт) може відкрити певну бесіду в https://chat.smsbat.com/. Оператор авторизується JWT, переданим як параметр запиту.

https://chat.smsbat.com/?chat_raw_id=<chat_id>&token=<jwt>
https://chat.smsbat.com/?phone=<phone>&token=<jwt>
https://chat.smsbat.com/?from=<bm_id>&phone=<phone>&token=<jwt>
https://chat.smsbat.com/?source=7&from=<bm_id>&phone=<phone>&token=<jwt>
ПараметрОпис
chat_raw_idID чату
phoneНомер телефону в міжнародному форматі
fromІдентифікатор бренду/бізнес-облікового запису (bm_id)
sourceДжерело чату — 7 для Instagram, див. §8.1
tokenДійсний, непрострочений оператор JWT з доступом до чатів

Недійсний JWT спрямовує відвідувача на екран входу в панель оператора.


4. Прямі розмови в Instagram

4.1 Список чатів

GET https://chatapi.smsbat.com/api/chat/chats?source=7&page=1&per_page=20
Authorization: Bearer <token>

Note

Пагінація тут per_page (snake_case). Під /api/meta/* і опитування кінцевою точкою є perPage (camelCase). Це не помилка — API використовує обидва.

Параметри запиту, усі необов’язкові:

ПараметрТипОпис
sourceChatSource7 обмежує результати Instagram
entityIdintІдентифікатор бізнес-облікового запису. Застосовується лише разом із source
instagram_user_idintІдентифікатор користувача Instagram у ChatHub
facebook_user_idintІдентифікатор користувача Facebook у ChatHub
page / per_pageintПагінація, за замовчуванням 1 / 20
statusChatStatus[]Статус чату, повторюється
searchstringПошук у довільному тексті (ім’я, телефон, …)
organizationIdintID організації
operatorIdint[]Фільтрувати за призначеними операторами
datestring[]Дві межі: ?date=…&date=…
isChainboolПовертати чати як ланцюжки, що містять повідомлення з попередніх чатів
isUnread, starMark, isOperator, isAIAgentboolДодаткові фільтри
phone, email, contactId, clientId, tagIds, rate, sortedBy—Інші фільтри

200 OK повертає GetChatsResponse:

{
  "total": 1,
  "newMessagesCount": 2,
  "items": [
    {
      "id": 1867,
      "theme": null,
      "messSource": 7,
      "chatStatus": 1,
      "countUnread": 2,
      "metaUserId": "1585775752382460",
      "instaAccount": { "id": 12, "name": "my_instagram_shop", "photo": "https://..." },
      "instagramUser": { "id": 123, "name": "marianna_cat", "photo": "https://..." },
      "operator": { "id": 21, "name": "Jane", "photo": "https://..." },
      "client": { "id": 55, "name": "Marianna", "photo": null },
      "textLastMess": "Hello! Is this product available?",
      "timeLastMess": "2026-08-13T10:15:00Z",
      "authorLastMessage": 1,
      "messageStatus": 6,
      "isMedia": false,
      "phone": null,
      "organizationId": 1,
      "createdAt": "2026-08-13T10:14:00Z",
      "isStarred": false,
      "isBlocked": false,
      "tags": []
    }
  ]
}

Поля, важливі для програми Instagram:

ПолеЗначення
instaAccountБізнес-акаунт Instagram (магазин). id – значення фільтра entityId; name – це ім’я облікового запису з Meta
instagramUserКлієнт. name – дескриптор Instagram, id – значення фільтра instagram_user_id
metaUserIdІдентифікатор області дії клієнта на стороні Meta (рядок)
messSource7 для Instagram
phoneЗазвичай null для Instagram — не використовуйте його як ключ

ChatDTO також містить olxUser, promUser, waba, rozetkaUser, facebookAccount, facebookUser, viberAccount, tgBot, tgUser, viberBot, viberBotUser, widget, media, isConnectedAI, isPromo, rate, rateComment, closedBy, draft, lang, starMark, contactId, contactName, block, isInStopList, stopList, isSmsFallbackEnabled та taggedMessages.

4.2 Повідомлення чату

GET https://chatapi.smsbat.com/api/chat/chats/1867/messages?isChain=false
Authorization: Bearer <token>

200 OK повертає масив ChatMessageDTO:

[
  {
    "id": 9928,
    "chatId": 1867,
    "message": "Hi! Do you have size M in stock?",
    "messageTranslation": null,
    "phone": null,
    "author": 1,
    "source": 7,
    "media": null,
    "replyTo": null,
    "status": 6,
    "date": "2026-08-13T10:14:00Z",
    "operator": null,
    "client": { "id": 123, "name": "marianna_cat", "photo": "https://..." },
    "messageType": 0,
    "isInternal": false,
    "isBroadcast": false,
    "starMark": false,
    "referralGuid": null,
    "postId": null,
    "isConnectedAI": false,
    "organizationId": 1,
    "countUnreadMessages": 0
  }
]

postId заповнюється, коли повідомлення стосується публікації в Instagram або історії — передайте його назад як id / postId до Meta API. media є ChatMediaDTO: { name, format, type, uri, raw, length, isUploaded }.

4.3 Надіслати повідомлення (JSON)

POST https://chatapi.smsbat.com/api/chat/1867/message
Authorization: Bearer <token>
Content-Type: application/json

Тіло — SendChatMessageDTO:

{
  "textMessage": "Hello! Yes, size M is available.",
  "author": 0,
  "isInternal": false,
  "replyToMessageId": 9928,
  "appGuid": "550e8400-e29b-41d4-a716-446655440000",
  "media": {
    "name": "item.jpg",
    "format": "image/jpeg",
    "dataBase64": "/9j/4AAQSkZJRg...",
    "type": 1
  }
}
ПолеТипОпис
textMessagestring?Текст повідомлення. Може бути порожнім, якщо присутній media
authorAuthorMessage?0 оператор, 1 клієнт
isInternalbool?true позначає внутрішню примітку, яка не доставлена ​​клієнту
replyToMessageIdint?ID повідомлення, на яке відповідає
appGuiduuid?Реферальний GUID
mediaMediaDTO?{ name, format, dataBase64, thumbnail, duration, type }

200 OK → { "id": 9930, "messageStatus": 0 }

GUID направлення також може передаватися в шляху: POST /api/chat/{chatId}/{referralGuid}/message (також …/message/v1, …/message/v2).

4.4 Надіслати файл або відео (багаточастинний, v2)

POST https://chatapi.smsbat.com/api/chat/1867/message/v2
Authorization: Bearer <token>
Content-Type: multipart/form-data

Назви полів форми мають регістр Pascal із крапковою нотацією

textMessage та media.file мовчки ігноруються. Використовуйте точні назви нижче.

Поле формиТипОпис
TextMessagestringТекст повідомлення
Authorint0 оператор, 1 клієнт
IsInternalboolВнутрішня примітка
ReplyToMessageIdintПовідомлення, на яке відповідає
AppGuiduuidРеферальний GUID
Media.FilebinaryСам файл
Media.NamestringІм’я файлу
Media.FormatstringТип MIME (video/mp4, image/png, application/pdf)
Media.TypeMediaTypeДив. §8.5
Media.DataBase64stringАльтернатива Media.File
Media.ThumbnailstringКадр попереднього перегляду відео Base64
Media.DurationdoubleТривалість відео в секундах
curl -X POST "https://chatapi.smsbat.com/api/chat/1867/message/v2" \
  -H "Authorization: Bearer <token>" \
  -F "TextMessage=Here is the price list" \
  -F "Author=0" \
  -F "Media.Type=2" \
  -F "Media.File=@./price.pdf"

200 OK → { "id": 9931, "messageStatus": 0 }

4.5 Змінити статус чату

PUT https://chatapi.smsbat.com/api/chat/status
Authorization: Bearer <token>
Content-Type: application/json

{ "id": 1867, "status": 4 }

200 OK повторює оновлений об’єкт.

4.6 Оновлення статусів повідомлень

PUT https://chatapi.smsbat.com/api/chat/messages/status
Authorization: Bearer <token>
Content-Type: application/json

{ "status": 3, "messageIds": [9928, 9929] }

4.7 Видалити чат

DELETE https://chatapi.smsbat.com/api/chat/chats/1867
Authorization: Bearer <token>

5. Пости, ролики та історії

Основний шлях: https://chatapi.smsbat.com/api/meta Авторизація: X-Authorization-Key: <organization token>

5.1 Список дописів, роликів і історій

GET https://chatapi.smsbat.com/api/meta/posts?platform=instagram&mediaType=story&page=1&perPage=20
X-Authorization-Key: <token>
ПараметрТипНеобхідноОпис
pageintніСторінка, за замовчуванням 1
perPageintніЕлементів на сторінці, за замовчуванням 20
idintніФільтрувати за ідентифікатором внутрішньої публікації
platformstringніinstagram або facebook
mediaTypestringніpost, reel або story. Усі типи, якщо опущено
# Every post
curl -H "X-Authorization-Key: <token>" \
  "https://chatapi.smsbat.com/api/meta/posts?page=1&perPage=10"

# Instagram only
curl -H "X-Authorization-Key: <token>" \
  "https://chatapi.smsbat.com/api/meta/posts?platform=instagram"

# A single post by ID
curl -H "X-Authorization-Key: <token>" \
  "https://chatapi.smsbat.com/api/meta/posts?id=42"

# Instagram Stories only
curl -H "X-Authorization-Key: <token>" \
  "https://chatapi.smsbat.com/api/meta/posts?platform=instagram&mediaType=story"

200 OK:

{
  "total": 42,
  "items": [
    {
      "id": 42,
      "metaId": "18113450675314072",
      "text": "Check out our new collection!",
      "imageUrl": "https://dashboard.smsbat.com/api/meta/post/media/7d124c36-1711-4aa8-b21d-f6dbf8f347ef",
      "platform": "instagram",
      "mediaType": "story",
      "createdAt": "2026-07-22T09:35:30Z",
      "story": {
        "id": 42,
        "metaId": "18113450675314072",
        "url": "https://dashboard.smsbat.com/api/meta/post/media/7d124c36-1711-4aa8-b21d-f6dbf8f347ef"
      }
    }
  ]
}

Розбіжність — назва поля лічильника

Схема Swagger MetaCommentPostListItemDtoPaginationDTO визначає total. The внутрішні специфікаційні документи totalCount. Swagger генерується з коду, отже total є більш імовірною правдою. Розбирайте total ?? totalCount, поки це не буде вирішено.

ПолеОпис
idID внутрішньої посади
metaIdЗовнішня публікація / Котушка / Ідентифікатор історії в мета
textПідпис до повідомлення
imageUrlURL-адреса медіа-проксі-сервера з непослідовним ключем MetaPost.Guid або null
platformfacebook або instagram
mediaTypepost, reel або story
createdAtДата створення (дата платформи або дата бази даних)
storyПодаруйте лише за mediaType: "story"
story.idІдентифікатор внутрішньої історії; дорівнює post.id
story.metaIdЗовнішній ідентифікатор історії в мета
story.urlСтабільна URL-адреса проксі-сервера збережених носіїв історії; null, якщо медіа не вдалося зберегти

Пошта обслуговується двома маршрутами: GET /api/meta/post/media/{id:int} для зворотного зв’язку сумісність і GET /api/meta/post/media/{guid:guid}. Нові відповіді API та зворотні виклики завжди створюйте форму GUID.

5.2 Список коментарів

GET https://chatapi.smsbat.com/api/meta/comments?platform=instagram&postId=42&page=1&perPage=20
X-Authorization-Key: <token>
ПараметрТипНеобхідноОпис
pageintніСторінка, за замовчуванням 1
perPageintніЕлементи на сторінці, за замовчуванням 20
postIdintніФільтрувати за ID повідомлення
parentCommentIdintніДочірні коментарі (відповіді) на даний коментар
platformstringніfacebook або instagram

200 OK:

{
  "total": 100,
  "items": [
    {
      "id": 5,
      "metaId": "179000000000005",
      "text": "What is the price?",
      "createdAt": "2026-04-15T10:30:00Z",
      "platform": "instagram",
      "replyStatus": null,
      "author": {
        "type": "meta_user",
        "name": "John Doe",
        "metaUserId": "1585775752382460"
      },
      "post": {
        "id": 1,
        "metaId": "18113450675314072",
        "text": null,
        "imageUrl": "https://dashboard.smsbat.com/api/meta/post/media/7d124c36-…",
        "createdAt": "2026-07-22T09:35:30Z",
        "mediaType": "story",
        "story": {
          "id": 1,
          "metaId": "18113450675314072",
          "url": "https://dashboard.smsbat.com/api/meta/post/media/7d124c36-…"
        }
      },
      "mediaUrl": "https://chatapi.smsbat.com/api/meta/comment/media/5",
      "replyTo": {
        "id": 3,
        "metaId": "179000000000003",
        "text": "Parent comment..."
      }
    }
  ]
}
ПолеОпис
idID внутрішнього коментаря
metaIdЗовнішній ідентифікатор у Мета. null за нашу відповідь, що очікує на розгляд, поки її не буде надіслано
textТекст коментаря
createdAtДата створення
platformfacebook або instagram
replyStatusnull для вхідного коментаря користувача; "pending" / "sent" / "failure" за нашу відповідь
author.type"meta_user" зовнішній користувач, "owner" власник сторінки
author.nameІм’я автора
author.metaUserIdІдентифікатор користувача з областю дії в мета; null для "owner"
postПублікація, ролик або історія, до якої належить коментар
post.mediaTypepost, reel або story
post.storyПосилання на історію { id, metaId, url }, лише історії
mediaUrlДо коментаря додається медіа, або null
replyToБатьківський коментар { id, metaId, text }; null на верхньому рівні

Невідповідність — тип `author.type`

Внутрішня специфікація документує рядки "meta_user" / "owner". Типи пихатості MetaCommentAuthorType як ціле число з переліком [0, 1]. A JsonStringEnumConverter пояснив би розрив, але це не було підтверджено реальною відповіддю. Напишіть a аналізатор, який приймає обидва.

5.3 Відповідь на коментар

Поставте відповідь у чергу для доставки.

curl -X POST \
  -H "X-Authorization-Key: <token>" \
  -H "Content-Type: application/json" \
  -d '{"text": "Thanks for the feedback!"}' \
  "https://chatapi.smsbat.com/api/meta/comments/5/reply"

Тіло запиту: { "text": "Reply text" }

202 Accepted повертає об’єкт коментаря — такої ж форми, як GET /api/meta/comments — з replyStatus: "pending" та metaId: null. Результат доставки надходить пізніше як a Зворотний виклик source: 13 (§6.4).

Невідповідність — код відповіді

Суагер заявляє 200 без тіла; у внутрішній специфікації зазначено 202 Accepted з коментарем як тілом. Контролер, швидше за все, не має ProducesResponseType атрибут, залишаючи Swagger за замовчуванням. Приймайте будь-які 2xx і не залежайте від тіла.


6. Вебхуки

SMSBAT надсилає POST запитів із application/json на вашу URL-адресу та очікує HTTP 200 назад.

Пульові поля повністю опущено

Поле зі значенням null взагалі не серіалізується в тіло зворотного виклику. для a повідомлення, яке надійшло не з Facebook чи Instagram, просто немає ключа MetaUserId. Розглядайте “відсутній” і null як одне й те саме.

6.1 Зареєструйте URL зворотного виклику

curl -X POST 'https://restapi.smsbat.com/organizations/callback_urls' \
  -H 'X-Authorization-Key: <token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://your-server.com/webhook",
    "source": 12,
    "headerName": "X-Webhook-Secret",
    "headerValue": "your-secret",
    "channelType": 7,
    "channelEntityId": 12
  }'
ПолеТипОпис
urlstringВаша кінцева точка
sourceSendingSourceCallbackТип події, див. §8.2
headerName / headerValuestringДовільний заголовок авторизації, який ми додаємо до запиту (необов’язково)
channelTypeChatSourceКанал. 7 для Instagram. Необов’язковий
channelEntityIdintКонкретний бізнес-акаунт. Потрібен channelType

Без channelType URL-адреса отримує події з кожного каналу.

Tip

Для повного охоплення коментарів потрібні дві реєстрації: source: 12 для нових коментарів і source: 13 для статусів відповідей. Для відповідей Direct та Story додайте source: 3 (і 11, якщо ви хочете отримати кожне повідомлення чату).

Решта операцій:

GET    https://restapi.smsbat.com/organizations/callback_urls?source=12
GET    https://restapi.smsbat.com/organizations/callback_urls/{id}
PUT    https://restapi.smsbat.com/organizations/callback_urls/{id}
DELETE https://restapi.smsbat.com/organizations/callback_urls/{id}

GET повертає:

[
  {
    "id": 101,
    "url": "https://your-server.com/webhook",
    "source": 12,
    "headerName": "X-Webhook-Secret",
    "headerValue": "your-secret",
    "createdAt": "2026-08-13T09:00:00Z",
    "channelType": 7,
    "channelEntityId": 12
  }
]

6.2 Нове повідомлення та відповідь на Instagram Story (source: 3, 11)

Відповідь користувача на Історію Instagram надходить як звичайне повідомлення в цих зворотних викликах, з додатковим блоком верхнього рівня Story:

{
  "ChatId": 123,
  "MessageId": 456,
  "MessageText": "😍",
  "Username": "Jane Smith",
  "UserId": 789,
  "MetaUserId": "1585775752382460",
  "ShopId": 12,
  "ShopName": "instagram shop name",
  "Author": 0,
  "type_messenger": 7,
  "Story": {
    "Id": 42,
    "MetaId": "18113450675314072",
    "Url": "https://dashboard.smsbat.com/api/meta/post/media/7d124c36-1711-4aa8-b21d-f6dbf8f347ef"
  }
}
ПолеОпис
ChatId / MessageIdІдентифікатори чату та повідомлень
Author0 користувач, 1 оператор
UsernameВідображуване ім’я або дескриптор Instagram/Facebook
UserIdВнутрішній числовий ідентифікатор користувача в SMSBAT
MetaUserIdОхоплений ідентифікатор співрозмовника в Meta. У вихідному повідомленні оператора це все ще ідентифікує мета-користувача чату, а не оператора
ShopIdВнутрішній ідентифікатор бізнес-облікового запису Instagram / Facebook
ShopNameНазва бізнес-облікового запису, отримана від Meta під час підключення
MessageTextТекст повідомлення
MessageMediaURL-адреса медіа, якщо повідомлення є медіа
type_messengerДжерело, 7 для Instagram
operator_nameІм’я оператора, коли Author = 1
StoryПоказувати тільки у вхідній відповіді Story
Story.IdІдентифікатор внутрішньої історії (MetaPost) — можна використовувати безпосередньо як id / postId у Meta API
Story.MetaIdЗовнішній ідентифікатор історії в мета
Story.UrlСтабільна URL-адреса проксі-сервера збережених носіїв Story. Відсутній, коли медіа не вдалося зберегти — блок Story і повідомлення все ще доставляються

`Author` інвертується відносно API чату

У ChatMessageDTO.author 0 означає оператора, а 1 означає клієнта. У цьому зворотному виклику це так навпаки: 0 – користувач, 1 – оператор. Не поширюйте відображення.

6.3 Новий коментар (source: 12)

Спрацьовує, коли користувач Meta коментує публікацію у Facebook або Instagram / Reel.

Note

Instagram Відповіді на історію не доставляються через source: 12. Вони надходять як звичайні вхідні повідомлення на source: 3 та/або 11 з блоком Story — див. §6.2.

{
  "type": "new_comment",
  "platform": "instagram",
  "comment": {
    "id": 10,
    "metaId": "179000000000010",
    "parentCommentId": 5,
    "parentMetaId": "179000000000005",
    "parentCommentText": "The user's previous comment",
    "text": "Great product!",
    "createdAt": "2026-04-16T12:00:00Z",
    "author": {
      "type": "meta_user",
      "name": "Jane Smith",
      "metaUserId": "1585775752382460"
    }
  },
  "post": {
    "id": 1,
    "metaId": "123456789012345",
    "text": "Post description...",
    "imageUrl": "https://dashboard.smsbat.com/api/meta/post/media/7d124c36-…",
    "createdAt": "2026-04-10T12:00:00Z",
    "mediaType": "post"
  }
}

6.4 Статус відповіді на коментар (source: 13)

Спрацьовує після того, як ми намагаємось надіслати відповідь, незалежно від того, вдалось це чи не вдалося.

{
  "type": "comment_status",
  "platform": "instagram",
  "comment": {
    "id": 15,
    "metaId": "179000000000015",
    "parentCommentId": 10,
    "parentMetaId": "179000000000010",
    "parentCommentText": "Great product!",
    "text": "Thanks for the feedback!",
    "createdAt": "2026-04-16T12:05:00Z",
    "updatedAt": "2026-04-16T12:05:03Z",
    "replyStatus": "sent",
    "author": {
      "type": "owner",
      "name": "Support Agent"
    }
  },
  "post": {
    "id": 1,
    "metaId": "179999999999999",
    "text": "Reel description...",
    "imageUrl": "https://dashboard.smsbat.com/api/meta/post/media/7d124c36-…",
    "createdAt": "2026-07-22T09:35:30Z",
    "mediaType": "reel"
  }
}

6.5 Спільні поля зворотного виклику коментарів

Обидва зворотні виклики коментарів мають одну форму тіла і відрізняються лише на type.

ПолеОпис
type"new_comment" або "comment_status"
platform"facebook" або "instagram"
comment.idID внутрішнього коментаря
comment.metaIdЗовнішній ідентифікатор у мета; null для очікуваної відповіді перед її відправленням
comment.parentCommentIdID батьківського коментаря. Відсутній для коментаря вищого рівня
comment.parentMetaIdІдентифікатор зовнішнього батьківського коментаря. Відсутній на вищому рівні
comment.parentCommentTextТекст коментаря батьків. Відсутній на вищому рівні
comment.textТекст коментаря
comment.createdAtДата створення
comment.updatedAtОстаннє оновлення. Відсутній, якщо коментар ніколи не редагувався
comment.replyStatus"pending" / "sent" / "failure". Відсутній для вхідного коментаря користувача
comment.author.type"meta_user" або "owner"
comment.author.nameІм’я автора
comment.author.metaUserIdІдентифікатор автора з областю дії в мета. Відсутній протягом "owner"
comment.mediaUrlКоментуйте ЗМІ. Відсутній, коли немає
post.idID внутрішньої посади
post.metaIdЗовнішня публікація / Котушка / Ідентифікатор історії в мета
post.textТекст публікації
post.imageUrlОпублікуйте URL-адресу зображення або null
post.createdAtДата створення публікації
post.mediaTypeУ зворотних викликах коментарів лише post або reel

6.6 Новий чат (source: 7)

{ "ChatId": 12345, "Phone": "+380501234567", "chat.Source": 7 }

6.7 Зміна статусу повідомлень і чату (source: 6 / 5)

{ "name": "changed_message_status", "id": 9928, "status": 6 }
{ "name": "changed_chat_status",    "id": 1867, "status": 4 }

6.8 Повідомлення відредаговано або видалено (source: 9)

{ "messageId": 9930, "text": "Updated message text" }
{ "messageId": 9931, "delete": true }

6.9 Індикатор набору тексту (source: 8)

{ "chat_id": 1867, "event": "start_typing", "operator_name": "Iryna" }
{ "chat_id": 1867, "event": "end_typing" }

7. Опитування подій

Для середовищ, які не можуть приймати вхідний HTTP.

7.1 Отримання подій

GET https://chatapi.smsbat.com/api/chat/callback-events?page=1&perPage=20
Authorization: Bearer <token>
ПараметрОпис
organizationIdДодатково. Взято з лексеми, якщо опущено
page / perPageПагінація, за замовчуванням 1 / 20
{
  "page": 1,
  "perPage": 20,
  "total": 947,
  "items": [
    {
      "ChatId": 1867,
      "MessageId": 9928,
      "MessageText": "Hello there!",
      "MessageMedia": null,
      "Phone": null,
      "Username": "marianna_cat",
      "UserId": 123,
      "ShopId": 12,
      "ShopName": "instagram shop name",
      "Author": 1,
      "type_messenger": 7,
      "message_date": "2026-08-13T12:27:39.724Z",
      "timestamp": "2026-08-13T12:27:39.736Z",
      "event_guid": "ff60129e-c6e4-4876-9d90-badb430c0606",
      "organization_id": 1,
      "callback_type": "3"
    }
  ]
}

Кожна подія містить event_guid, timestamp, organization_id та callback_type — рядок, що відповідає значенням source у §8.2. Решта полів відповідають відповідним вебхук у §6.

7.2 Підтвердження оброблених подій

POST https://chatapi.smsbat.com/api/chat/callback-events/processed
Authorization: Bearer <token>
Content-Type: application/json

[ "ff60129e-c6e4-4876-9d90-badb430c0606" ]

200 OK → { "deleted": 1 }

Події, які вже видалено, просто не зараховуються до deleted. Замовлення та повторні спроби за вами відповідальність сторони.

7.3 Рекомендований цикл

  1. Опитування GET /api/chat/callback-events за розкладом.
  2. Обробка подій у вашому сервісі.
  3. Надішліть оброблений список event_guid на /callback-events/processed.
  4. Повторіть.

8. Посилання на Enum

8.1 ChatSource — канал (0–9)

КодКанал
0Viber
1ViberBot
2TelegramBot
3Whatsapp
4Віджет
5Розетка
6Facebook
7Instagram
8Випускний
9Olx

8.2 SendingSourceCallback — тип події зворотного виклику (0–13)

КодПодія
3Chat — нове повідомлення в чаті, включаючи відповіді на історію
5Статус чату змінено
6Статус повідомлення змінено
7Створено новий чат
8Індикатор набору
9Повідомлення оновлено або видалено
11AnyChatMessage — будь-яке повідомлення чату
12MetaNewComment — новий коментар в Instagram / Facebook
13MetaCommentStatus — статус доставки нашої відповіді на коментар

Перелік охоплює 0–13; решта значень не потрібні для інтеграції з Instagram.

8,3 ChatStatus (0–4)

0 Нове, 1 Відкрито, 2 Очікування, 3 На паузі, 4 Закрито

8,4 MessageStatus (0–11)

КодІм’я
0НОВИЙ
1УСПІХ
2ВІДХИЛЕНО
3ПРОЧИТАТИ
4НЕВІДОМО
5ОБРОБКА
6ДОСТАВЛЕНО
7BLOCKED_BY_USER
8USER_NOT_FOUND

Перелік охоплює 0–11. Значення 9, 10 і 11 існують в API, але ще не задокументовані — розглядайте їх як UNKNOWN.

8,5 MediaType (1–10)

1 Фото, 2 Файл, 3 Аудіо, 4 Відео, 5 Наклейка, 6 Наклейка Анімована, 7 StickerVideo, 8 Animation, 9 Voice, 10 VideoNote

8.6 AuthorMessage — автор в Chat API (0–4)

0 Оператор, 1 Клієнт, 2 Бот, 3 ViberAccount

Перелік охоплює 0–4; значення 4 не задокументовано. Зворотні виклики “нове повідомлення” використовують протилежне відображення — див. §6.2.

8,7 ChatMessageType (0–2)

0 Текст, 1 Фото, 2 Файл

8.8 Коментар replyStatus

null вхідний коментар користувача, "pending" наша відповідь у черзі, "sent" доставлено, Помилка доставки "failure".


Відкриті питання

Три пункти, де внутрішня специфікація та згенерований код Swagger розходяться. Один запит із реальним токеном розраховує їх усі; до того часу пишіть клієнту в захисті.

#ПитанняСпецифікаціяЧванствоЯк перевірити
1Заголовок авторизації для /api/meta/*X-Authorization-Keyлише Bearer заявленоcurl -i -H "X-Authorization-Key: <token>" ".../api/meta/posts?perPage=1" — очікуйте 200, а не 401
2Поле лічильника в метавідповідяхtotalCounttotalТой самий запит — прочитати кореневий ключ JSON
3author.type тип і reply код статусу"meta_user" / "owner", 202 з корпусомint [0,1], 200 без тілаcurl -i .../api/meta/comments?perPage=1 плюс тестова відповідь

Тимчасове керівництво:

  • лічильник — читання total ?? totalCount;
  • author.type — приймати як рядок, так і ціле число (0 ↔ meta_user, 1 ↔ owner, відображення потрібно підтвердити);
  • reply — розглядати будь-який 2xx як успішний, не вимагати тіла, отримати кінцевий статус із зворотного виклику source: 13.

Примітки щодо впровадження

  • Автентифікація залежить від групи кінцевих точок — /api/meta/* використовує X-Authorization-Key, чати та оператори використовують Bearer, restapi приймає будь-який.
  • Позначення сторінок пишеться двома способами — per_page на /api/chat/chats, perPage на /api/meta/* і /api/chat/callback-events.
  • Поля multipart/form-data мають регістр Pascal із крапковою нотацією (Media.File, Media.Type).
  • Пульові поля пропускаються у зворотних викликах — відсутність ключа означає null.
  • phone зазвичай це null в Instagram. Ідентифікуйте клієнта за номером instagramUser.id / metaUserId та магазин за instaAccount.id (значення фільтра entityId).
  • Story.Id із зворотного виклику можна передати прямо назад як id / postId до Meta API.
  • Перевірте expiresAt оператора JWT, перш ніж використовувати його в глибокому посиланні або віджеті.