Integrare API Meta și Instagram
Referință pentru construirea unei aplicații Instagram pe SMSBAT ChatHub Platform: autentificare, Instagram Direct conversații, comentarii la postări și Reels, răspunsuri la povești, webhooks și sondaje.
Surse
Această pagină îmbină specificația internă Meta Comments API cu OpenAPI live
definiții la https://chatapi.smsbat.com/swagger/v1/swagger.json și
https://restapi.smsbat.com/swagger/v1/swagger.json. Acolo unde cei doi nu sunt de acord,
diferența este menționată în linie și listată sub Întrebări deschise.
1. URL-uri de bază
| Scop | URL |
|---|---|
| Chat API + Meta API | https://chatapi.smsbat.com |
| Swagger UI / OpenAPI | https://chatapi.smsbat.com/index.html · …/swagger/v1/swagger.json |
| API REST (organizații, adrese URL de apel invers) | https://restapi.smsbat.com |
| REST API Swagger | https://restapi.smsbat.com/swagger/v1/swagger.json |
| Panoul web al operatorului | https://chat.smsbat.com |
2. Autentificare
Schema de autentificare depinde de grupul de puncte finale. Amestecarea lor este cea mai frecventă cauză a 401.
| Grupa | Antet |
|---|---|
chatapi.smsbat.com/api/meta/* (postări, comentarii) | 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 · Autentificare de bază |
Jetonul de organizare pentru X-Authorization-Key este emis în panoul de sub Profil.
JWT-urile companiei și ale operatorului provin din /api/company/get-token și /api/operator/get-token.
Discrepanță
Documentul chatapi OpenAPI declară o singură schemă de securitate — Bearer — și o aplică
la nivel global. X-Authorization-Key nu este deloc declarat acolo, deși Meta internă
Specificația API de comentarii o numește /api/meta/*. Cel mai probabil este tratat de
middleware care nu se reflectă în Swagger. Confirmați empiric înainte de a expedia.
2.1 Jeton de companie
POST https://chatapi.smsbat.com/api/company/get-token
Content-Type: application/json
{ "login": "company_login", "password": "company_password" }
200 OK returnează un șir de simbol liber.
2.2 Organizații
GET https://chatapi.smsbat.com/api/company/organization
Authorization: Bearer <company_token>
[ { "id": 24, "name": "My Instagram Store" } ]
2.3 Operatori într-o organizație
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" }
}
]
Stare operator: 0 Activ, 1 Inactiv, 2 Șters.
2.4 Adăugați/sincronizați operatori
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 Operator 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 returnează JWT ca șir.
2.6 Validarea unui jeton de operator
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
}
Când nu este valid: { "isValid": false, "error": "Invalid token" }.
2.7 Încorporați panoul de chat al operatorului
<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. Deeplinks în panoul de chat
Un sistem extern (CRM, ERP, site web) poate deschide o anumită conversație în
https://chat.smsbat.com/. Operatorul este autorizat printr-un JWT transmis ca parametru de interogare.
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>
| Parametru | Descriere |
|---|---|
chat_raw_id | ID chat |
phone | Număr de telefon în format internațional |
from | Identificator de marcă/cont de afaceri (bm_id) |
source | Sursă de chat — 7 pentru Instagram, vezi §8.1 |
token | Operator JWT valid, neexpirat, cu acces la chat |
Un JWT nevalid aterizează vizitatorul pe ecranul de conectare al panoului operator.
4. Instagram Conversații directe
4.1 Listează chat-urile
GET https://chatapi.smsbat.com/api/chat/chats?source=7&page=1&per_page=20
Authorization: Bearer <token>
Note
Paginarea aici este per_page (caz_șarpe). Sub /api/meta/* și sondajul
punctul final este perPage (camelCase). Aceasta nu este o greșeală de tipar - API-ul le folosește pe ambele.
Parametri de interogare, toți opționali:
| Parametru | Tip | Descriere |
|---|---|---|
source | ChatSource | 7 restricționează rezultatele la Instagram |
entityId | int | ID-ul contului de companie. Se aplică numai împreună cu source |
instagram_user_id | int | ID utilizator Instagram în ChatHub |
facebook_user_id | int | ID utilizator Facebook în ChatHub |
page / per_page | int | Paginare, valori implicite 1 / 20 |
status | ChatStatus[] | Stare chat, repetabil |
search | string | Căutare în text liber (nume, telefon, …) |
organizationId | int | ID organizație |
operatorId | int[] | Filtrați după operatori alocați |
date | string[] | Două limite: ?date=…&date=… |
isChain | bool | Întoarce chat-urile ca lanțuri, purtând mesaje din chat-urile anterioare |
isUnread, starMark, isOperator, isAIAgent | bool | Filtre suplimentare |
phone, email, contactId, clientId, tagIds, rate, sortedBy | — | Alte filtre |
200 OK returnează 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": []
}
]
}
Câmpurile care contează pentru o aplicație Instagram:
| Câmp | Înțeles |
|---|---|
instaAccount | Contul de afaceri Instagram (magazinul). id este valoarea filtrului entityId; name este numele contului din Meta |
instagramUser | clientul. name este mânerul Instagram, id este valoarea filtrului instagram_user_id |
metaUserId | ID-ul de acoperire al clientului pe partea lui Meta (șir) |
messSource | 7 pentru Instagram |
phone | De obicei null pentru Instagram — nu o utilizați ca cheie |
ChatDTO mai conține 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 și taggedMessages.
4.2 Mesaje de chat
GET https://chatapi.smsbat.com/api/chat/chats/1867/messages?isChain=false
Authorization: Bearer <token>
200 OK returnează o matrice de 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 este populat atunci când mesajul se referă la o postare sau o poveste Instagram - transmiteți-o
direct înapoi ca id / postId la Meta API. media este un ChatMediaDTO:
{ name, format, type, uri, raw, length, isUploaded }.
4.3 Trimiteți un mesaj (JSON)
POST https://chatapi.smsbat.com/api/chat/1867/message
Authorization: Bearer <token>
Content-Type: application/json
Corpul — 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
}
}
| Câmp | Tip | Descriere |
|---|---|---|
textMessage | string? | Textul mesajului. Poate fi gol atunci când este prezent media |
author | AuthorMessage? | 0 operator, 1 client |
isInternal | bool? | true marchează o notă internă care nu este livrată clientului |
replyToMessageId | int? | ID-ul mesajului căruia i se răspunde |
appGuid | uuid? | GUID de referință |
media | MediaDTO? | { name, format, dataBase64, thumbnail, duration, type } |
200 OK → { "id": 9930, "messageStatus": 0 }
Un GUID de trimitere poate fi transmis și în calea:
POST /api/chat/{chatId}/{referralGuid}/message (la fel …/message/v1, …/message/v2).
4.4 Trimiteți un fișier sau un videoclip (multipart, v2)
POST https://chatapi.smsbat.com/api/chat/1867/message/v2
Authorization: Bearer <token>
Content-Type: multipart/form-data
Numele câmpurilor de formulare sunt PascalCase cu notație de puncte
textMessage și media.file sunt ignorate în tăcere. Folosiți numele exacte de mai jos.
| Câmp formular | Tip | Descriere |
|---|---|---|
TextMessage | string | Textul mesajului |
Author | int | 0 operator, 1 client |
IsInternal | bool | Notă internă |
ReplyToMessageId | int | Se răspunde la mesajul |
AppGuid | uuid | GUID de referință |
Media.File | binary | Fișierul în sine |
Media.Name | string | Nume fișier |
Media.Format | string | Tip MIME (video/mp4, image/png, application/pdf) |
Media.Type | MediaType | Vezi §8.5 |
Media.DataBase64 | string | Alternativă la Media.File |
Media.Thumbnail | string | Cadru de previzualizare video Base64 |
Media.Duration | double | Durata videoclipului în secunde |
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 Schimbați starea chatului
PUT https://chatapi.smsbat.com/api/chat/status
Authorization: Bearer <token>
Content-Type: application/json
{ "id": 1867, "status": 4 }
200 OK ecou obiectul actualizat.
4.6 Actualizați stările mesajelor
PUT https://chatapi.smsbat.com/api/chat/messages/status
Authorization: Bearer <token>
Content-Type: application/json
{ "status": 3, "messageIds": [9928, 9929] }
4.7 Ștergeți un chat
DELETE https://chatapi.smsbat.com/api/chat/chats/1867
Authorization: Bearer <token>
5. Postări, role și povești
Calea de bază: https://chatapi.smsbat.com/api/meta
Auth: X-Authorization-Key: <organization token>
5.1 Listează postări, role și povești
GET https://chatapi.smsbat.com/api/meta/posts?platform=instagram&mediaType=story&page=1&perPage=20
X-Authorization-Key: <token>
| Parametru | Tip | Necesar | Descriere |
|---|---|---|---|
page | int | nu | Pagina, implicit 1 |
perPage | int | nu | Articole pe pagină, implicit 20 |
id | int | nu | Filtrați după ID-ul postării interne |
platform | string | nu | instagram sau facebook |
mediaType | string | nu | post, reel sau story. Toate tipurile când sunt omise |
# 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"
}
}
]
}
Discrepanță — numele câmpului contorului
Schema Swagger MetaCommentPostListItemDtoPaginationDTO definește total. The
caietul de sarcini intern totalCount. Swagger este generat din cod, deci
total este adevărul cel mai probabil. Analizați total ?? totalCount până când acest lucru este rezolvat.
| Câmp | Descriere |
|---|---|
id | ID-ul postului intern |
metaId | Postare externă / Reel / ID de poveste în Meta |
text | Post legenda |
imageUrl | Adresa URL media proxy introdusă de codul non-secvențial MetaPost.Guid sau null |
platform | facebook sau instagram |
mediaType | post, reel sau story |
createdAt | Data creării (data platformei sau data bazei de date) |
story | Prezentați doar pentru mediaType: "story" |
story.id | ID intern al poveștii; egal cu post.id |
story.metaId | ID extern al poveștii în Meta |
story.url | Adresa URL proxy stabilă a conținutului media Story stocat; null dacă media nu a putut fi salvată |
Posta media este deservită de două rute: GET /api/meta/post/media/{id:int} pentru înapoi
compatibilitate și GET /api/meta/post/media/{guid:guid}. Noi răspunsuri API și apeluri inverse
generați întotdeauna formularul GUID.
5.2 Listați comentarii
GET https://chatapi.smsbat.com/api/meta/comments?platform=instagram&postId=42&page=1&perPage=20
X-Authorization-Key: <token>
| Parametru | Tip | Necesar | Descriere |
|---|---|---|---|
page | int | nu | Pagina, implicit 1 |
perPage | int | nu | Articole pe pagină, implicit 20 |
postId | int | nu | Filtrați după ID-ul postării |
parentCommentId | int | nu | Comentariile copilului (răspunsurile) la un comentariu dat |
platform | string | nu | facebook sau 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..."
}
}
]
}
| Câmp | Descriere |
|---|---|
id | ID comentariu intern |
metaId | ID extern în Meta. null pentru un răspuns în așteptare al nostru până când acesta este trimis |
text | Textul comentariului |
createdAt | Data creării |
platform | facebook sau instagram |
replyStatus | null pentru un comentariu primit de la utilizator; "pending" / "sent" / "failure" pentru răspunsul nostru |
author.type | "meta_user" utilizator extern, "owner" proprietarul paginii |
author.name | Numele autorului |
author.metaUserId | ID utilizator definit în Meta; null pentru "owner" |
post | Postarea, Reel sau Story îi aparține comentariului |
post.mediaType | post, reel sau story |
post.story | Referință povești { id, metaId, url }, numai povești |
mediaUrl | Media atașată comentariului sau null |
replyTo | Comentariu părinte { id, metaId, text }; null la nivel superior |
Discrepanță — tip de `author.type`
Specificația internă documentează șirurile "meta_user" / "owner". Tipuri de balonare
MetaCommentAuthorType ca întreg cu enumerarea [0, 1]. A JsonStringEnumConverter
ar explica decalajul, dar acest lucru nu a fost confirmat împotriva unui răspuns real. Scrie a
parser care acceptă ambele.
5.3 Răspundeți la un comentariu
Pune în coadă un răspuns pentru livrare.
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"
Corpul cererii: { "text": "Reply text" }
202 Accepted returnează obiectul de comentariu — aceeași formă ca GET /api/meta/comments — cu
replyStatus: "pending" și metaId: null. Rezultatul livrării vine mai târziu ca a
source: 13 apel invers (§6.4).
Discrepanță — cod de răspuns
Swagger declară 200 fără corp; specificația internă declară 202 Accepted
cu comentariul ca corp. Controllerului, cel mai probabil, îi lipsește un ProducesResponseType
atribut, lăsând Swagger pe implicit. Acceptați orice 2xx și nu depindeți de un corp.
6. Webhooks
SMSBAT trimite solicitări POST cu application/json la adresa URL și așteaptă HTTP 200 înapoi.
Câmpurile nule sunt omise în întregime
Un câmp a cărui valoare este null nu este deloc serializat în corpul de apel invers. Pentru a
mesaj care nu a venit de la Facebook sau Instagram, pur și simplu nu există cheie MetaUserId.
Tratează „absent” și null ca fiind același lucru.
6.1 Înregistrați o adresă URL de apel invers
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
}'
| Câmp | Tip | Descriere |
|---|---|---|
url | string | Punctul final |
source | SendingSourceCallback | Tipul de eveniment, vezi §8.2 |
headerName / headerValue | string | Antet de autorizare arbitrară pe care îl atașăm la cerere (opțional) |
channelType | ChatSource | Canal. 7 pentru Instagram. Opțional |
channelEntityId | int | Un anumit cont de afaceri. Necesită channelType |
Fără channelType, adresa URL primește evenimente de la fiecare canal.
Tip
Acoperirea completă a comentariilor necesită două înregistrări: source: 12 pentru comentarii noi și
source: 13 pentru stările de răspuns. Pentru răspunsurile Direct și Story adăugați source: 3
(și 11 dacă doriți fiecare mesaj de chat).
Operațiuni rămase:
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 returnează:
[
{
"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 Mesaj nou și răspuns la povestea Instagram (source: 3, 11)
Răspunsul unui utilizator la o Povestea Instagram sosește ca un mesaj obișnuit în aceste apeluri inverse,
cu un bloc suplimentar Story de nivel superior:
{
"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"
}
}
| Câmp | Descriere |
|---|---|
ChatId / MessageId | Identificatori de chat și mesaje |
Author | 0 utilizator, 1 operator |
Username | Nume afișat sau mâner pentru Instagram / Facebook |
UserId | ID de utilizator numeric intern în SMSBAT |
MetaUserId | ID delimitat al partenerului de conversație în Meta. Pe un mesaj de operator de ieșire, acesta încă identifică utilizatorul Meta al chat-ului, nu operatorul |
ShopId | ID-ul intern al contului de afaceri Instagram / Facebook |
ShopName | Numele contului de companie așa cum a fost primit de la Meta la momentul conexiunii |
MessageText | Textul mesajului |
MessageMedia | URL media când mesajul este media |
type_messenger | Sursa, 7 pentru Instagram |
operator_name | Numele operatorului când Author = 1 |
Story | Prezentați numai într-un răspuns la o poveste de intrare |
Story.Id | Povestea internă (MetaPost) ID — poate fi utilizat direct ca id / postId în Meta API |
Story.MetaId | ID extern al poveștii în Meta |
Story.Url | Adresa URL proxy stabilă a conținutului media Story stocat. Lipsă când media nu a putut fi salvată — blocul Story și mesajul sunt încă livrate |
`Author` este inversat față de API-ul Chat
În ChatMessageDTO.author, 0 înseamnă operator și 1 înseamnă client. În acest apel invers este
invers: 0 este utilizatorul, 1 este operatorul. Nu împărtășiți maparea.
6.3 Comentariu nou (source: 12)
Se declanșează atunci când un utilizator Meta comentează o postare pe Facebook sau o postare pe Instagram / Reel.
Note
Instagram Răspunsurile la povești nu sunt livrate prin source: 12. Ele sosesc ca de obicei
mesajele primite pe source: 3 și/sau 11 cu un bloc Story - vezi §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 Starea răspunsului la comentariu (source: 13)
Se declanșează după ce încercăm să oferim un răspuns, indiferent dacă acesta reușește sau eșuează.
{
"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 Câmpuri de apel invers pentru comentarii partajate
Ambele apeluri pentru comentarii au o singură formă a corpului și diferă doar prin type.
| Câmp | Descriere |
|---|---|
type | "new_comment" sau "comment_status" |
platform | "facebook" sau "instagram" |
comment.id | ID comentariu intern |
comment.metaId | ID extern în Meta; null pentru un răspuns în așteptare înainte de a fi trimis |
comment.parentCommentId | ID comentariu părinte. Absent pentru un comentariu de nivel superior |
comment.parentMetaId | ID comentariu pentru părinte extern. Absent la nivel superior |
comment.parentCommentText | Textul comentariului părintelui. Absent la nivel superior |
comment.text | Textul comentariului |
comment.createdAt | Data creării |
comment.updatedAt | Ultima actualizare. Absent dacă comentariul nu a fost editat niciodată |
comment.replyStatus | "pending" / "sent" / "failure". Absent pentru un comentariu de utilizator primit |
comment.author.type | "meta_user" sau "owner" |
comment.author.name | Numele autorului |
comment.author.metaUserId | ID-ul autorului vizat în Meta. Absent pentru "owner" |
comment.mediaUrl | Comentează media. Absent când nu există |
post.id | ID-ul postului intern |
post.metaId | Postare externă / Reel / ID de poveste în Meta |
post.text | Postează text |
post.imageUrl | Postați adresa URL a imaginii sau null |
post.createdAt | Data post-creare |
post.mediaType | În apelurile înapoi în comentarii, numai post sau reel |
6.6 Chat nou (source: 7)
{ "ChatId": 12345, "Phone": "+380501234567", "chat.Source": 7 }
6.7 Modificări ale stării mesajelor și chat (source: 6 / 5)
{ "name": "changed_message_status", "id": 9928, "status": 6 }
{ "name": "changed_chat_status", "id": 1867, "status": 4 }
6.8 Mesaj editat sau șters (source: 9)
{ "messageId": 9930, "text": "Updated message text" }
{ "messageId": 9931, "delete": true }
6.9 Indicator de tastare (source: 8)
{ "chat_id": 1867, "event": "start_typing", "operator_name": "Iryna" }
{ "chat_id": 1867, "event": "end_typing" }
7. Sondaj la eveniment
Pentru medii care nu pot accepta HTTP de intrare.
7.1 Preluare evenimente
GET https://chatapi.smsbat.com/api/chat/callback-events?page=1&perPage=20
Authorization: Bearer <token>
| Parametru | Descriere |
|---|---|
organizationId | Opțional. Luat din jeton când este omis |
page / perPage | Paginare, implicite 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"
}
]
}
Fiecare eveniment poartă event_guid, timestamp, organization_id și callback_type — a
șir care se potrivește cu valorile source din §8.2. Câmpurile rămase se potrivesc cu cele corespunzătoare
webhook în §6.
7.2 Confirmați evenimentele procesate
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 }
Evenimentele deja eliminate pur și simplu nu sunt luate în considerare pentru deleted. Comenzile și reîncercările sunt dvs
responsabilitatea părţii.
7.3 Bucla recomandată
- Sondaj
GET /api/chat/callback-eventsla un program. - Procesați evenimentele în serviciul dumneavoastră.
- Trimiteți lista procesată
event_guidla/callback-events/processed. - Repetați.
8. Referință enumerare
8.1 ChatSource — canal (0–9)
| Cod | Canal |
|---|---|
| 0 | Viber |
| 1 | ViberBot |
| 2 | TelegramBot |
| 3 | |
| 4 | Widget |
| 5 | Rozetka |
| 6 | |
| 7 | |
| 8 | Balul de absolvire |
| 9 | Olx |
8.2 SendingSourceCallback — tip de eveniment de apel invers (0–13)
| Cod | Eveniment |
|---|---|
| 3 | Chat — mesaj nou de chat, inclusiv răspunsuri la poveste |
| 5 | Starea chatului a fost schimbată |
| 6 | Starea mesajului a fost schimbată |
| 7 | Chat nou creat |
| 8 | Indicator de tastare |
| 9 | Mesaj actualizat sau șters |
| 11 | AnyChatMessage — orice mesaj de chat |
| 12 | MetaNewComment — comentariu nou Instagram / Facebook |
| 13 | MetaCommentStatus — starea de livrare a răspunsului nostru la comentariu |
Enumerarea se întinde pe 0–13; valorile rămase nu sunt necesare pentru integrările Instagram.
8,3 ChatStatus (0–4)
0 Nou, 1 Deschis, 2 În așteptare, 3 OnPause, 4 Închis
8,4 MessageStatus (0–11)
| Cod | Nume |
|---|---|
| 0 | NOU |
| 1 | SUCCES |
| 2 | RESPINS |
| 3 | CITEȘTE |
| 4 | NECUNOSCUT |
| 5 | PRELUCRARE |
| 6 | LIVRAT |
| 7 | BLOCKED_BY_USER |
| 8 | USER_NOT_FUND |
Enumerația se întinde pe 0–11. Valorile 9, 10 și 11 există în API, dar nu sunt încă documentate —
tratați-i ca UNKNOWN.
8,5 MediaType (1–10)
1 Fotografie, 2 Fișier, 3 Audio, 4 Video, 5 Autocolant, 6 Autocolant animat,
7 StickerVideo, 8 Animație, 9 Voce, 10 VideoNotă
8.6 AuthorMessage — autor în API-ul Chat (0–4)
0 Operator, 1 Client, 2 Bot, 3 ViberAccount
Enumerarea se întinde pe 0–4; valoarea 4 este nedocumentată. Reapelurile „noul mesaj” folosesc
cartografiere opusă — vezi §6.2.
8,7 ChatMessageType (0–2)
0 Text, 1 Fotografie, 2 Fișier
8.8 Comentariu replyStatus
null comentariu primit de la utilizator, "pending" răspunsul nostru este pus în coadă, "sent" livrat,
"failure" livrarea a eșuat.
Întrebări deschise
Trei puncte în care specificațiile interne și Swagger-ul generat de cod nu sunt de acord. Unul cererea cu un token real le soluționează pe toate; pana atunci scrie-i clientului defensiv.
| # | Întrebare | Specificație | Swagger | Cum se verifică |
|---|---|---|---|---|
| 1 | Antet de autentificare pentru /api/meta/* | X-Authorization-Key | doar Bearer declarat | curl -i -H "X-Authorization-Key: <token>" ".../api/meta/posts?perPage=1" — așteptați 200, nu 401 |
| 2 | Câmp de contor în Meta răspunsuri | totalCount | total | Aceeași cerere — citiți cheia JSON rădăcină |
| 3 | author.type tip și reply cod de stare | "meta_user" / "owner", 202 cu corp | int [0,1], 200 fără corp | curl -i .../api/meta/comments?perPage=1 plus un răspuns de test |
Îndrumări intermediare:
- counter — citiți
total ?? totalCount; author.type— acceptă atât un șir, cât și un număr întreg (0↔meta_user,1↔owner, maparea trebuie confirmată);reply— tratează orice2xxca succes, nu necesită corp, ia starea finală din apel inverssource: 13.
Note de implementare
- Autentificarea diferă în funcție de grupul de puncte finale —
/api/meta/*utilizeazăX-Authorization-Key, chat-uri și operatorii folosescBearer,restapiacceptă fie. - Paginarea este scrisă în două moduri —
per_pagepe/api/chat/chats,perPagepe/api/meta/*și/api/chat/callback-events. - Câmpurile
multipart/form-datasunt PascalCase cu notație punct (Media.File,Media.Type). - Câmpurile nule sunt omise din apeluri inverse — o cheie absentă înseamnă
null. phoneeste de obiceinullpe Instagram. Identificați clientul prininstagramUser.id/metaUserIdși magazinul deinstaAccount.id(valoarea filtruluientityId).Story.Iddintr-un apel invers poate fi transmis direct înapoi caid/postIdcătre Meta API.- Verificați operatorul JWT
expiresAtînainte de a-l folosi într-un link profund sau widget.