Meta- und Instagram-API-Integration
Referenz zum Erstellen einer Instagram-App auf der SMSBAT ChatHub-Plattform: Authentifizierung, Instagram Direct-Konversationen, Kommentare zu Posts und Reels, Story-Antworten, Webhooks und Umfragen.
Quellen
Diese Seite führt die interne Meta-Kommentar-API-Spezifikation mit der Live-OpenAPI zusammen
Definitionen bei https://chatapi.smsbat.com/swagger/v1/swagger.json und
https://restapi.smsbat.com/swagger/v1/swagger.json. Wo die beiden anderer Meinung sind, ist die
Der Unterschied wird inline angezeigt und unter Offene Fragen aufgeführt.
1. Basis-URLs
| Zweck | URL |
|---|---|
| Chat-API + Meta-API | https://chatapi.smsbat.com |
| Swagger-Benutzeroberfläche / OpenAPI | https://chatapi.smsbat.com/index.html · …/swagger/v1/swagger.json |
| REST-API (Organisationen, Rückruf-URLs) | https://restapi.smsbat.com |
| REST-API-Swagger | https://restapi.smsbat.com/swagger/v1/swagger.json |
| Operator-Webpanel | https://chat.smsbat.com |
2. Authentifizierung
Das Authentifizierungsschema hängt von der Endpunktgruppe ab. Ihre Verwechslung ist die häufigste Ursache für 401.
| Gruppe | Kopfzeile |
|---|---|
chatapi.smsbat.com/api/meta/* (Beiträge, Kommentare) | 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 · Grundlegende Authentifizierung |
Der Organisationstoken für X-Authorization-Key wird im Panel unter Profil ausgestellt.
Firmen- und Betreiber-JWTs stammen aus /api/company/get-token und /api/operator/get-token.
Diskrepanz
Das chatapi OpenAPI-Dokument deklariert ein einzelnes Sicherheitsschema – Bearer – und wendet es an
weltweit. X-Authorization-Key ist dort überhaupt nicht deklariert, obwohl die interne Meta
Die Kommentar-API-Spezifikation nennt es /api/meta/*. Es wird höchstwahrscheinlich von gehandhabt
Middleware, die nicht in Swagger widergespiegelt wird. Bestätigen Sie dies empirisch, bevor Sie versenden.
2.1 Firmentoken
POST https://chatapi.smsbat.com/api/company/get-token
Content-Type: application/json
{ "login": "company_login", "password": "company_password" }
200 OK gibt eine leere Token-Zeichenfolge zurück.
2.2 Organisationen
GET https://chatapi.smsbat.com/api/company/organization
Authorization: Bearer <company_token>
[ { "id": 24, "name": "My Instagram Store" } ]
2.3 Betreiber in einer 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" }
}
]
Betreiberstatus: 0 Aktiv, 1 Inaktiv, 2 Gelöscht.
2.4 Operatoren hinzufügen/synchronisieren
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 gibt das JWT als String zurück.
2.6 Validieren eines Operator-Tokens
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
}
Wenn ungültig: { "isValid": false, "error": "Invalid token" }.
2.7 Einbetten des Operator-Chat-Panels
<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 in das Chat-Panel
Ein externes System (CRM, ERP, Website) kann eine bestimmte Konversation öffnen
https://chat.smsbat.com/. Der Operator wird durch ein JWT autorisiert, das als Abfrageparameter übergeben wird.
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>
| Parameter | Beschreibung |
|---|---|
chat_raw_id | Chat-ID |
phone | Telefonnummer im internationalen Format |
from | Marken-/Geschäftskonto-ID (bm_id) |
source | Chat-Quelle – 7 für Instagram, siehe §8.1 |
token | Gültiges, nicht abgelaufenes Operator-JWT mit Zugriff auf Chats |
Ein ungültiges JWT führt den Besucher auf den Anmeldebildschirm des Bedienfelds.
4. Instagram-Direktgespräche
4.1 Chats auflisten
GET https://chatapi.smsbat.com/api/chat/chats?source=7&page=1&per_page=20
Authorization: Bearer <token>
Note
Die Paginierung hier ist per_page (snake_case). Unter /api/meta/* und der Umfrage
Endpunkt ist perPage (camelCase). Dies ist kein Tippfehler – die API verwendet beides.
Abfrageparameter, alle optional:
| Parameter | Geben Sie | ein Beschreibung |
|---|---|---|
source | ChatSource | 7 beschränkt die Ergebnisse auf Instagram |
entityId | int | Geschäftskonto-ID. Nur zusammen mit source |
instagram_user_id | int | Instagram-Benutzer-ID in ChatHub |
facebook_user_id | int | Facebook-Benutzer-ID in ChatHub |
page / per_page | int | Paginierung, Standardeinstellungen 1 / 20 |
status | ChatStatus[] | Chatstatus, wiederholbar |
search | string | Freitextsuche (Name, Telefon, …) |
organizationId | int | Organisations-ID |
operatorId | int[] | Nach zugewiesenen Operatoren filtern |
date | string[] | Zwei Grenzen: ?date=…&date=… |
isChain | bool | Chats als Ketten zurückgeben und Nachrichten aus vorherigen Chats enthalten |
isUnread, starMark, isOperator, isAIAgent | bool | Zusätzliche Filter |
phone, email, contactId, clientId, tagIds, rate, sortedBy | — | Andere Filter |
200 OK gibt GetChatsResponse zurück:
{
"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": []
}
]
}
Die Felder, die für eine Instagram-App wichtig sind:
| Feld | Bedeutung |
|---|---|
instaAccount | Das Instagram-Geschäftskonto (der Shop). id ist der Filterwert entityId; name ist der Kontoname von Meta |
instagramUser | Der Kunde. name ist das Instagram-Handle, id ist der instagram_user_id-Filterwert |
metaUserId | Die bereichsbezogene ID des Kunden auf Metas Seite (Zeichenfolge) |
messSource | 7 für Instagram |
phone | Normalerweise null für Instagram – nicht als Schlüssel verwenden |
ChatDTO trägt auch 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 und taggedMessages.
4.2 Chat-Nachrichten
GET https://chatapi.smsbat.com/api/chat/chats/1867/messages?isChain=false
Authorization: Bearer <token>
200 OK gibt ein Array von ChatMessageDTO zurück:
[
{
"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 wird ausgefüllt, wenn sich die Nachricht auf einen Instagram-Beitrag oder eine Story bezieht – geben Sie sie weiter
direkt zurück als id / postId zur Meta API. media ist ein ChatMediaDTO:
{ name, format, type, uri, raw, length, isUploaded }.
4.3 Eine Nachricht senden (JSON)
POST https://chatapi.smsbat.com/api/chat/1867/message
Authorization: Bearer <token>
Content-Type: application/json
Körper – 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
}
}
| Feld | Geben Sie | ein Beschreibung |
|---|---|---|
textMessage | string? | Nachrichtentext. Kann leer sein, wenn media vorhanden ist |
author | AuthorMessage? | 0 Operator, 1 Client |
isInternal | bool? | true markiert eine interne Notiz, die nicht an den Kunden zugestellt wird |
replyToMessageId | int? | ID der Nachricht, auf die geantwortet wird |
appGuid | uuid? | Empfehlungs-GUID |
media | MediaDTO? | { name, format, dataBase64, thumbnail, duration, type } |
200 OK → { "id": 9930, "messageStatus": 0 }
Im Pfad kann auch eine Verweis-GUID übergeben werden:
POST /api/chat/{chatId}/{referralGuid}/message (ebenso …/message/v1, …/message/v2).
4.4 Eine Datei oder ein Video senden (multipart, v2)
POST https://chatapi.smsbat.com/api/chat/1867/message/v2
Authorization: Bearer <token>
Content-Type: multipart/form-data
Formularfeldnamen sind PascalCase mit Punktnotation
textMessage und media.file werden stillschweigend ignoriert. Verwenden Sie unten die genauen Namen.
| Formularfeld | Geben Sie | ein Beschreibung |
|---|---|---|
TextMessage | string | Nachrichtentext |
Author | int | 0 Operator, 1 Client |
IsInternal | bool | Interner Hinweis |
ReplyToMessageId | int | Auf die Nachricht wird geantwortet |
AppGuid | uuid | Empfehlungs-GUID |
Media.File | binary | Die Datei selbst |
Media.Name | string | Dateiname |
Media.Format | string | MIME-Typ (video/mp4, image/png, application/pdf) |
Media.Type | MediaType | Siehe §8.5 |
Media.DataBase64 | string | Alternative zu Media.File |
Media.Thumbnail | string | Base64-Videovorschau-Frame |
Media.Duration | double | Videodauer in Sekunden |
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 Chatstatus ändern
PUT https://chatapi.smsbat.com/api/chat/status
Authorization: Bearer <token>
Content-Type: application/json
{ "id": 1867, "status": 4 }
200 OK gibt das aktualisierte Objekt wieder.
4.6 Nachrichtenstatus aktualisieren
PUT https://chatapi.smsbat.com/api/chat/messages/status
Authorization: Bearer <token>
Content-Type: application/json
{ "status": 3, "messageIds": [9928, 9929] }
4.7 Einen Chat löschen
DELETE https://chatapi.smsbat.com/api/chat/chats/1867
Authorization: Bearer <token>
5. Beiträge, Reels und Stories
Basispfad: https://chatapi.smsbat.com/api/meta
Authentifizierung: X-Authorization-Key: <organization token>
5.1 Posts, Reels und Stories auflisten
GET https://chatapi.smsbat.com/api/meta/posts?platform=instagram&mediaType=story&page=1&perPage=20
X-Authorization-Key: <token>
| Parameter | Geben Sie | ein Erforderlich | Beschreibung |
|---|---|---|---|
page | int | nein | Seite, Standard 1 |
perPage | int | nein | Elemente pro Seite, Standard 20 |
id | int | nein | Nach interner Beitrags-ID filtern |
platform | string | nein | instagram oder facebook |
mediaType | string | nein | post, reel oder story. Alle Typen, wenn weggelassen |
# 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"
}
}
]
}
Diskrepanz – Zählerfeldname
Das Swagger-Schema MetaCommentPostListItemDtoPaginationDTO definiert total. Die
interne Spezifikationsdokumente totalCount. Swagger wird also aus dem Code generiert
total ist die wahrscheinlichere Wahrheit. Analysieren Sie total ?? totalCount, bis dies geklärt ist.
| Feld | Beschreibung |
|---|---|
id | Interne Beitrags-ID |
metaId | Externer Beitrag/Reel/Story-ID in Meta |
text | Bildunterschrift |
imageUrl | Proxy-Medien-URL, verschlüsselt durch das nicht sequentielle MetaPost.Guid oder null |
platform | facebook oder instagram |
mediaType | post, reel oder story |
createdAt | Erstellungsdatum (Plattformdatum oder Datenbankdatum) |
story | Vorhanden nur für mediaType: "story" |
story.id | Interne Story-ID; gleich post.id |
story.metaId | Externe Story-ID in Meta |
story.url | Stabile Proxy-URL der gespeicherten Story-Medien; null wenn das Medium nicht gespeichert werden konnte |
Postmedien werden über zwei Routen bereitgestellt: GET /api/meta/post/media/{id:int} für rückwärts
Kompatibilität und GET /api/meta/post/media/{guid:guid}. Neue API-Antworten und Rückrufe
Generieren Sie immer das GUID-Formular.
5.2 Kommentare auflisten
GET https://chatapi.smsbat.com/api/meta/comments?platform=instagram&postId=42&page=1&perPage=20
X-Authorization-Key: <token>
| Parameter | Geben Sie | ein Erforderlich | Beschreibung |
|---|---|---|---|
page | int | nein | Seite, Standard 1 |
perPage | int | nein | Elemente pro Seite, Standard 20 |
postId | int | nein | Nach Beitrags-ID filtern |
parentCommentId | int | nein | Untergeordnete Kommentare (Antworten) eines bestimmten Kommentars |
platform | string | nein | facebook oder 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..."
}
}
]
}
| Feld | Beschreibung |
|---|---|
id | Interne Kommentar-ID |
metaId | Externe ID in Meta. null für eine ausstehende Antwort von uns bis zum Versand |
text | Kommentartext |
createdAt | Erstellungsdatum |
platform | facebook oder instagram |
replyStatus | null für einen eingehenden Benutzerkommentar; "pending" / "sent" / "failure" für unsere Antwort |
author.type | "meta_user" externer Benutzer, "owner" Seitenbesitzer |
author.name | Autorenname |
author.metaUserId | Bereichsbezogene Benutzer-ID in Meta; null für "owner" |
post | Der Beitrag, das Reel oder die Story, zu dem der Kommentar gehört |
post.mediaType | post, reel oder story |
post.story | Story-Referenz { id, metaId, url }, nur Stories |
mediaUrl | An den Kommentar angehängte Medien oder null |
replyTo | Elternkommentar { id, metaId, text }; null auf oberster Ebene |
Diskrepanz – Art von `author.type`
Die interne Spezifikation dokumentiert die Zeichenfolgen "meta_user" / "owner". Swagger-Typen
MetaCommentAuthorType als Ganzzahl mit Enumeration [0, 1]. Ein JsonStringEnumConverter
würde die Lücke erklären, aber das wurde nicht anhand einer echten Reaktion bestätigt. Schreiben Sie ein
Parser, der beides akzeptiert.
5.3 Auf einen Kommentar antworten
Stellt eine Antwort zur Zustellung in die Warteschlange.
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"
Anfragetext: { "text": "Reply text" }
202 Accepted gibt das Kommentarobjekt zurück – gleiche Form wie GET /api/meta/comments – mit
replyStatus: "pending" und metaId: null. Das Lieferergebnis kommt später als
source: 13 Rückruf (§6.4).
Diskrepanz – Antwortcode
Swagger erklärt 200 ohne Körper; Die interne Spezifikation deklariert 202 Accepted
mit dem Kommentar als Text. Dem Controller fehlt höchstwahrscheinlich ein ProducesResponseType
Attribut, wobei Swagger auf der Standardeinstellung belassen wird. Akzeptieren Sie alle 2xx und verlassen Sie sich nicht auf einen Körper.
6. Webhooks
SMSBAT sendet POST-Anfragen mit application/json an Ihre URL und erwartet HTTP 200 zurück.
Nullfelder werden komplett weggelassen
Ein Feld mit dem Wert null wird überhaupt nicht in den Rückruftext serialisiert. Für einen
Bei Nachrichten, die nicht von Facebook oder Instagram stammen, gibt es einfach keinen MetaUserId-Schlüssel.
Behandeln Sie „abwesend“ und null als dasselbe.
6.1 Registrieren Sie eine Rückruf-URL
curl -X POST 'https://restapi.smsbat.com/organizations/callback_urls' \
-H 'X-Authorization-Key: <token>' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://your-server.com/webhook",
"source": 12,
"headerName": "X-Webhook-Secret",
"headerValue": "your-secret",
"channelType": 7,
"channelEntityId": 12
}'
| Feld | Geben Sie | ein Beschreibung |
|---|---|---|
url | string | Ihr Endpunkt |
source | SendingSourceCallback | Ereignistyp, siehe §8.2 |
headerName / headerValue | string | Beliebiger Authentifizierungsheader, den wir an die Anfrage anhängen (optional) |
channelType | ChatSource | Kanal. 7 für Instagram. Optional |
channelEntityId | int | Ein bestimmtes Geschäftskonto. Erfordert channelType |
Ohne channelType empfängt die URL Ereignisse von jedem Kanal.
Tip
Für eine vollständige Kommentarabdeckung sind zwei Registrierungen erforderlich: source: 12 für neue Kommentare und
source: 13 für Antwortstatus. Für Direkt- und Story-Antworten fügen Sie source: 3 hinzu
(und 11, wenn Sie jede Chat-Nachricht möchten).
Verbleibende Operationen:
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 gibt Folgendes zurück:
[
{
"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 Neue Nachricht und Instagram-Story-Antwort (source: 3, 11)
Die Antwort eines Benutzers auf eine Instagram-Story kommt in diesen Rückrufen als normale Nachricht an.
mit einem zusätzlichen Story-Block der obersten Ebene:
{
"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"
}
}
| Feld | Beschreibung |
|---|---|
ChatId / MessageId | Chat- und Nachrichten-IDs |
Author | 0 Benutzer, 1 Operator |
Username | Instagram-/Facebook-Anzeigename oder -Handle |
UserId | Interne numerische Benutzer-ID in SMSBAT |
MetaUserId | Bereichsbezogene ID des Gesprächspartners in Meta. Bei einer ausgehenden Operator-Nachricht identifiziert dies immer noch den Meta-Benutzer des Chats, nicht den Operator |
ShopId | Interne ID des Instagram-/Facebook-Geschäftskontos |
ShopName | Name des Geschäftskontos, wie er zum Zeitpunkt der Verbindung von Meta erhalten wurde |
MessageText | Nachrichtentext |
MessageMedia | Medien-URL, wenn es sich bei der Nachricht um Medien |
type_messenger | Quelle, 7 für Instagram |
operator_name | Betreibername, wenn Author = 1 |
Story | Präsentiert nur bei einer eingehenden Story-Antwort |
Story.Id | Interne Story-ID (MetaPost) – direkt verwendbar als id / postId in der Meta-API |
Story.MetaId | Externe Story-ID in Meta |
Story.Url | Stabile Proxy-URL der gespeicherten Story-Medien. Abwesend, wenn das Medium nicht gespeichert werden konnte – der Story-Block und die Nachricht werden weiterhin zugestellt |
`Author` ist relativ zur Chat-API invertiert
In ChatMessageDTO.author bedeutet 0 Betreiber und 1 Kunde. In diesem Rückruf ist es so
umgekehrt: 0 ist der Benutzer, 1 ist der Operator. Teilen Sie die Zuordnung nicht.
6.3 Neuer Kommentar (source: 12)
Wird ausgelöst, wenn ein Meta-Benutzer einen Facebook-Beitrag oder einen Instagram-Beitrag/Reel kommentiert.
Note
Instagram Story-Antworten werden nicht über source: 12 zugestellt. Sie kommen wie gewohnt an
Eingehende Nachrichten auf source: 3 und/oder 11 mit einem Story-Block – siehe §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 Kommentarantwortstatus (source: 13)
Wird ausgelöst, nachdem wir versucht haben, eine Antwort zu übermitteln, unabhängig davon, ob dies erfolgreich ist oder fehlschlägt.
{
"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 Rückruffelder für freigegebene Kommentare
Beide Kommentarrückrufe haben eine Körperform gemeinsam und unterscheiden sich nur um type.
| Feld | Beschreibung |
|---|---|
type | "new_comment" oder "comment_status" |
platform | "facebook" oder "instagram" |
comment.id | Interne Kommentar-ID |
comment.metaId | Externe ID in Meta; null für eine ausstehende Antwort, bevor sie gesendet wird |
comment.parentCommentId | ID des übergeordneten Kommentars. Abwesend für einen Top-Level-Kommentar |
comment.parentMetaId | Externe übergeordnete Kommentar-ID. Auf oberster Ebene nicht vorhanden |
comment.parentCommentText | Kommentartext des übergeordneten Elements. Auf oberster Ebene nicht vorhanden |
comment.text | Kommentartext |
comment.createdAt | Erstellungsdatum |
comment.updatedAt | Letztes Update. Fehlt, wenn der Kommentar nie bearbeitet wurde |
comment.replyStatus | "pending" / "sent" / "failure". Abwesend für einen eingehenden Benutzerkommentar |
comment.author.type | "meta_user" oder "owner" |
comment.author.name | Autorenname |
comment.author.metaUserId | Bereichsbezogene Autoren-ID in Meta. Abwesend für "owner" |
comment.mediaUrl | Kommentarmedien. Abwesend, wenn es keines gibt |
post.id | Interne Beitrags-ID |
post.metaId | Externer Beitrag/Reel/Story-ID in Meta |
post.text | Beitragstext |
post.imageUrl | Bild-URL posten, oder null |
post.createdAt | Erstellungsdatum des Beitrags |
post.mediaType | Bei Kommentarrückrufen nur post oder reel |
6.6 Neuer Chat (source: 7)
{ "ChatId": 12345, "Phone": "+380501234567", "chat.Source": 7 }
6.7 Nachrichten- und Chat-Statusänderungen (source: 6 / 5)
{ "name": "changed_message_status", "id": 9928, "status": 6 }
{ "name": "changed_chat_status", "id": 1867, "status": 4 }
6.8 Nachricht bearbeitet oder gelöscht (source: 9)
{ "messageId": 9930, "text": "Updated message text" }
{ "messageId": 9931, "delete": true }
6.9 Tippanzeige (source: 8)
{ "chat_id": 1867, "event": "start_typing", "operator_name": "Iryna" }
{ "chat_id": 1867, "event": "end_typing" }
7. Ereignisabfrage
Für Umgebungen, die eingehendes HTTP nicht akzeptieren können.
7.1 Ereignisse abrufen
GET https://chatapi.smsbat.com/api/chat/callback-events?page=1&perPage=20
Authorization: Bearer <token>
| Parameter | Beschreibung |
|---|---|
organizationId | Optional. Wird aus dem Token übernommen, wenn es weggelassen wird |
page / perPage | Paginierung, Standardeinstellungen 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"
}
]
}
Jedes Ereignis trägt event_guid, timestamp, organization_id und callback_type – a
Zeichenfolge, die den source-Werten in §8.2 entspricht. Die übrigen Felder stimmen mit den entsprechenden überein
Webhook in §6.
7.2 Verarbeitete Ereignisse quittieren
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 }
Bereits entfernte Ereignisse zählen einfach nicht für deleted. Die Bestellung und Wiederholungsversuche obliegen Ihnen
Verantwortung der Seite.
7.3 Empfohlene Schleife
- Umfrage
GET /api/chat/callback-eventsnach Zeitplan. - Verarbeiten Sie die Ereignisse in Ihrem Dienst.
- Senden Sie die verarbeitete
event_guid-Liste an/callback-events/processed. - Wiederholen.
8. Enum-Referenz
8.1 ChatSource – Kanal (0–9)
| Code | Kanal |
|---|---|
| 0 | Viber |
| 1 | ViberBot |
| 2 | TelegramBot |
| 3 | |
| 4 | Widget |
| 5 | Rozetka |
| 6 | |
| 7 | |
| 8 | Abschlussball |
| 9 | Olx |
8.2 SendingSourceCallback – Rückrufereignistyp (0–13)
| Code | Veranstaltung |
|---|---|
| 3 | Chat – neue Chat-Nachricht, einschließlich Story-Antworten |
| 5 | Chatstatus geändert |
| 6 | Nachrichtenstatus geändert |
| 7 | Neuer Chat erstellt |
| 8 | Tippanzeige |
| 9 | Nachricht aktualisiert oder gelöscht |
| 11 | AnyChatMessage – jede Chat-Nachricht |
| 12 | MetaNewComment – neuer Instagram-/Facebook-Kommentar |
| 13 | MetaCommentStatus – Lieferstatus unserer Kommentarantwort |
Die Aufzählung umfasst 0–13; Die restlichen Werte werden für Instagram-Integrationen nicht benötigt.
8,3 ChatStatus (0–4)
0 Neu, 1 Offen, 2 Wartend, 3 OnPause, 4 Geschlossen
8,4 MessageStatus (0–11)
| Code | Name |
|---|---|
| 0 | NEU |
| 1 | ERFOLGREICH |
| 2 | ABGELEHNT |
| 3 | LESEN |
| 4 | UNBEKANNT |
| 5 | VERARBEITUNG |
| 6 | GELIEFERT |
| 7 | BLOCKED_BY_USER |
| 8 | USER_NOT_FOUND |
Die Aufzählung umfasst 0–11. Die Werte 9, 10 und 11 sind in der API vorhanden, aber noch nicht dokumentiert –
Behandeln Sie sie als UNKNOWN.
8,5 MediaType (1–10)
1 Foto, 2 Datei, 3 Audio, 4 Video, 5 Aufkleber, 6 StickerAnimated,
7 StickerVideo, 8 Animation, 9 Stimme, 10 VideoNote
8.6 AuthorMessage – Autor in der Chat-API (0–4)
0 Operator, 1 Client, 2 Bot, 3 ViberAccount
Die Aufzählung umfasst 0–4; Wert 4 ist nicht dokumentiert. Die Rückrufe „Neue Nachricht“ verwenden die
entgegengesetzte Zuordnung – siehe §6.2.
8,7 ChatMessageType (0–2)
0 Text, 1 Foto, 2 Datei
8,8 Kommentar replyStatus
null eingehender Benutzerkommentar, "pending" unsere Antwort steht in der Warteschlange, "sent" zugestellt,
"failure" Lieferung fehlgeschlagen.
Offene Fragen
Drei Punkte, in denen die interne Spezifikation und der vom Code generierte Swagger nicht übereinstimmen. Eins Eine Anfrage mit einem echten Token erledigt alle; Schreiben Sie dem Kunden bis dahin defensiv.
| # | Frage | Spezifikation | Prahlerei | So überprüfen Sie |
|---|---|---|---|---|
| 1 | Auth-Header für /api/meta/* | X-Authorization-Key | nur Bearer deklariert | curl -i -H "X-Authorization-Key: <token>" ".../api/meta/posts?perPage=1" – erwarten Sie 200, nicht 401 |
| 2 | Zählerfeld in Meta-Antworten | totalCount | total | Dieselbe Anfrage – Lesen Sie den Root-JSON-Schlüssel |
| 3 | author.type Typ und reply Statuscode | "meta_user" / "owner", 202 mit Körper | int [0,1], 200 ohne Körper | curl -i .../api/meta/comments?perPage=1 plus eine Testantwort |
Vorläufige Anleitung:
- Zähler – lesen Sie
total ?? totalCount; author.type– akzeptiert sowohl eine Zeichenfolge als auch eine Ganzzahl (0↔meta_user,1↔owner, Zuordnung muss bestätigt werden);reply– Behandeln Sie jedes2xxals Erfolg, erfordern Sie keinen Text, übernehmen Sie den endgültigen Status aus demsource: 13-Rückruf.
Implementierungshinweise
- Auth unterscheidet sich je nach Endpunktgruppe –
/api/meta/*verwendetX-Authorization-Key, Chats und Operatoren verwendenBearer,restapiakzeptiert beides. - Paginierung wird auf zwei Arten geschrieben –
per_pageauf/api/chat/chats,perPageauf/api/meta/*und/api/chat/callback-events. multipart/form-data-Felder sind PascalCase mit Punktnotation (Media.File,Media.Type).- Nullfelder werden bei Rückrufen weggelassen – ein fehlender Schlüssel bedeutet
null. phoneist auf Instagram normalerweisenull. Identifizieren Sie den Kunden mitinstagramUser.id/metaUserIdund der Shop nachinstaAccount.id(der FilterwertentityId).Story.Idaus einem Rückruf kann direkt alsid/postIdan die Meta-API zurückgegeben werden.- Überprüfen Sie die
expiresAtdes Operator-JWT, bevor Sie ihn in einem Deeplink oder dem Widget verwenden.