Help Center Integrare API Meta și Instagram

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ă

ScopURL
Chat API + Meta APIhttps://chatapi.smsbat.com
Swagger UI / OpenAPIhttps://chatapi.smsbat.com/index.html · …/swagger/v1/swagger.json
API REST (organizații, adrese URL de apel invers)https://restapi.smsbat.com
REST API Swaggerhttps://restapi.smsbat.com/swagger/v1/swagger.json
Panoul web al operatoruluihttps://chat.smsbat.com

2. Autentificare

Schema de autentificare depinde de grupul de puncte finale. Amestecarea lor este cea mai frecventă cauză a 401.

GrupaAntet
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>

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>
ParametruDescriere
chat_raw_idID chat
phoneNumăr de telefon în format internațional
fromIdentificator de marcă/cont de afaceri (bm_id)
sourceSursă de chat — 7 pentru Instagram, vezi §8.1
tokenOperator 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:

ParametruTipDescriere
sourceChatSource7 restricționează rezultatele la Instagram
entityIdintID-ul contului de companie. Se aplică numai împreună cu source
instagram_user_idintID utilizator Instagram în ChatHub
facebook_user_idintID utilizator Facebook în ChatHub
page / per_pageintPaginare, valori implicite 1 / 20
statusChatStatus[]Stare chat, repetabil
searchstringCăutare în text liber (nume, telefon, …)
organizationIdintID organizație
operatorIdint[]Filtrați după operatori alocați
datestring[]Două limite: ?date=…&date=…
isChainboolÎntoarce chat-urile ca lanțuri, purtând mesaje din chat-urile anterioare
isUnread, starMark, isOperator, isAIAgentboolFiltre 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
instaAccountContul de afaceri Instagram (magazinul). id este valoarea filtrului entityId; name este numele contului din Meta
instagramUserclientul. name este mânerul Instagram, id este valoarea filtrului instagram_user_id
metaUserIdID-ul de acoperire al clientului pe partea lui Meta (șir)
messSource7 pentru Instagram
phoneDe 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âmpTipDescriere
textMessagestring?Textul mesajului. Poate fi gol atunci când este prezent media
authorAuthorMessage?0 operator, 1 client
isInternalbool?true marchează o notă internă care nu este livrată clientului
replyToMessageIdint?ID-ul mesajului căruia i se răspunde
appGuiduuid?GUID de referință
mediaMediaDTO?{ 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 formularTipDescriere
TextMessagestringTextul mesajului
Authorint0 operator, 1 client
IsInternalboolNotă internă
ReplyToMessageIdintSe răspunde la mesajul
AppGuiduuidGUID de referință
Media.FilebinaryFișierul în sine
Media.NamestringNume fișier
Media.FormatstringTip MIME (video/mp4, image/png, application/pdf)
Media.TypeMediaTypeVezi §8.5
Media.DataBase64stringAlternativă la Media.File
Media.ThumbnailstringCadru de previzualizare video Base64
Media.DurationdoubleDurata 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>
ParametruTipNecesarDescriere
pageintnuPagina, implicit 1
perPageintnuArticole pe pagină, implicit 20
idintnuFiltrați după ID-ul postării interne
platformstringnuinstagram sau facebook
mediaTypestringnupost, 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âmpDescriere
idID-ul postului intern
metaIdPostare externă / Reel / ID de poveste în Meta
textPost legenda
imageUrlAdresa URL media proxy introdusă de codul non-secvențial MetaPost.Guid sau null
platformfacebook sau instagram
mediaTypepost, reel sau story
createdAtData creării (data platformei sau data bazei de date)
storyPrezentați doar pentru mediaType: "story"
story.idID intern al poveștii; egal cu post.id
story.metaIdID extern al poveștii în Meta
story.urlAdresa 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>
ParametruTipNecesarDescriere
pageintnuPagina, implicit 1
perPageintnuArticole pe pagină, implicit 20
postIdintnuFiltrați după ID-ul postării
parentCommentIdintnuComentariile copilului (răspunsurile) la un comentariu dat
platformstringnufacebook 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âmpDescriere
idID comentariu intern
metaIdID extern în Meta. null pentru un răspuns în așteptare al nostru până când acesta este trimis
textTextul comentariului
createdAtData creării
platformfacebook sau instagram
replyStatusnull pentru un comentariu primit de la utilizator; "pending" / "sent" / "failure" pentru răspunsul nostru
author.type"meta_user" utilizator extern, "owner" proprietarul paginii
author.nameNumele autorului
author.metaUserIdID utilizator definit în Meta; null pentru "owner"
postPostarea, Reel sau Story îi aparține comentariului
post.mediaTypepost, reel sau story
post.storyReferință povești { id, metaId, url }, numai povești
mediaUrlMedia atașată comentariului sau null
replyToComentariu 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âmpTipDescriere
urlstringPunctul final
sourceSendingSourceCallbackTipul de eveniment, vezi §8.2
headerName / headerValuestringAntet de autorizare arbitrară pe care îl atașăm la cerere (opțional)
channelTypeChatSourceCanal. 7 pentru Instagram. Opțional
channelEntityIdintUn 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âmpDescriere
ChatId / MessageIdIdentificatori de chat și mesaje
Author0 utilizator, 1 operator
UsernameNume afișat sau mâner pentru Instagram / Facebook
UserIdID de utilizator numeric intern în SMSBAT
MetaUserIdID 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
ShopIdID-ul intern al contului de afaceri Instagram / Facebook
ShopNameNumele contului de companie așa cum a fost primit de la Meta la momentul conexiunii
MessageTextTextul mesajului
MessageMediaURL media când mesajul este media
type_messengerSursa, 7 pentru Instagram
operator_nameNumele operatorului când Author = 1
StoryPrezentați numai într-un răspuns la o poveste de intrare
Story.IdPovestea internă (MetaPost) ID — poate fi utilizat direct ca id / postId în Meta API
Story.MetaIdID extern al poveștii în Meta
Story.UrlAdresa 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âmpDescriere
type"new_comment" sau "comment_status"
platform"facebook" sau "instagram"
comment.idID comentariu intern
comment.metaIdID extern în Meta; null pentru un răspuns în așteptare înainte de a fi trimis
comment.parentCommentIdID comentariu părinte. Absent pentru un comentariu de nivel superior
comment.parentMetaIdID comentariu pentru părinte extern. Absent la nivel superior
comment.parentCommentTextTextul comentariului părintelui. Absent la nivel superior
comment.textTextul comentariului
comment.createdAtData creării
comment.updatedAtUltima 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.nameNumele autorului
comment.author.metaUserIdID-ul autorului vizat în Meta. Absent pentru "owner"
comment.mediaUrlComentează media. Absent când nu există
post.idID-ul postului intern
post.metaIdPostare externă / Reel / ID de poveste în Meta
post.textPostează text
post.imageUrlPostați adresa URL a imaginii sau null
post.createdAtData 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>
ParametruDescriere
organizationIdOpțional. Luat din jeton când este omis
page / perPagePaginare, 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ă

  1. Sondaj GET /api/chat/callback-events la un program.
  2. Procesați evenimentele în serviciul dumneavoastră.
  3. Trimiteți lista procesată event_guid la /callback-events/processed.
  4. Repetați.

8. Referință enumerare

8.1 ChatSource — canal (0–9)

CodCanal
0Viber
1ViberBot
2TelegramBot
3Whatsapp
4Widget
5Rozetka
6Facebook
7Instagram
8Balul de absolvire
9Olx

8.2 SendingSourceCallback — tip de eveniment de apel invers (0–13)

CodEveniment
3Chat — mesaj nou de chat, inclusiv răspunsuri la poveste
5Starea chatului a fost schimbată
6Starea mesajului a fost schimbată
7Chat nou creat
8Indicator de tastare
9Mesaj actualizat sau șters
11AnyChatMessage — orice mesaj de chat
12MetaNewComment — comentariu nou Instagram / Facebook
13MetaCommentStatus — 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)

