Intégration des API Meta et Instagram
Référence pour créer une application Instagram sur la Plateforme SMSBAT ChatHub : authentification, Conversations directes Instagram, commentaires sur les publications et les bobines, réponses aux histoires, webhooks et sondages.
Sources
Cette page fusionne la spécification interne de l’API Meta Comments avec l’OpenAPI en direct
définitions à https://chatapi.smsbat.com/swagger/v1/swagger.json et
https://restapi.smsbat.com/swagger/v1/swagger.json. Là où les deux ne sont pas d’accord, le
la différence est signalée en ligne et répertoriée sous Questions ouvertes.
1. URL de base
| Objectif | URL |
|---|---|
| API de chat + méta-API | https://chatapi.smsbat.com |
| Interface utilisateur Swagger / OpenAPI | https://chatapi.smsbat.com/index.html · …/swagger/v1/swagger.json |
| API REST (organisations, URL de rappel) | https://restapi.smsbat.com |
| API REST Swagger | https://restapi.smsbat.com/swagger/v1/swagger.json |
| Panneau Web de l’opérateur | https://chat.smsbat.com |
2. Authentification
Le schéma d’authentification dépend du groupe de points de terminaison. Les mélanger est la cause la plus fréquente du 401.
| Groupe | En-tête |
|---|---|
chatapi.smsbat.com/api/meta/* (messages, commentaires) | 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 · Authentification de base |
Le jeton d’organisation pour X-Authorization-Key est émis dans le panneau sous Profil.
Les JWT de l’entreprise et de l’opérateur proviennent de /api/company/get-token et /api/operator/get-token.
Différence
Le document chatapi OpenAPI déclare un schéma de sécurité unique — Bearer — et l’applique
à l’échelle mondiale. X-Authorization-Key n’y est pas du tout déclaré, bien que le Meta interne
La spécification de l’API Commentaires le nomme /api/meta/*. Il est très probablement géré par
middleware qui n’est pas reflété dans Swagger. Confirmez empiriquement avant d’expédier.
2.1 Jeton d’entreprise
POST https://chatapi.smsbat.com/api/company/get-token
Content-Type: application/json
{ "login": "company_login", "password": "company_password" }
200 OK renvoie une chaîne de jeton nue.
2.2 Organisations
GET https://chatapi.smsbat.com/api/company/organization
Authorization: Bearer <company_token>
[ { "id": 24, "name": "My Instagram Store" } ]
2.3 Opérateurs dans une organisation
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" }
}
]
Statuts de l’opérateur : 0 Actif, 1 Inactif, 2 Supprimé.
2.4 Ajouter/synchroniser des opérateurs
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 Opérateur 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 renvoie le JWT sous forme de chaîne.
2.6 Valider un jeton d’opérateur
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
}
Lorsqu’il n’est pas valide : { "isValid": false, "error": "Invalid token" }.
2.7 Intégrer le panneau de discussion de l’opérateur
<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. Liens profonds vers le panneau de discussion
Un système externe (CRM, ERP, site internet) peut ouvrir une conversation spécifique dans
https://chat.smsbat.com/. L’opérateur est autorisé par un JWT passé en paramètre de requête.
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>
| Paramètre | Descriptif |
|---|---|
chat_raw_id | Identifiant de discussion |
phone | Numéro de téléphone au format international |
from | Identifiant de marque/compte professionnel (bm_id) |
source | Source du chat — 7 pour Instagram, voir §8.1 |
token | Opérateur JWT valide et non expiré avec accès aux chats |
Un JWT invalide amène le visiteur sur l’écran de connexion du panneau de commande.
4. Conversations directes sur Instagram
4.1 Liste des discussions
GET https://chatapi.smsbat.com/api/chat/chats?source=7&page=1&per_page=20
Authorization: Bearer <token>
Note
La pagination ici est per_page (snake_case). Sous /api/meta/* et le scrutin
le point final est perPage (camelCase). Ce n’est pas une faute de frappe : l’API utilise les deux.
Paramètres de requête, tous facultatifs :
| Paramètre | Tapez | Descriptif |
|---|---|---|
source | ChatSource | 7 restreint les résultats à Instagram |
entityId | int | Identifiant du compte professionnel. Appliqué uniquement avec source |
instagram_user_id | int | ID utilisateur Instagram dans ChatHub |
facebook_user_id | int | ID utilisateur Facebook dans ChatHub |
page / per_page | int | Pagination, valeurs par défaut 1 / 20 |
status | ChatStatus[] | Statut du chat, reproductible |
search | string | Recherche en texte libre (nom, téléphone, …) |
organizationId | int | Identifiant de l’organisation |
operatorId | int[] | Filtrer par opérateurs assignés |
date | string[] | Deux bornes : ?date=…&date=… |
isChain | bool | Renvoie les discussions sous forme de chaînes, transportant les messages des discussions précédentes |
isUnread, starMark, isOperator, isAIAgent | bool | Filtres supplémentaires |
phone, email, contactId, clientId, tagIds, rate, sortedBy | — | Autres filtres |
200 OK renvoie 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": []
}
]
}
Les champs importants pour une application Instagram :
| Champ | Signification |
|---|---|
instaAccount | Le Compte professionnel Instagram (la boutique). id est la valeur du filtre entityId ; name est le nom du compte de Meta |
instagramUser | Le client. name est le pseudo Instagram, id est la valeur du filtre instagram_user_id |
metaUserId | L’identifiant du client du côté de Meta (chaîne) |
messSource | 7 pour Instagram |
phone | Habituellement null pour Instagram — ne l’utilisez pas comme clé |
ChatDTO porte également 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 et taggedMessages.
4.2 Messages de discussion
GET https://chatapi.smsbat.com/api/chat/chats/1867/messages?isChain=false
Authorization: Bearer <token>
200 OK renvoie un tableau 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 est renseigné lorsque le message concerne une publication ou une histoire Instagram – transmettez-le
directement en tant que id / postId à la Meta API. media est un ChatMediaDTO :
{ name, format, type, uri, raw, length, isUploaded }.
4.3 Envoyer un message (JSON)
POST https://chatapi.smsbat.com/api/chat/1867/message
Authorization: Bearer <token>
Content-Type: application/json
Corps — 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
}
}
| Champ | Tapez | Descriptif |
|---|---|---|
textMessage | string? | Texte du message. Peut être vide lorsque media est présent |
author | AuthorMessage? | 0 opérateur, 1 client |
isInternal | bool? | true marque une note interne qui n’est pas remise au client |
replyToMessageId | int? | ID du message auquel on répond |
appGuid | uuid? | GUID de référence |
media | MediaDTO? | { name, format, dataBase64, thumbnail, duration, type } |
200 OK → { "id": 9930, "messageStatus": 0 }
Un GUID de référence peut également être transmis dans le chemin :
POST /api/chat/{chatId}/{referralGuid}/message (de même …/message/v1, …/message/v2).
4.4 Envoyer un fichier ou une vidéo (multipart, v2)
POST https://chatapi.smsbat.com/api/chat/1867/message/v2
Authorization: Bearer <token>
Content-Type: multipart/form-data
Les noms des champs du formulaire sont en PascalCase avec la notation par points
textMessage et media.file sont silencieusement ignorés. Utilisez les noms exacts ci-dessous.
| Champ de formulaire | Tapez | Descriptif |
|---|---|---|
TextMessage | string | Texte du message |
Author | int | 0 opérateur, 1 client |
IsInternal | bool | Note interne |
ReplyToMessageId | int | Message auquel on répond |
AppGuid | uuid | GUID de référence |
Media.File | binary | Le fichier lui-même |
Media.Name | string | Nom du fichier |
Media.Format | string | Type MIME (video/mp4, image/png, application/pdf) |
Media.Type | MediaType | Voir §8.5 |
Media.DataBase64 | string | Alternative à Media.File |
Media.Thumbnail | string | Image d’aperçu vidéo Base64 |
Media.Duration | double | Durée de la vidéo en secondes |
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 Modifier le statut du chat
PUT https://chatapi.smsbat.com/api/chat/status
Authorization: Bearer <token>
Content-Type: application/json
{ "id": 1867, "status": 4 }
200 OK fait écho à l’objet mis à jour.
4.6 Mettre à jour les statuts des messages
PUT https://chatapi.smsbat.com/api/chat/messages/status
Authorization: Bearer <token>
Content-Type: application/json
{ "status": 3, "messageIds": [9928, 9929] }
4.7 Supprimer une discussion
DELETE https://chatapi.smsbat.com/api/chat/chats/1867
Authorization: Bearer <token>
5. Publications, bobines et histoires
Chemin de base : https://chatapi.smsbat.com/api/meta
Authentification : X-Authorization-Key: <organization token>
5.1 Liste des publications, des bobines et des histoires
GET https://chatapi.smsbat.com/api/meta/posts?platform=instagram&mediaType=story&page=1&perPage=20
X-Authorization-Key: <token>
| Paramètre | Tapez | Obligatoire | Descriptif |
|---|---|---|---|
page | int | non | Page, par défaut 1 |
perPage | int | non | Éléments par page, par défaut 20 |
id | int | non | Filtrer par ID de publication interne |
platform | string | non | instagram ou facebook |
mediaType | string | non | post, reel ou story. Tous les types lorsqu’ils sont omis |
# 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"
}
}
]
}
Différence — nom du champ du compteur
Le schéma Swagger MetaCommentPostListItemDtoPaginationDTO définit total. Le
documents de spécifications internes totalCount. Swagger est généré à partir du code, donc
total est la vérité la plus probable. Analysez total ?? totalCount jusqu’à ce que cela soit réglé.
| Champ | Descriptif |
|---|---|
id | ID de poste interne |
metaId | Publication externe / Reel / Story ID dans Meta |
text | Légende du message |
imageUrl | URL du média proxy saisie par le MetaPost.Guid non séquentiel ou null |
platform | facebook ou instagram |
mediaType | post, reel ou story |
createdAt | Date de création (date de la plateforme ou date de la base de données) |
story | Présent uniquement pour mediaType: "story" |
story.id | ID d’histoire interne ; égal à post.id |
story.metaId | ID d’histoire externe dans Meta |
story.url | URL proxy stable du média Story stocké ; null si le média n’a pas pu être enregistré |
Les médias postaux sont desservis par deux routes : GET /api/meta/post/media/{id:int} pour le retour
compatibilité et GET /api/meta/post/media/{guid:guid}. Nouvelles réponses et rappels d’API
générez toujours le formulaire GUID.
5.2 Liste des commentaires
GET https://chatapi.smsbat.com/api/meta/comments?platform=instagram&postId=42&page=1&perPage=20
X-Authorization-Key: <token>
| Paramètre | Tapez | Obligatoire | Descriptif |
|---|---|---|---|
page | int | non | Page, par défaut 1 |
perPage | int | non | Éléments par page, par défaut 20 |
postId | int | non | Filtrer par ID de publication |
parentCommentId | int | non | Commentaires des enfants (réponses) d’un commentaire donné |
platform | string | non | facebook ou 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..."
}
}
]
}
| Champ | Descriptif |
|---|---|
id | ID de commentaire interne |
metaId | ID externe dans Meta. null pour une de nos réponses en attente jusqu’à son envoi |
text | Texte du commentaire |
createdAt | Date de création |
platform | facebook ou instagram |
replyStatus | null pour un commentaire utilisateur entrant ; "pending" / "sent" / "failure" pour notre réponse |
author.type | "meta_user" utilisateur externe, "owner" propriétaire de la page |
author.name | Nom de l’auteur |
author.metaUserId | ID utilisateur étendu dans Meta ; null pour "owner" |
post | La publication, la bobine ou l’histoire à laquelle appartient le commentaire |
post.mediaType | post, reel ou story |
post.story | Référence de l’histoire { id, metaId, url }, Histoires uniquement |
mediaUrl | Média joint au commentaire, ou null |
replyTo | Commentaire des parents { id, metaId, text } ; null au plus haut niveau |
Écart — type de `author.type`
La spécification interne documente les chaînes "meta_user" / "owner". Types fanfarons
MetaCommentAuthorType sous forme de entier avec l’énumération [0, 1]. Un JsonStringEnumConverter
expliquerait l’écart, mais cela n’a pas été confirmé par une réponse réelle. Écrivez un
analyseur qui accepte les deux.
5.3 Répondre à un commentaire
Met en file d’attente une réponse pour livraison.
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"
Corps de la requête : { "text": "Reply text" }
202 Accepted renvoie l’objet commentaire — même forme que GET /api/meta/comments — avec
replyStatus: "pending" et metaId: null. Le résultat de la livraison arrive plus tard sous forme de
Rappel source: 13 (§6.4).
Écart – code de réponse
Swagger déclare 200 sans corps ; la spécification interne déclare 202 Accepted
avec le commentaire comme corps. Le contrôleur manque probablement d’un ProducesResponseType
attribut, laissant Swagger sur sa valeur par défaut. Acceptez n’importe quel 2xx et ne dépendez pas d’un corps.
6. Webhooks
SMSBAT envoie POST requêtes avec application/json à votre URL et attend HTTP 200 en retour.
Les champs nuls sont entièrement omis
Un champ dont la valeur est null n’est pas du tout sérialisé dans le corps du rappel. Pour un
message qui ne vient pas de Facebook ou d’Instagram, il n’y a tout simplement pas de touche MetaUserId.
Traitez « absent » et null comme la même chose.
6.1 Enregistrez une URL de rappel
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
}'
| Champ | Tapez | Descriptif |
|---|---|---|
url | string | Votre point de terminaison |
source | SendingSourceCallback | Type d’événement, voir §8.2 |
headerName / headerValue | string | En-tête d’authentification arbitraire que nous attachons à la demande (facultatif) |
channelType | ChatSource | Chaîne. 7 pour Instagram. Facultatif |
channelEntityId | int | Un compte professionnel spécifique. Nécessite channelType |
Sans channelType, l’URL reçoit les événements de chaque canal.
Tip
La couverture complète des commentaires nécessite deux inscriptions : source: 12 pour les nouveaux commentaires et
source: 13 pour les statuts de réponse. Pour les réponses Direct et Story, ajoutez source: 3
(et 11 si vous voulez chaque message de chat).
Opérations restantes :
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 renvoie :
[
{
"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 Nouveau message et réponse Instagram Story (source: 3, 11)
La réponse d’un utilisateur à une histoire Instagram arrive sous la forme d’un message ordinaire dans ces rappels,
avec un bloc Story supplémentaire de niveau supérieur :
{
"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"
}
}
| Champ | Descriptif |
|---|---|
ChatId / MessageId | Identifiants de chat et de message |
Author | 0 utilisateur, 1 opérateur |
Username | Nom d’affichage ou identifiant Instagram / Facebook |
UserId | ID utilisateur numérique interne dans SMSBAT |
MetaUserId | ID étendu de l’interlocuteur dans Meta. Dans un message d’opérateur sortant, cela identifie toujours l’utilisateur méta du chat, pas l’opérateur |
ShopId | ID interne du compte professionnel Instagram / Facebook |
ShopName | Nom du compte professionnel tel que reçu de Meta au moment de la connexion |
MessageText | Texte du message |
MessageMedia | URL du média lorsque le message est un média |
type_messenger | Source, 7 pour Instagram |
operator_name | Nom de l’opérateur lorsque Author = 1 |
Story | Présenter uniquement sur une réponse Story entrante |
Story.Id | ID d’histoire interne (MetaPost) — utilisable directement comme id / postId dans la Meta API |
Story.MetaId | ID d’histoire externe dans Meta |
Story.Url | URL proxy stable du média Story stocké. Absent lorsque le média n’a pas pu être enregistré — le bloc Story et le message sont toujours délivrés |
`Author` est inversé par rapport à l'API Chat
Dans ChatMessageDTO.author, 0 signifie opérateur et 1 signifie client. Dans ce rappel, c’est
à l’inverse : 0 est l’utilisateur, 1 est l’opérateur. Ne partagez pas le mappage.
6.3 Nouveau commentaire (source: 12)
Se déclenche lorsqu’un utilisateur Meta commente une publication Facebook ou une publication / Reel Instagram.
Note
Instagram Les réponses aux histoires ne sont pas envoyées via source: 12. Elles arrivent comme d’habitude
messages entrants sur source: 3 et/ou 11 avec un bloc Story — voir §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 État de la réponse aux commentaires (source: 13)
Se déclenche après que nous avons tenté de fournir une réponse, que celle-ci réussisse ou échoue.
{
"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 Champs de rappel des commentaires partagés
Les deux rappels de commentaires partagent une forme de corps et ne diffèrent que par type.
| Champ | Descriptif |
|---|---|
type | "new_comment" ou "comment_status" |
platform | "facebook" ou "instagram" |
comment.id | ID de commentaire interne |
comment.metaId | ID externe dans Meta ; null pour une réponse en attente avant son envoi |
comment.parentCommentId | ID du commentaire parent. Absent pour un commentaire de niveau supérieur |
comment.parentMetaId | ID de commentaire parent externe. Absent au plus haut niveau |
comment.parentCommentText | Texte du commentaire des parents. Absent au plus haut niveau |
comment.text | Texte du commentaire |
comment.createdAt | Date de création |
comment.updatedAt | Dernière mise à jour. Absent si le commentaire n’a jamais été édité |
comment.replyStatus | "pending" / "sent" / "failure". Absent pour un commentaire utilisateur entrant |
comment.author.type | "meta_user" ou "owner" |
comment.author.name | Nom de l’auteur |
comment.author.metaUserId | ID d’auteur étendu dans Meta. Absent pour le "owner" |
comment.mediaUrl | Commentez les médias. Absent quand il n’y en a pas |
post.id | ID de poste interne |
post.metaId | Publication externe / Reel / Story ID dans Meta |
post.text | Texte du message |
post.imageUrl | URL de la publication, ou null |
post.createdAt | Date de création du message |
post.mediaType | Dans les rappels de commentaires, uniquement post ou reel |
6.6 Nouveau chat (source: 7)
{ "ChatId": 12345, "Phone": "+380501234567", "chat.Source": 7 }
6.7 Modifications de l’état des messages et du chat (source: 6 / 5)
{ "name": "changed_message_status", "id": 9928, "status": 6 }
{ "name": "changed_chat_status", "id": 1867, "status": 4 }
6.8 Message modifié ou supprimé (source: 9)
{ "messageId": 9930, "text": "Updated message text" }
{ "messageId": 9931, "delete": true }
6.9 Indicateur de frappe (source: 8)
{ "chat_id": 1867, "event": "start_typing", "operator_name": "Iryna" }
{ "chat_id": 1867, "event": "end_typing" }
7. Sondage d’événements
Pour les environnements qui ne peuvent pas accepter le HTTP entrant.
7.1 Récupérer les événements
GET https://chatapi.smsbat.com/api/chat/callback-events?page=1&perPage=20
Authorization: Bearer <token>
| Paramètre | Descriptif |
|---|---|
organizationId | Facultatif. Extrait du jeton en cas d’omission |
page / perPage | Pagination, valeurs par défaut 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"
}
]
}
Chaque événement porte event_guid, timestamp, organization_id et callback_type — un
chaîne correspondant aux valeurs source du §8.2. Les champs restants correspondent aux champs correspondants
webhook au §6.
7.2 Acquitter les événements traités
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 }
Les événements déjà supprimés ne comptent tout simplement pas dans le calcul du deleted. La commande et les tentatives sont à vous
la responsabilité du côté.
7.3 Boucle recommandée
- Sondez
GET /api/chat/callback-eventsselon un calendrier. - Traitez les événements dans votre service.
- Envoyez la liste
event_guidtraitée au/callback-events/processed. - Répétez.
8. Référence d’énumération
8.1 ChatSource — canal (0–9)
| Codes | Chaîne |
|---|---|
| 0 | Viber |
| 1 | ViberBot |
| 2 | TélégrammeBot |
| 3 | |
| 4 | Widget |
| 5 | Rozetka |
| 6 | |
| 7 | |
| 8 | Bal de promo |
| 9 | Olx |
8.2 SendingSourceCallback — type d’événement de rappel (0–13)
| Codes | Événement |
|---|---|
| 3 | Chat — nouveau message de discussion, y compris les réponses de l’histoire |
| 5 | Statut du chat modifié |
| 6 | Statut du message modifié |
| 7 | Nouveau chat créé |
| 8 | Indicateur de frappe |
| 9 | Message mis à jour ou supprimé |
| 11 | AnyChatMessage — n’importe quel message de discussion |
| 12 | MetaNewComment — nouveau commentaire Instagram / Facebook |
| 13 | MetaCommentStatus — état de livraison de notre réponse au commentaire |
L’énumération s’étend sur 0–13 ; les valeurs restantes ne sont pas nécessaires pour les intégrations Instagram.
8.3 ChatStatus (0–4)
0 Nouveau, 1 Ouvert, 2 En attente, 3 En Pause, 4 Fermé
8,4 MessageStatus (0-11)
| Codes | Nom |
|---|---|
| 0 | NOUVEAU |
| 1 | SUCCÈS |
| 2 | REJETÉ |
| 3 | LIRE |
| 4 | INCONNU |
| 5 | TRAITEMENT |
| 6 | LIVRÉ |
| 7 | BLOCKED_BY_USER |
| 8 | USER_NOT_FOUND |
L’énumération s’étend sur 0–11. Les valeurs 9, 10 et 11 existent dans l’API mais ne sont pas encore documentées —
traitez-les comme UNKNOWN.
8,5 MediaType (1–10)
1 Photo, 2 Fichier, 3 Audio, 4 Vidéo, 5 Autocollant, 6 AutocollantAnimé,
7 AutocollantVidéo, 8 Animation, 9 Voix, 10 VidéoNote
8.6 AuthorMessage — auteur dans l’API Chat (0–4)
0 Opérateur, 1 Client, 2 Bot, 3 ViberAccount
L’énumération s’étend sur 0–4 ; la valeur 4 n’est pas documentée. Les rappels “nouveau message” utilisent le
mappage opposé — voir §6.2.
8,7 ChatMessageType (0–2)
0 Texte, 1 Photo, 2 Fichier
8.8 Commentaire replyStatus
null commentaire utilisateur entrant, "pending" notre réponse est en file d’attente, "sent" livrée,
La livraison "failure" a échoué.
Questions ouvertes
Trois points sur lesquels la spécification interne et le Swagger généré par le code sont en désaccord. Un la demande avec un vrai jeton les règle tous ; en attendant, écrivez au client sur la défensive.
| # | Question | Spécification | Fanfaronnade | Comment vérifier |
|---|---|---|---|---|
| 1 | En-tête d’authentification pour /api/meta/* | X-Authorization-Key | seulement Bearer déclarés | curl -i -H "X-Authorization-Key: <token>" ".../api/meta/posts?perPage=1" — attendez-vous à 200, pas à 401 |
| 2 | Champ de compteur dans les réponses méta | totalCount | total | Même requête : lisez la clé racine JSON |
| 3 | Type author.type et code d’état reply | "meta_user" / "owner", 202 avec corps | int [0,1], 200 sans corps | curl -i .../api/meta/comments?perPage=1 plus une réponse test |
Orientations provisoires :
- compteur — lire
total ?? totalCount; author.type— accepte à la fois une chaîne et un entier (0↔meta_user,1↔owner, mappage à confirmer) ;reply— traite tout2xxcomme un succès, ne nécessite aucun corps, prend le statut final du rappelsource: 13.
Notes d’implémentation
- L’authentification diffère selon le groupe de points de terminaison —
/api/meta/*utiliseX-Authorization-Key, les chats et les opérateurs utilisentBearer,restapiaccepte non plus. - La pagination s’écrit de deux manières —
per_pagesur/api/chat/chats,perPagesur/api/meta/*et/api/chat/callback-events. - Les champs
multipart/form-datasont en PascalCase avec la notation par points (Media.File,Media.Type). - Les champs nuls sont omis des rappels — une clé absente signifie
null. phoneest généralementnullsur Instagram. Identifiez le client parinstagramUser.id/metaUserIdet la boutique parinstaAccount.id(la valeur du filtreentityId).Story.Idd’un rappel peut être transmis directement sous la formeid/postIdà la Meta API.- Vérifiez le
expiresAtde l’opérateur JWT avant de l’utiliser dans un lien profond ou le widget.