Ενσωμάτωση API Meta & Instagram
Αναφορά για τη δημιουργία μιας εφαρμογής Instagram στην SMSBAT ChatHub Platform: έλεγχος ταυτότητας, Απευθείας συνομιλίες Instagram, σχόλια σε αναρτήσεις και Καρούλια, απαντήσεις στο Story, webhook και δημοσκοπήσεις.
Πηγές
Αυτή η σελίδα συγχωνεύει την εσωτερική προδιαγραφή Meta Comments API με το ζωντανό OpenAPI
ορισμοί στο https://chatapi.smsbat.com/swagger/v1/swagger.json και
https://restapi.smsbat.com/swagger/v1/swagger.json. Όπου οι δύο διαφωνούν, το
Η διαφορά καλείται ενσωματωμένα και παρατίθεται στην ενότητα Ανοιχτές ερωτήσεις.
1. Βασικές διευθύνσεις URL
| Σκοπός | URL |
|---|---|
| Chat API + Meta API | https://chatapi.smsbat.com |
| Swagger UI / OpenAPI | https://chatapi.smsbat.com/index.html · …/swagger/v1/swagger.json |
| REST API (οργανισμοί, διευθύνσεις URL επανάκλησης) | https://restapi.smsbat.com |
| REST API Swagger | https://restapi.smsbat.com/swagger/v1/swagger.json |
| Πίνακας web χειριστή | https://chat.smsbat.com |
2. Έλεγχος ταυτότητας
Το σχήμα auth εξαρτάται από την ομάδα τελικού σημείου. Η ανάμειξή τους είναι η πιο κοινή αιτία 401.
| Ομάδα | Κεφαλίδα |
|---|---|
chatapi.smsbat.com/api/meta/* (αναρτήσεις, σχόλια) | 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 · Βασικό Auth |
Το διακριτικό οργάνωσης για X-Authorization-Key εκδίδεται στον πίνακα κάτω από το Προφίλ.
Τα JWT της εταιρείας και του χειριστή προέρχονται από /api/company/get-token και /api/operator/get-token.
Ασυμφωνία
Το έγγραφο chatapi OpenAPI δηλώνει ένα ενιαίο σχήμα ασφαλείας — Bearer — και το εφαρμόζει
σε παγκόσμιο επίπεδο. Το X-Authorization-Key δεν δηλώνεται καθόλου εκεί, αν και το εσωτερικό Meta
Σχόλια Η προδιαγραφή API το ονομάζει /api/meta/*. Το πιο πιθανό είναι να το χειρίζεται
ενδιάμεσο λογισμικό που δεν αντικατοπτρίζεται στο Swagger. Επιβεβαιώστε εμπειρικά πριν την αποστολή.
2.1 Εταιρικό διακριτικό
POST https://chatapi.smsbat.com/api/company/get-token
Content-Type: application/json
{ "login": "company_login", "password": "company_password" }
Το 200 OK επιστρέφει μια γυμνή συμβολοσειρά.
2.2 Οργανισμοί
GET https://chatapi.smsbat.com/api/company/organization
Authorization: Bearer <company_token>
[ { "id": 24, "name": "My Instagram Store" } ]
2.3 Χειριστές σε έναν οργανισμό
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" }
}
]
Καταστάσεις χειριστή: 0 Ενεργός, 1 Ανενεργός, 2 Διαγραμμένος.
2.4 Προσθήκη / συγχρονισμός τελεστών
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 Χειριστής 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 επιστρέφει το JWT ως συμβολοσειρά.
2.6 Επικύρωση διακριτικού χειριστή
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
}
Όταν δεν είναι έγκυρο: { "isValid": false, "error": "Invalid token" }.
2.7 Ενσωματώστε τον πίνακα συνομιλίας χειριστή
<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. Σύνδεσμοι σε βάθος στον πίνακα συνομιλίας
Ένα εξωτερικό σύστημα (CRM, ERP, ιστότοπος) μπορεί να ανοίξει μια συγκεκριμένη συνομιλία
https://chat.smsbat.com/. Ο χειριστής είναι εξουσιοδοτημένος από ένα JWT που μεταβιβάζεται ως παράμετρος ερωτήματος.
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>
| Παράμετρος | Περιγραφή |
|---|---|
chat_raw_id | Αναγνωριστικό συνομιλίας |
phone | Αριθμός τηλεφώνου σε διεθνή μορφή |
from | Αναγνωριστικό επωνυμίας/επαγγελματικού λογαριασμού (bm_id) |
source | Πηγή συνομιλίας — 7 για το Instagram, βλ. §8.1 |
token | Έγκυρος χειριστής JWT που δεν έχει λήξει με πρόσβαση σε συνομιλίες |
Ένα μη έγκυρο JWT προσγειώνει τον επισκέπτη στην οθόνη σύνδεσης του πίνακα χειριστή.
4. Απευθείας συνομιλίες Instagram
4.1 Καταχωρίστε τις συνομιλίες
GET https://chatapi.smsbat.com/api/chat/chats?source=7&page=1&per_page=20
Authorization: Bearer <token>
Note
Η σελιδοποίηση εδώ είναι per_page (snake_case). Κάτω από το /api/meta/* και την ψηφοφορία
Το τελικό σημείο είναι perPage (camelCase). Αυτό δεν είναι τυπογραφικό λάθος — το API χρησιμοποιεί και τα δύο.
Παράμετροι ερωτήματος, όλες προαιρετικές:
| Παράμετρος | Τύπος | Περιγραφή |
|---|---|---|
source | ChatSource | Το 7 περιορίζει τα αποτελέσματα στο Instagram |
entityId | int | Αναγνωριστικό επαγγελματικού λογαριασμού. Εφαρμόζεται μόνο μαζί με source |
instagram_user_id | int | Αναγνωριστικό χρήστη Instagram στο ChatHub |
facebook_user_id | int | Αναγνωριστικό χρήστη Facebook στο ChatHub |
page / per_page | int | Σελιδοποίηση, προεπιλογές 1 / 20 |
status | ChatStatus[] | Κατάσταση συνομιλίας, επαναλαμβανόμενη |
search | string | Αναζήτηση σε ελεύθερο κείμενο (όνομα, τηλέφωνο, …) |
organizationId | int | Αναγνωριστικό οργανισμού |
operatorId | int[] | Φιλτράρισμα κατά εκχωρημένους τελεστές |
date | string[] | Δύο όρια: ?date=…&date=… |
isChain | bool | Επιστρέψτε τις συνομιλίες ως αλυσίδες, μεταφέροντας μηνύματα από προηγούμενες συνομιλίες |
isUnread, starMark, isOperator, isAIAgent | bool | Πρόσθετα φίλτρα |
phone, email, contactId, clientId, tagIds, rate, sortedBy | — | Άλλα φίλτρα |
Το 200 OK επιστρέφει 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": []
}
]
}
Τα πεδία που έχουν σημασία για μια εφαρμογή Instagram:
| Πεδίο | Σημασία |
|---|---|
instaAccount | Ο επαγγελματικός λογαριασμός Instagram (το κατάστημα). Το id είναι η τιμή φίλτρου entityId. name είναι το όνομα λογαριασμού από το Meta |
instagramUser | Ο πελάτης. name είναι η λαβή Instagram, id είναι η τιμή φίλτρου instagram_user_id |
metaUserId | Το αναγνωριστικό εύρους του πελάτη στην πλευρά του Meta (string) |
messSource | 7 για το Instagram |
phone | Συνήθως null για το Instagram — μην το χρησιμοποιείτε ως κλειδί |
Το ChatDTO φέρει επίσης 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 και taggedMessages.
4.2 Μηνύματα συνομιλίας
GET https://chatapi.smsbat.com/api/chat/chats/1867/messages?isChain=false
Authorization: Bearer <token>
Το 200 OK επιστρέφει έναν πίνακα 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 συμπληρώνεται όταν το μήνυμα σχετίζεται με μια ανάρτηση στο Instagram ή μια ιστορία — περάστε το
κατευθείαν πίσω ως id / postId στο Meta API. Το media είναι ένα ChatMediaDTO:
{ name, format, type, uri, raw, length, isUploaded }.
4.3 Αποστολή μηνύματος (JSON)
POST https://chatapi.smsbat.com/api/chat/1867/message
Authorization: Bearer <token>
Content-Type: application/json
Σώμα — 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
}
}
| Πεδίο | Τύπος | Περιγραφή |
|---|---|---|
textMessage | string? | Κείμενο μηνύματος. Μπορεί να είναι κενό όταν υπάρχει media |
author | AuthorMessage? | 0 χειριστής, 1 πελάτης |
isInternal | bool? | Το true σηματοδοτεί μια εσωτερική σημείωση που δεν παραδίδεται στον πελάτη |
replyToMessageId | int? | Αναγνωριστικό του μηνύματος στο οποίο απαντάται |
appGuid | uuid? | GUID παραπομπής |
media | MediaDTO? | { name, format, dataBase64, thumbnail, duration, type } |
200 OK → { "id": 9930, "messageStatus": 0 }
Ένα GUID παραπομπής μπορεί επίσης να περάσει στη διαδρομή:
POST /api/chat/{chatId}/{referralGuid}/message (ομοίως …/message/v1, …/message/v2).
4.4 Αποστολή αρχείου ή βίντεο (πολυμερής, v2)
POST https://chatapi.smsbat.com/api/chat/1867/message/v2
Authorization: Bearer <token>
Content-Type: multipart/form-data
Τα ονόματα πεδίων φόρμας είναι PascalCase με σημειογραφία κουκκίδας
Τα textMessage και media.file αγνοούνται σιωπηλά. Χρησιμοποιήστε τα ακριβή ονόματα παρακάτω.
| Πεδίο φόρμας | Τύπος | Περιγραφή |
|---|---|---|
TextMessage | string | Κείμενο μηνύματος |
Author | int | 0 χειριστής, 1 πελάτης |
IsInternal | bool | Εσωτερική σημείωση |
ReplyToMessageId | int | Μήνυμα που απαντάται στο |
AppGuid | uuid | GUID παραπομπής |
Media.File | binary | Το ίδιο το αρχείο |
Media.Name | string | Όνομα αρχείου |
Media.Format | string | Τύπος MIME (video/mp4, image/png, application/pdf) |
Media.Type | MediaType | Βλέπε §8.5 |
Media.DataBase64 | string | Εναλλακτική του Media.File |
Media.Thumbnail | string | Πλαίσιο προεπισκόπησης βίντεο Base64 |
Media.Duration | double | Διάρκεια βίντεο σε δευτερόλεπτα |
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 Αλλαγή κατάστασης συνομιλίας
PUT https://chatapi.smsbat.com/api/chat/status
Authorization: Bearer <token>
Content-Type: application/json
{ "id": 1867, "status": 4 }
Το 200 OK αντηχεί το ενημερωμένο αντικείμενο.
4.6 Ενημέρωση καταστάσεων μηνυμάτων
PUT https://chatapi.smsbat.com/api/chat/messages/status
Authorization: Bearer <token>
Content-Type: application/json
{ "status": 3, "messageIds": [9928, 9929] }
4.7 Διαγραφή συνομιλίας
DELETE https://chatapi.smsbat.com/api/chat/chats/1867
Authorization: Bearer <token>
5. Αναρτήσεις, Καρούλια και Ιστορίες
Βασική διαδρομή: https://chatapi.smsbat.com/api/meta
Autth: X-Authorization-Key: <organization token>
5.1 Καταχωρίστε τις αναρτήσεις, τους κυλίνδρους και τις ιστορίες
GET https://chatapi.smsbat.com/api/meta/posts?platform=instagram&mediaType=story&page=1&perPage=20
X-Authorization-Key: <token>
| Παράμετρος | Τύπος | Απαιτείται | Περιγραφή |
|---|---|---|---|
page | int | όχι | Σελίδα, προεπιλογή 1 |
perPage | int | όχι | Στοιχεία ανά σελίδα, προεπιλογή 20 |
id | int | όχι | Φιλτράρισμα κατά εσωτερικό αναγνωριστικό ανάρτησης |
platform | string | όχι | instagram ή facebook |
mediaType | string | όχι | post, reel ή story. Όλοι οι τύποι όταν παραλείπονται |
# 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"
}
}
]
}
Ασυμφωνία — όνομα πεδίου μετρητή
Το σχήμα Swagger MetaCommentPostListItemDtoPaginationDTO ορίζει το total. Το
έγγραφα εσωτερικών προδιαγραφών totalCount. Το Swagger δημιουργείται από τον κώδικα, έτσι
Το total είναι η πιο πιθανή αλήθεια. Αναλύστε το total ?? totalCount μέχρι να διευθετηθεί αυτό.
| Πεδίο | Περιγραφή |
|---|---|
id | Αναγνωριστικό εσωτερικής ανάρτησης |
metaId | Εξωτερική ανάρτηση / Καρούλι / Αναγνωριστικό ιστορίας στο Meta |
text | Λεζάντα ανάρτησης |
imageUrl | Διεύθυνση URL μέσου διακομιστή μεσολάβησης κλειδωμένη από το μη διαδοχικό MetaPost.Guid ή null |
platform | facebook ή instagram |
mediaType | post, reel ή story |
createdAt | Ημερομηνία δημιουργίας (ημερομηνία πλατφόρμας ή ημερομηνία βάσης δεδομένων) |
story | Παρουσιάστε μόνο για mediaType: "story" |
story.id | Αναγνωριστικό εσωτερικής ιστορίας. ίσο με post.id |
story.metaId | Εξωτερικό Αναγνωριστικό ιστορίας στο Meta |
story.url | Σταθερή διεύθυνση URL διακομιστή μεσολάβησης των αποθηκευμένων μέσων Story. null εάν δεν ήταν δυνατή η αποθήκευση των μέσων |
Το Post Media εξυπηρετείται από δύο διαδρομές: GET /api/meta/post/media/{id:int} για επιστροφή
συμβατότητα και GET /api/meta/post/media/{guid:guid}. Νέες αποκρίσεις API και επανακλήσεις
να δημιουργείτε πάντα τη φόρμα GUID.
5.2 Λίστα σχολίων
GET https://chatapi.smsbat.com/api/meta/comments?platform=instagram&postId=42&page=1&perPage=20
X-Authorization-Key: <token>
| Παράμετρος | Τύπος | Απαιτείται | Περιγραφή |
|---|---|---|---|
page | int | όχι | Σελίδα, προεπιλογή 1 |
perPage | int | όχι | Στοιχεία ανά σελίδα, προεπιλογή 20 |
postId | int | όχι | Φιλτράρισμα κατά αναγνωριστικό ταχυδρομείου |
parentCommentId | int | όχι | Παιδικά σχόλια (απαντήσεις) ενός δεδομένου σχολίου |
platform | string | όχι | facebook ή 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..."
}
}
]
}
| Πεδίο | Περιγραφή |
|---|---|
id | Αναγνωριστικό εσωτερικού σχολίου |
metaId | Εξωτερική ταυτότητα στο Meta. null για μια εκκρεμή απάντησή μας μέχρι να σταλεί |
text | Κείμενο σχολίου |
createdAt | Ημερομηνία δημιουργίας |
platform | facebook ή instagram |
replyStatus | null για ένα εισερχόμενο σχόλιο χρήστη. "pending" / "sent" / "failure" για την απάντησή μας |
author.type | "meta_user" εξωτερικός χρήστης, "owner" κάτοχος σελίδας |
author.name | Όνομα συγγραφέα |
author.metaUserId | Αναγνωριστικό χρήστη με εμβέλεια στο Meta. null για "owner" |
post | Η ανάρτηση, ο κύλινδρος ή η ιστορία το σχόλιο ανήκει στο |
post.mediaType | post, reel ή story |
post.story | Αναφορά ιστορίας { id, metaId, url }, Μόνο ιστορίες |
mediaUrl | Μέσα που επισυνάπτονται στο σχόλιο ή null |
replyTo | Σχόλιο γονέα { id, metaId, text }; null σε ανώτατο επίπεδο |
Ασυμφωνία — τύπος `author.type`
Οι εσωτερικές προδιαγραφές τεκμηριώνουν τις συμβολοσειρές "meta_user" / "owner". Τύποι Swagger
MetaCommentAuthorType ως ακέραιος με enum [0, 1]. A JsonStringEnumConverter
θα εξηγούσε το κενό, αλλά αυτό δεν έχει επιβεβαιωθεί έναντι μιας πραγματικής απάντησης. Γράψτε α
αναλυτής που δέχεται και τα δύο.
5.3 Απάντηση σε ένα σχόλιο
Ουρές απάντησης για παράδοση.
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"
Σώμα αιτήματος: { "text": "Reply text" }
Το 202 Accepted επιστρέφει το αντικείμενο σχολίου — ίδιο σχήμα με το GET /api/meta/comments — με
replyStatus: "pending" και metaId: null. Το αποτέλεσμα παράδοσης έρχεται αργότερα ως α
source: 13 επανάκληση (§6.4).
Ασυμφωνία — κωδικός απάντησης
Ο Swagger δηλώνει 200 χωρίς σώμα. η εσωτερική προδιαγραφή δηλώνει 202 Accepted
με σώμα το σχόλιο. Το χειριστήριο πιθανότατα στερείται ProducesResponseType
χαρακτηριστικό, αφήνοντας το Swagger στην προεπιλογή του. Αποδεχτείτε οποιοδήποτε 2xx και μην εξαρτάστε από ένα σώμα.
6. Webhooks
Το SMSBAT στέλνει POST αιτήματα με application/json στη διεύθυνση URL σας και αναμένει HTTP 200 πίσω.
Τα μηδενικά πεδία παραλείπονται εντελώς
Ένα πεδίο του οποίου η τιμή είναι null δεν είναι καθόλου σειριοποιημένο στο σώμα επανάκλησης. Για ένα
μήνυμα που δεν προήλθε από το Facebook ή το Instagram απλά δεν υπάρχει κλειδί MetaUserId.
Αντιμετωπίστε το “απών” και το null ως το ίδιο πράγμα.
6.1 Καταχωρίστε μια διεύθυνση 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
}'
| Πεδίο | Τύπος | Περιγραφή |
|---|---|---|
url | string | Το τελικό σας σημείο |
source | SendingSourceCallback | Τύπος συμβάντος, βλέπε §8.2 |
headerName / headerValue | string | Επικεφαλίδα αυθαίρετης ταυτότητας που επισυνάπτουμε στο αίτημα (προαιρετικό) |
channelType | ChatSource | Κανάλι. 7 για το Instagram. Προαιρετικό |
channelEntityId | int | Ένας συγκεκριμένος επαγγελματικός λογαριασμός. Απαιτεί channelType |
Χωρίς channelType η διεύθυνση URL λαμβάνει συμβάντα από κάθε κανάλι.
Tip
Η πλήρης κάλυψη σχολίων χρειάζεται δύο εγγραφές: source: 12 για νέα σχόλια και
source: 13 για καταστάσεις απαντήσεων. Για απαντήσεις Direct και Story προσθέστε source: 3
(και 11 αν θέλετε κάθε μήνυμα συνομιλίας).
Υπόλοιπες λειτουργίες:
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 επιστρέφει:
[
{
"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 Νέο μήνυμα και απάντηση στο Instagram Story (source: 3, 11)
Η απάντηση ενός χρήστη σε ένα Instagram Story φτάνει ως ένα συνηθισμένο μήνυμα σε αυτές τις επανακλήσεις,
με ένα επιπλέον μπλοκ ανώτατου επιπέδου Story:
{
"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"
}
}
| Πεδίο | Περιγραφή |
|---|---|
ChatId / MessageId | Αναγνωριστικά συνομιλίας και μηνυμάτων |
Author | 0 χρήστης, 1 χειριστής |
Username | Εμφανιζόμενο όνομα ή λαβή Instagram / Facebook |
UserId | Εσωτερικό αριθμητικό αναγνωριστικό χρήστη στο SMSBAT |
MetaUserId | Αναγνωριστικό εύρους του συνομιλητή στο Meta. Σε ένα εξερχόμενο μήνυμα χειριστή αυτό εξακολουθεί να προσδιορίζει τον χρήστη Meta της συνομιλίας και όχι τον χειριστή |
ShopId | Εσωτερικό αναγνωριστικό του επαγγελματικού λογαριασμού Instagram / Facebook |
ShopName | Όνομα επαγγελματικού λογαριασμού όπως ελήφθη από τη Meta κατά τη στιγμή της σύνδεσης |
MessageText | Κείμενο μηνύματος |
MessageMedia | URL πολυμέσων όταν το μήνυμα είναι πολυμέσα |
type_messenger | Πηγή, 7 για το Instagram |
operator_name | Όνομα χειριστή όταν Author = 1 |
Story | Παρουσίαση μόνο σε μια εισερχόμενη απάντηση ιστορίας |
Story.Id | Αναγνωριστικό εσωτερικής ιστορίας (MetaPost) — μπορεί να χρησιμοποιηθεί απευθείας ως id / postId στο Meta API |
Story.MetaId | Εξωτερικό Αναγνωριστικό ιστορίας στο Meta |
Story.Url | Σταθερή διεύθυνση URL διακομιστή μεσολάβησης του αποθηκευμένου μέσου Story. Απουσία όταν δεν ήταν δυνατή η αποθήκευση των μέσων — το μπλοκ Story και το μήνυμα εξακολουθούν να παραδίδονται |
`Author` αντιστρέφεται σε σχέση με το Chat API
Στο ChatMessageDTO.author, το 0 σημαίνει τελεστής και το 1 σημαίνει πελάτης. Σε αυτό το callback είναι
αντίστροφα: 0 είναι ο χρήστης, 1 είναι ο χειριστής. Μην κοινοποιείτε τη χαρτογράφηση.
6.3 Νέο σχόλιο (source: 12)
Ενεργοποιείται όταν ένας χρήστης Meta σχολιάζει μια ανάρτηση στο Facebook ή μια ανάρτηση στο Instagram / Reel.
Note
Instagram Οι απαντήσεις στο Story δεν παραδίδονται μέσω source: 12. Φτάνουν ως συνηθισμένες
εισερχόμενα μηνύματα στο source: 3 και/ή στο 11 με μπλοκ Story — δείτε την §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 Κατάσταση απάντησης σχολίου (source: 13)
Πυροδοτεί αφού προσπαθήσουμε να δώσουμε μια απάντηση, είτε πετύχει είτε αποτύχει.
{
"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 Κοινόχρηστα πεδία επανάκλησης σχολίων
Και οι δύο επανακλήσεις σχολίων μοιράζονται ένα σχήμα σώματος και διαφέρουν μόνο κατά type.
| Πεδίο | Περιγραφή |
|---|---|
type | "new_comment" ή "comment_status" |
platform | "facebook" ή "instagram" |
comment.id | Αναγνωριστικό εσωτερικού σχολίου |
comment.metaId | Εξωτερική ταυτότητα στο Meta. null για μια εκκρεμή απάντηση πριν αποσταλεί |
comment.parentCommentId | Αναγνωριστικό γονικού σχολίου. Απών για σχόλιο ανώτατου επιπέδου |
comment.parentMetaId | Εξωτερικό αναγνωριστικό γονικού σχολίου. Απών στο ανώτατο επίπεδο |
comment.parentCommentText | Κείμενο σχολίου γονέα. Απών στο ανώτατο επίπεδο |
comment.text | Κείμενο σχολίου |
comment.createdAt | Ημερομηνία δημιουργίας |
comment.updatedAt | Τελευταία ενημέρωση. Απουσία αν το σχόλιο δεν υποβλήθηκε ποτέ σε επεξεργασία |
comment.replyStatus | "pending" / "sent" / "failure". Απών για ένα εισερχόμενο σχόλιο χρήστη |
comment.author.type | "meta_user" ή "owner" |
comment.author.name | Όνομα συγγραφέα |
comment.author.metaUserId | Αναγνωριστικό συγγραφέα με εμβέλεια στο Meta. Απών για "owner" |
comment.mediaUrl | Μέσα σχολιασμού. Απουσιάζει όταν δεν υπάρχει |
post.id | Αναγνωριστικό εσωτερικής ανάρτησης |
post.metaId | Εξωτερική ανάρτηση / Καρούλι / Αναγνωριστικό ιστορίας στο Meta |
post.text | Κείμενο ανάρτησης |
post.imageUrl | Διεύθυνση URL εικόνας ανάρτησης ή null |
post.createdAt | Ημερομηνία μετά τη δημιουργία |
post.mediaType | Στις επιστροφές σχολίων, μόνο post ή reel |
6.6 Νέα συνομιλία (source: 7)
{ "ChatId": 12345, "Phone": "+380501234567", "chat.Source": 7 }
6.7 Αλλαγές κατάστασης μηνύματος και συνομιλίας (source: 6 / 5)
{ "name": "changed_message_status", "id": 9928, "status": 6 }
{ "name": "changed_chat_status", "id": 1867, "status": 4 }
6.8 Το μήνυμα επεξεργάστηκε ή διαγράφηκε (source: 9)
{ "messageId": 9930, "text": "Updated message text" }
{ "messageId": 9931, "delete": true }
6.9 Ένδειξη πληκτρολόγησης (source: 8)
{ "chat_id": 1867, "event": "start_typing", "operator_name": "Iryna" }
{ "chat_id": 1867, "event": "end_typing" }
7. Δημοσκόπηση εκδήλωσης
Για περιβάλλοντα που δεν μπορούν να δεχτούν εισερχόμενο HTTP.
7.1 Λήψη συμβάντων
GET https://chatapi.smsbat.com/api/chat/callback-events?page=1&perPage=20
Authorization: Bearer <token>
| Παράμετρος | Περιγραφή |
|---|---|
organizationId | Προαιρετικός. Λαμβάνεται από το διακριτικό όταν παραλείπεται |
page / perPage | Σελιδοποίηση, προεπιλογές 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"
}
]
}
Κάθε συμβάν φέρει event_guid, timestamp, organization_id και callback_type — ένα
συμβολοσειρά που ταιριάζει με τις τιμές source στην §8.2. Τα υπόλοιπα πεδία ταιριάζουν με τα αντίστοιχα
webhook στην §6.
7.2 Αναγνώριση επεξεργασμένων συμβάντων
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 }
Τα συμβάντα που έχουν ήδη αφαιρεθεί απλά δεν υπολογίζονται στο deleted. Η παραγγελία και οι επαναλήψεις είναι δικές σας
ευθύνη της πλευράς.
7.3 Προτεινόμενος βρόχος
- Δημοσκόπηση
GET /api/chat/callback-eventsσε πρόγραμμα. - Επεξεργαστείτε τα συμβάντα στην υπηρεσία σας.
- Στείλτε την επεξεργασμένη λίστα
event_guidστο/callback-events/processed. - Επαναλάβετε.
8. Αριθμός αναφοράς
8.1 ChatSource — κανάλι (0–9)
| Κωδικός | Κανάλι |
|---|---|
| 0 | Viber |
| 1 | ViberBot |
| 2 | TelegramBot |
| 3 | |
| 4 | Widget |
| 5 | Ροζέτκα |
| 6 | |
| 7 | |
| 8 | Prom |
| 9 | Olx |
8.2 SendingSourceCallback — τύπος συμβάντος επανάκλησης (0–13)
| Κωδικός | Εκδήλωση |
|---|---|
| 3 | Chat — νέο μήνυμα συνομιλίας, συμπεριλαμβανομένων των απαντήσεων Story |
| 5 | Η κατάσταση συνομιλίας άλλαξε |
| 6 | Η κατάσταση του μηνύματος άλλαξε |
| 7 | Δημιουργήθηκε νέα συνομιλία |
| 8 | Ένδειξη πληκτρολόγησης |
| 9 | Το μήνυμα ενημερώθηκε ή διαγράφηκε |
| 11 | AnyChatMessage — οποιοδήποτε μήνυμα συνομιλίας |
| 12 | MetaNewComment — νέο σχόλιο Instagram / Facebook |
| 13 | MetaCommentStatus — κατάσταση παράδοσης της απάντησης σχολίου μας |
Ο αριθμός εκτείνεται σε 0–13. οι υπόλοιπες τιμές δεν χρειάζονται για ενσωματώσεις στο Instagram.
8,3 ChatStatus (0–4)
0 Νέο, 1 Ανοιχτό, 2 Αναμονή, 3 Σε Παύση, 4 Κλειστό
8,4 MessageStatus (0–11)
| Κωδικός | Όνομα |
|---|---|
| 0 | ΝΕΟ |
| 1 | ΕΠΙΤΥΧΙΑ |
| 2 | ΑΠΟΡΡΙΠΘΗΚΕ |
| 3 | ΔΙΑΒΑΣΤΕ |
| 4 | ΑΓΝΩΣΤΟΣ |
| 5 | ΕΠΕΞΕΡΓΑΣΙΑ |
| 6 | ΠΑΡΑΔΟΣΕ |
| 7 | BLOCKED_BY_USER |
| 8 | USER_NOT_FOUND |
Ο αριθμός εκτείνεται σε 0–11. Οι τιμές 9, 10 και 11 υπάρχουν στο API αλλά δεν είναι ακόμη τεκμηριωμένες —
Αντιμετωπίστε τους ως UNKNOWN.
8,5 MediaType (1–10)
1 Φωτογραφία, 2 Αρχείο, 3 Ήχος, 4 Βίντεο, 5 Αυτοκόλλητο, 6 StickerAnimated,
7 StickerVideo, 8 Animation, 9 Voice, 10 VideoNote
8.6 AuthorMessage — συγγραφέας στο Chat API (0–4)
0 Operator, 1 Client, 2 Bot, 3 ViberAccount
Ο αριθμός εκτείνεται σε 0–4. Η τιμή 4 δεν είναι τεκμηριωμένη. Οι επανακλήσεις “νέου μηνύματος” χρησιμοποιούν το
αντίθετη χαρτογράφηση — βλ. §6.2.
8,7 ChatMessageType (0–2)
0 Κείμενο, 1 Φωτογραφία, 2 Αρχείο
8,8 Σχόλιο replyStatus
null εισερχόμενο σχόλιο χρήστη, "pending" η απάντησή μας βρίσκεται στην ουρά, "sent" παραδόθηκε,
Η παράδοση "failure" απέτυχε.
Ανοιχτές ερωτήσεις
Τρία σημεία όπου η εσωτερική προδιαγραφή και το Swagger που δημιουργείται από κώδικα διαφωνούν. Ένα Το αίτημα με ένα πραγματικό διακριτικό τακτοποιεί όλα αυτά. μέχρι τότε, γράψτε τον πελάτη αμυντικά.
| # | Ερώτηση | Προδιαγραφές | Swagger | Πώς να ελέγξετε |
|---|---|---|---|---|
| 1 | Κεφαλίδα ταυτότητας για /api/meta/* | X-Authorization-Key | μόνο Bearer δηλώθηκε | curl -i -H "X-Authorization-Key: <token>" ".../api/meta/posts?perPage=1" — αναμένετε 200, όχι 401 |
| 2 | Πεδίο μετρητή στις απαντήσεις Meta | totalCount | total | Ίδιο αίτημα — διαβάστε το ριζικό κλειδί JSON |
| 3 | Τύπος author.type και κωδικός κατάστασης reply | "meta_user" / "owner", 202 με σώμα | int [0,1], 200 χωρίς σώμα | curl -i .../api/meta/comments?perPage=1 συν μια δοκιμαστική απάντηση |
Ενδιάμεση καθοδήγηση:
- μετρητής — διαβάστε
total ?? totalCount; author.type— αποδεχτείτε και μια συμβολοσειρά και έναν ακέραιο (0↔meta_user,1↔owner, αντιστοίχιση προς επιβεβαίωση).reply— αντιμετωπίστε οποιοδήποτε2xxως επιτυχία, δεν απαιτείται σώμα, λάβετε την τελική κατάσταση από την επιστροφή κλήσηςsource: 13.
Σημειώσεις υλοποίησης
- Το Auth διαφέρει ανά ομάδα τελικού σημείου —
/api/meta/*χρησιμοποιείX-Authorization-Key, συζητήσεις και Οι χειριστές χρησιμοποιούνBearer,restapiαποδέχεται είτε. - Η σελιδοποίηση γράφεται με δύο τρόπους —
per_pageστο/api/chat/chats,perPageστο/api/meta/*και/api/chat/callback-events. - Τα πεδία
multipart/form-dataείναι PascalCase με σημειογραφία (Media.File,Media.Type). - Τα μηδενικά πεδία παραλείπονται από τις επανακλήσεις — ένα κλειδί που απουσιάζει σημαίνει
null. - Το
phoneείναι συνήθωςnullστο Instagram. Προσδιορίστε τον πελάτη μεinstagramUser.id/metaUserIdκαι το κατάστημα κατάinstaAccount.id(η τιμή φίλτρουentityId). - Το
Story.Idαπό μια επιστροφή κλήσης μπορεί να μεταδοθεί κατευθείαν ωςid/postIdστο Meta API. - Ελέγξτε το
expiresAtτου χειριστή JWT πριν το χρησιμοποιήσετε σε έναν σύνδεσμο σε βάθος ή στο γραφικό στοιχείο.