CodNume
0NOU
1SUCCES
2RESPINS
3CITEȘTE
4NECUNOSCUT
5PRELUCRARE
6LIVRAT
7BLOCKED_BY_USER
8USER_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.

#ÎntrebareSpecificațieSwaggerCum se verifică
1Antet de autentificare pentru /api/meta/*X-Authorization-Keydoar Bearer declaratcurl -i -H "X-Authorization-Key: <token>" ".../api/meta/posts?perPage=1" — așteptați 200, nu 401
2Câmp de contor în Meta răspunsuritotalCounttotalAceeași cerere — citiți cheia JSON rădăcină
3author.type tip și reply cod de stare"meta_user" / "owner", 202 cu corpint [0,1], 200 fără corpcurl -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ă orice 2xx ca succes, nu necesită corp, ia starea finală din apel invers source: 13.

Note de implementare

  • Autentificarea diferă în funcție de grupul de puncte finale — /api/meta/* utilizează X-Authorization-Key, chat-uri și operatorii folosesc Bearer, restapi acceptă fie.
  • Paginarea este scrisă în două moduri — per_page pe /api/chat/chats, perPage pe /api/meta/* și /api/chat/callback-events.
  • Câmpurile multipart/form-data sunt PascalCase cu notație punct (Media.File, Media.Type).
  • Câmpurile nule sunt omise din apeluri inverse — o cheie absentă înseamnă null.
  • phone este de obicei null pe Instagram. Identificați clientul prin instagramUser.id / metaUserId și magazinul de instaAccount.id (valoarea filtrului entityId).
  • Story.Id dintr-un apel invers poate fi transmis direct înapoi ca id / postId către Meta API.
  • Verificați operatorul JWT expiresAt înainte de a-l folosi într-un link profund sau widget.