Help Center Integrazione API Meta e Instagram

Integrazione API Meta e Instagram

Riferimento per la creazione di un’app Instagram sulla piattaforma SMSBAT ChatHub: autenticazione, Conversazioni di Instagram Direct, commenti su post e reel, risposte alle storie, webhook e sondaggi.

Fonti

Questa pagina unisce le specifiche interne dell’API Meta Comments con l’OpenAPI live definizioni a https://chatapi.smsbat.com/swagger/v1/swagger.json e https://restapi.smsbat.com/swagger/v1/swagger.json. Dove i due non sono d’accordo, il la differenza viene evidenziata in linea ed elencata in Domande aperte.


1. URL di base

ScopoURL
API di chat + Meta APIhttps://chatapi.smsbat.com
Interfaccia utente spavalda/OpenAPIhttps://chatapi.smsbat.com/index.html · …/swagger/v1/swagger.json
API REST (organizzazioni, URL di richiamata)https://restapi.smsbat.com
Spavalderia dell’API RESThttps://restapi.smsbat.com/swagger/v1/swagger.json
Pannello web operatorehttps://chat.smsbat.com

2. Autenticazione

Lo schema di autenticazione dipende dal gruppo di endpoint. Mescolarli è la causa più comune di 401.

GruppoIntestazione
chatapi.smsbat.com/api/meta/* (post, commenti)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 · Autenticazione di base

Il token dell’organizzazione per X-Authorization-Key viene rilasciato nel pannello sotto Profilo. I JWT dell’azienda e dell’operatore provengono da /api/company/get-token e /api/operator/get-token.

Discrepanza

Il documento chatapi OpenAPI dichiara un unico schema di sicurezza — Bearer — e lo applica a livello globale. X-Authorization-Key non è affatto dichiarato lì, sebbene il Meta interno La specifica API dei commenti lo nomina per /api/meta/*. Molto probabilmente è gestito da middleware che non si riflette in Swagger. Conferma empiricamente prima di spedire.

2.1 Gettone aziendale

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

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

200 OK restituisce una stringa token semplice.

2.2 Organizzazioni

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

2.3 Gli operatori di un’organizzazione

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

Stati dell’operatore: 0 Attivo, 1 Inattivo, 2 Eliminato.

2.4 Aggiungi/sincronizza 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 Operatore 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 restituisce JWT come stringa.

2.6 Convalidare un token operatore

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
}

Se non valido: { "isValid": false, "error": "Invalid token" }.

2.7 Incorpora il pannello chat dell’operatore

<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. Collegamenti diretti al pannello della chat

Un sistema esterno (CRM, ERP, sito web) può aprire una conversazione specifica in https://chat.smsbat.com/. L’operatore è autorizzato da un JWT passato come parametro di query.

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>
ParametroDescrizione
chat_raw_idID chat
phoneNumero di telefono in formato internazionale
fromIdentificatore del marchio/account aziendale (bm_id)
sourceSorgente chat — 7 per Instagram, vedere §8.1
tokenOperatore JWT valido e non scaduto con accesso alle chat

Un JWT non valido indirizza il visitatore alla schermata di accesso del pannello operatore.


4. Conversazioni dirette di Instagram

4.1 Elenca le chat

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

Note

La paginazione qui è per_page (snake_case). Sotto /api/meta/* e il sondaggio l’endpoint è perPage (camelCase). Non si tratta di un errore di battitura: l’API utilizza entrambi.

Parametri di query, tutti facoltativi:

ParametroDigitareDescrizione
sourceChatSource7 limita i risultati a Instagram
entityIdintID del conto aziendale. Applicato solo insieme a source
instagram_user_idintID utente Instagram in ChatHub
facebook_user_idintID utente Facebook in ChatHub
page / per_pageintImpaginazione, impostazioni predefinite 1 / 20
statusChatStatus[]Stato della chat, ripetibile
searchstringRicerca a testo libero (nome, telefono, …)
organizationIdintID organizzazione
operatorIdint[]Filtra per operatori assegnati
datestring[]Due limiti: ?date=…&date=…
isChainboolRestituisce le chat come catene, trasportando messaggi dalle chat precedenti
isUnread, starMark, isOperator, isAIAgentboolFiltri aggiuntivi
phone, email, contactId, clientId, tagIds, rate, sortedBy—Altri filtri

200 OK restituisce 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": []
    }
  ]
}

I campi che contano per un’app Instagram:

CampoSignificato
instaAccountL’Account aziendale Instagram (il negozio). id è il valore del filtro entityId; name è il nome dell’account di Meta
instagramUserIl cliente. name è l’handle di Instagram, id è il valore del filtro instagram_user_id
metaUserIdL’ID con ambito del cliente sul lato Meta (stringa)
messSource7 per Instagram
phoneDi solito null per Instagram: non usarlo come chiave

ChatDTO trasporta anche 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 e taggedMessages.

4.2 Messaggi di chat

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

200 OK restituisce un array di 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 viene compilato quando il messaggio si riferisce a un post o a una storia di Instagram: passalo direttamente come id / postId alla Meta API. media è un ChatMediaDTO: { name, format, type, uri, raw, length, isUploaded }.

4.3 Invia un messaggio (JSON)

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

Corpo — 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
  }
}
CampoDigitareDescrizione
textMessagestring?Testo del messaggio. Può essere vuoto quando è presente media
authorAuthorMessage?0 operatore, 1 cliente
isInternalbool?true segnala una nota interna che non viene consegnata al cliente
replyToMessageIdint?ID del messaggio a cui si risponde
appGuiduuid?GUID di riferimento
mediaMediaDTO?{ name, format, dataBase64, thumbnail, duration, type }

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

È inoltre possibile passare un GUID di riferimento nel percorso: POST /api/chat/{chatId}/{referralGuid}/message (allo stesso modo …/message/v1, …/message/v2).

4.4 Invia un file o un video (multiparte, v2)

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

I nomi dei campi del modulo sono PascalCase con notazione punto

textMessage e media.file vengono silenziosamente ignorati. Utilizza i nomi esatti riportati di seguito.

Campo moduloDigitareDescrizione
TextMessagestringTesto del messaggio
Authorint0 operatore, 1 cliente
IsInternalboolNota interna
ReplyToMessageIdintMessaggio a cui è stata data risposta
AppGuiduuidGUID di riferimento
Media.FilebinaryIl file stesso
Media.NamestringNome del file
Media.FormatstringTipo MIME (video/mp4, image/png, application/pdf)
Media.TypeMediaTypeVedi §8.5
Media.DataBase64stringAlternativa a Media.File
Media.ThumbnailstringCornice di anteprima video Base64
Media.DurationdoubleDurata del video in secondi
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 Modificare lo stato della chat

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

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

200 OK fa eco all’oggetto aggiornato.

4.6 Aggiorna gli stati dei messaggi

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

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

4.7 Eliminare una chat

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

5. Post, reel e storie

Sentiero base: https://chatapi.smsbat.com/api/meta Autentica: X-Authorization-Key: <organization token>

5.1 Elenca post, reel e storie

GET https://chatapi.smsbat.com/api/meta/posts?platform=instagram&mediaType=story&page=1&perPage=20
X-Authorization-Key: <token>
ParametroDigitareObbligatorioDescrizione
pageintnoPagina, predefinita 1
perPageintnoElementi per pagina, predefinito 20
idintnoFiltra per ID articolo interno
platformstringnoinstagram o facebook
mediaTypestringnopost, reel o story. Tutti i tipi se omessi
# 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"
      }
    }
  ]
}

Discrepanza - nome campo contatore

Lo schema Swagger MetaCommentPostListItemDtoPaginationDTO definisce total. Il documenti di specifica interna totalCount. Swagger viene generato dal codice, quindi total è la verità più probabile. Analizza total ?? totalCount finché non viene risolto.

CampoDescrizione
idID post interno
metaIdID post/reel/storia esterno in Meta
textDidascalia del messaggio
imageUrlURL multimediale proxy digitato dal non sequenziale MetaPost.Guid o null
platformfacebook o instagram
mediaTypepost, reel o story
createdAtData di creazione (data della piattaforma o data del database)
storyPresente solo per mediaType: "story"
story.idID della storia interna; uguale a post.id
story.metaIdID storia esterna in Meta
story.urlURL proxy stabile del supporto Story archiviato; null se non è stato possibile salvare il file multimediale

I post media sono serviti da due percorsi: GET /api/meta/post/media/{id:int} per indietro compatibilità e GET /api/meta/post/media/{guid:guid}. Nuove risposte API e callback generare sempre il modulo GUID.

5.2 Elenca i commenti

GET https://chatapi.smsbat.com/api/meta/comments?platform=instagram&postId=42&page=1&perPage=20
X-Authorization-Key: <token>
ParametroDigitareObbligatorioDescrizione
pageintnoPagina, predefinita 1
perPageintnoElementi per pagina, predefinito 20
postIdintnoFiltra per ID articolo
parentCommentIdintnoCommenti secondari (risposte) di un dato commento
platformstringnofacebook o 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..."
      }
    }
  ]
}
CampoDescrizione
idID commento interno
metaIdID esterno in Meta. null per una nostra risposta in attesa dell’invio
textTesto del commento
createdAtData di creazione
platformfacebook o instagram
replyStatusnull per il commento di un utente in entrata; "pending" / "sent" / "failure" per la nostra risposta
author.type"meta_user" utente esterno, "owner" proprietario della pagina
author.nameNome dell’autore
author.metaUserIdID utente con ambito in Meta; null per "owner"
postIl post, la Reel o la Storia a cui appartiene il commento
post.mediaTypepost, reel o story
post.storyRiferimento alla storia { id, metaId, url }, Solo storie
mediaUrlFile multimediali allegati al commento o null
replyToCommento dei genitori { id, metaId, text }; null al livello più alto

Discrepanza - tipo `author.type`

La specifica interna documenta le stringhe "meta_user" / "owner". Tipi spavaldi MetaCommentAuthorType come intero con enum [0, 1]. A JsonStringEnumConverter spiegherebbe il divario, ma ciò non è stato confermato da una risposta reale. Scrivi un parser che accetta entrambi.

5.3 Rispondere a un commento

Accoda una risposta per la consegna.

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"

Richiedi corpo: { "text": "Reply text" }

202 Accepted restituisce l’oggetto commento - stessa forma di GET /api/meta/comments - con replyStatus: "pending" e metaId: null. L’esito della consegna arriva più tardi come a source: 13 richiamata (§6.4).

Discrepanza - codice di risposta

Swagger dichiara 200 senza corpo; la specifica interna dichiara 202 Accepted con il commento come corpo. Molto probabilmente al controller manca un ProducesResponseType attributo, lasciando Swagger sul valore predefinito. Accetta qualsiasi 2xx e non dipendere da un corpo.


6. Webhook

SMSBAT invia POST richieste con application/json al tuo URL e si aspetta HTTP 200 in risposta.

I campi nulli vengono completamente omessi

Un campo il cui valore è null non è affatto serializzato nel corpo del callback. Per un messaggio che non proviene da Facebook o Instagram semplicemente non esiste il tasto MetaUserId. Tratta “assente” e null come la stessa cosa.

6.1 Registrare un URL di richiamata

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
  }'
CampoDigitareDescrizione
urlstringIl tuo punto finale
sourceSendingSourceCallbackTipo evento, vedere §8.2
headerName / headerValuestringIntestazione di autenticazione arbitraria che alleghiamo alla richiesta (facoltativa)
channelTypeChatSourceCanale. 7 per Instagram. Facoltativo
channelEntityIdintUn conto aziendale specifico. Richiede channelType

Senza channelType l’URL riceve eventi da ogni canale.

Tip

La copertura completa dei commenti richiede due registrazioni: source: 12 per nuovi commenti e source: 13 per gli stati delle risposte. Per le risposte dirette e alle storie aggiungi source: 3 (e 11 se vuoi tutti i messaggi di chat).

Operazioni rimanenti:

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 restituisce:

[
  {
    "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 Nuovo messaggio e risposta alla storia di Instagram (source: 3, 11)

La risposta di un utente a una Storia di Instagram arriva come un normale messaggio in queste richiamate, con un blocco Story di primo livello aggiuntivo:

{
  "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"
  }
}
CampoDescrizione
ChatId / MessageIdIdentificatori di chat e messaggi
Author0 utente, 1 operatore
UsernameNome visualizzato o handle di Instagram/Facebook
UserIdID utente numerico interno in SMSBAT
MetaUserIdID con ambito dell’interlocutore in Meta. Su un messaggio operatore in uscita questo identifica ancora l’utente Meta della chat, non l’operatore
ShopIdID interno dell’account aziendale Instagram/Facebook
ShopNameNome dell’account aziendale ricevuto da Meta al momento della connessione
MessageTextTesto del messaggio
MessageMediaURL multimediale quando il messaggio è multimediale
type_messengerFonte, 7 per Instagram
operator_nameNome dell’operatore quando Author = 1
StoryPresente solo nella risposta ad una Storia in entrata
Story.IdID storia interna (MetaPost) — utilizzabile direttamente come id / postId nella Meta API
Story.MetaIdID storia esterna in Meta
Story.UrlURL proxy stabile del supporto Story archiviato. Assente quando non è stato possibile salvare il supporto — il blocco Story e il messaggio vengono comunque recapitati

`Author` è invertito rispetto all'API Chat

In ChatMessageDTO.author, 0 significa operatore e 1 significa cliente. In questo richiamo lo è viceversa: 0 è l’utente, 1 è l’operatore. Non condividere la mappatura.

6.3 Nuovo commento (source: 12)

Si attiva quando un utente Meta commenta un post di Facebook o un post/reel di Instagram.

Note

Instagram Le risposte alle storie non vengono inviate tramite source: 12. Arrivano normalmente messaggi in entrata su source: 3 e/o 11 con un blocco Story — vedere §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 Stato della risposta al commento (source: 13)

Si attiva dopo il tentativo di fornire una risposta, indipendentemente dal fatto che abbia esito positivo o negativo.

{
  "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 Campi di richiamata dei commenti condivisi

Entrambi i richiami ai commenti condividono una forma del corpo e differiscono solo per type.

CampoDescrizione
type"new_comment" o "comment_status"
platform"facebook" o "instagram"
comment.idID commento interno
comment.metaIdID esterno in Meta; null per una risposta in sospeso prima che venga inviata
comment.parentCommentIdID commento principale. Assente per un commento di primo livello
comment.parentMetaIdID commento principale esterno. Assente ai massimi livelli
comment.parentCommentTextTesto del commento del genitore. Assente ai massimi livelli
comment.textTesto del commento
comment.createdAtData di creazione
comment.updatedAtUltimo aggiornamento. Assente se il commento non è mai stato modificato
comment.replyStatus"pending" / "sent" / "failure". Assente per il commento di un utente in entrata
comment.author.type"meta_user" o "owner"
comment.author.nameNome dell’autore
comment.author.metaUserIdID autore con ambito in Meta. Assente per "owner"
comment.mediaUrlCommento multimediale. Assente quando non ce n’è
post.idID post interno
post.metaIdID post/reel/storia esterno in Meta
post.textPubblica testo
post.imageUrlPubblica l’URL dell’immagine o null
post.createdAtData di creazione post
post.mediaTypeNei callback dei commenti, solo post o reel

6.6 Nuova chat (source: 7)

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

6.7 Modifiche allo stato dei messaggi e della chat (source: 6 / 5)

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

6.8 Messaggio modificato o eliminato (source: 9)

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

6.9 Indicatore di digitazione (source: 8)

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

7. Sondaggio sugli eventi

Per ambienti che non possono accettare HTTP in entrata.

7.1 Recupera eventi

GET https://chatapi.smsbat.com/api/chat/callback-events?page=1&perPage=20
Authorization: Bearer <token>
ParametroDescrizione
organizationIdOpzionale. Preso dal token quando omesso
page / perPageImpaginazione, impostazioni predefinite 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"
    }
  ]
}

Ogni evento porta event_guid, timestamp, organization_id e callback_type — un stringa che corrisponde ai valori source in §8.2. I restanti campi corrispondono ai corrispondenti webhook nel §6.

7.2 Riconoscere gli eventi elaborati

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 }

Gli eventi già rimossi semplicemente non contano per deleted. L’ordine e i tentativi sono tuoi responsabilità della parte.

7.3 Ciclo consigliato

  1. Sondaggio GET /api/chat/callback-events su un programma.
  2. Elabora gli eventi nel tuo servizio.
  3. Invia l’elenco event_guid elaborato a /callback-events/processed.
  4. Ripeti.

8. Riferimento all’enumerazione

8.1 ChatSource — canale (0–9)

CodiceCanale
0Viber
1ViberBot
2TelegramBot
3Whatsapp
4Dispositivo
5Rozetka
6Facebook
7Instagram
8Ballo di fine anno
9Olx

8.2 SendingSourceCallback — tipo di evento di richiamata (0–13)

CodiceEvento
3Chat — nuovo messaggio di chat, incluse le risposte alle storie
5Lo stato della chat è cambiato
6Lo stato del messaggio è cambiato
7Nuova chat creata
8Indicatore di digitazione
9Messaggio aggiornato o cancellato
11AnyChatMessage — qualsiasi messaggio di chat
12MetaNewComment — nuovo commento su Instagram/Facebook
13MetaCommentStatus — stato di consegna della nostra risposta al commento

L’enumerazione si estende su 0–13; i restanti valori non sono necessari per le integrazioni di Instagram.

8.3 ChatStatus (0–4)

0 Nuovo, 1 Aperto, 2 In attesa, 3 In pausa, 4 Chiuso

8.4 MessageStatus (0–11)

CodiceNome
0NUOVO
1SUCCESSO
2RIFIUTATO
3LEGGI
4SCONOSCIUTO
5LAVORAZIONE
6CONSEGNATO
7BLOCCATO_DA_UTENTE
8UTENTE_NOT_TROVATO

L’enumerazione si estende su 0–11. I valori 9, 10 e 11 esistono nell’API ma non sono ancora documentati — trattateli come UNKNOWN.

8.5 MediaType (1–10)

1 Foto, 2 File, 3 Audio, 4 Video, 5 Adesivo, 6 AdesivoAnimato, 7 StickerVideo, 8 Animazione, 9 Voce, 10 VideoNote

8.6 AuthorMessage — autore nell’API Chat (0–4)

0 Operatore, 1 Cliente, 2 Bot, 3 ViberAccount

L’enumerazione si estende su 0–4; il valore 4 non è documentato. Le richiamate del “nuovo messaggio” utilizzano l’estensione mappatura opposta — vedere §6.2.

8.7 ChatMessageType (0–2)

0 Testo, 1 Foto, 2 File

8.8 Commento replyStatus

null commento utente in entrata, "pending" la nostra risposta è in coda, "sent" consegnata, "failure" consegna non riuscita.


Domande aperte

Tre punti in cui le specifiche interne e lo Swagger generato dal codice non sono d’accordo. Uno la richiesta con gettone reale li salda tutti; fino ad allora, scrivi al cliente sulla difensiva.

#DomandaSpecificazioneSpavalderiaCome controllare
1Intestazione di autenticazione per /api/meta/*X-Authorization-Keysolo Bearer dichiaraticurl -i -H "X-Authorization-Key: <token>" ".../api/meta/posts?perPage=1" — aspettati 200, non 401
2Campo contatore nelle risposte MetatotalCounttotalStessa richiesta: leggi la chiave JSON root
3tipo author.type e codice di stato reply"meta_user" / "owner", 202 con corpoint [0,1], 200 senza corpocurl -i .../api/meta/comments?perPage=1 più una risposta di prova

Guida provvisoria:

  • contatore: leggi total ?? totalCount;
  • author.type — accetta sia una stringa che un numero intero (0 ↔ meta_user, 1 ↔ owner, mappatura da confermare);
  • reply — considera qualsiasi 2xx come successo, non richiede alcun corpo, prende lo stato finale dal callback source: 13.

Note di implementazione

  • L’autenticazione varia in base al gruppo di endpoint — /api/meta/* utilizza X-Authorization-Key, chat e gli operatori usano Bearer, restapi accetta entrambi.
  • L’impaginazione è scritta in due modi — per_page su /api/chat/chats, perPage su /api/meta/* e /api/chat/callback-events.
  • I campi multipart/form-data sono PascalCase con notazione punto (Media.File, Media.Type).
  • I campi nulli vengono omessi dalle richiamate — una chiave assente significa null.
  • phone di solito è null su Instagram. Identifica il cliente tramite instagramUser.id / metaUserId e il negozio per instaAccount.id (il valore del filtro entityId).
  • Story.Id da una richiamata può essere passato direttamente come id / postId alla Meta API.
  • Controlla il JWT expiresAt dell’operatore prima di utilizzarlo in un deeplink o nel widget.