Help Center Ενσωμάτωση API Meta & Instagram

Ενσωμάτωση 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 APIhttps://chatapi.smsbat.com
Swagger UI / OpenAPIhttps://chatapi.smsbat.com/index.html · …/swagger/v1/swagger.json
REST API (οργανισμοί, διευθύνσεις URL επανάκλησης)https://restapi.smsbat.com
REST API Swaggerhttps://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 χρησιμοποιεί και τα δύο.

Παράμετροι ερωτήματος, όλες προαιρετικές:

ΠαράμετροςΤύποςΠεριγραφή
sourceChatSourceΤο 7 περιορίζει τα αποτελέσματα στο Instagram
entityIdintΑναγνωριστικό επαγγελματικού λογαριασμού. Εφαρμόζεται μόνο μαζί με source
instagram_user_idintΑναγνωριστικό χρήστη Instagram στο ChatHub
facebook_user_idintΑναγνωριστικό χρήστη Facebook στο ChatHub
page / per_pageintΣελιδοποίηση, προεπιλογές 1 / 20
statusChatStatus[]Κατάσταση συνομιλίας, επαναλαμβανόμενη
searchstringΑναζήτηση σε ελεύθερο κείμενο (όνομα, τηλέφωνο, …)
organizationIdintΑναγνωριστικό οργανισμού
operatorIdint[]Φιλτράρισμα κατά εκχωρημένους τελεστές
datestring[]Δύο όρια: ?date=…&date=…
isChainboolΕπιστρέψτε τις συνομιλίες ως αλυσίδες, μεταφέροντας μηνύματα από προηγούμενες συνομιλίες
isUnread, starMark, isOperator, isAIAgentboolΠρόσθετα φίλτρα
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)
messSource7 για το 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
  }
}
ΠεδίοΤύποςΠεριγραφή
textMessagestring?Κείμενο μηνύματος. Μπορεί να είναι κενό όταν υπάρχει media
authorAuthorMessage?0 χειριστής, 1 πελάτης
isInternalbool?Το true σηματοδοτεί μια εσωτερική σημείωση που δεν παραδίδεται στον πελάτη
replyToMessageIdint?Αναγνωριστικό του μηνύματος στο οποίο απαντάται
appGuiduuid?GUID παραπομπής
mediaMediaDTO?{ 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 αγνοούνται σιωπηλά. Χρησιμοποιήστε τα ακριβή ονόματα παρακάτω.

Πεδίο φόρμαςΤύποςΠεριγραφή
TextMessagestringΚείμενο μηνύματος
Authorint0 χειριστής, 1 πελάτης
IsInternalboolΕσωτερική σημείωση
ReplyToMessageIdintΜήνυμα που απαντάται στο
AppGuiduuidGUID παραπομπής
Media.FilebinaryΤο ίδιο το αρχείο
Media.NamestringΌνομα αρχείου
Media.FormatstringΤύπος MIME (video/mp4, image/png, application/pdf)
Media.TypeMediaTypeΒλέπε §8.5
Media.DataBase64stringΕναλλακτική του Media.File
Media.ThumbnailstringΠλαίσιο προεπισκόπησης βίντεο Base64
Media.DurationdoubleΔιάρκεια βίντεο σε δευτερόλεπτα
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>
ΠαράμετροςΤύποςΑπαιτείταιΠεριγραφή
pageintόχιΣελίδα, προεπιλογή 1
perPageintόχιΣτοιχεία ανά σελίδα, προεπιλογή 20
idintόχιΦιλτράρισμα κατά εσωτερικό αναγνωριστικό ανάρτησης
platformstringόχιinstagram ή facebook
mediaTypestringόχι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
platformfacebook ή instagram
mediaTypepost, 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>
ΠαράμετροςΤύποςΑπαιτείταιΠεριγραφή
pageintόχιΣελίδα, προεπιλογή 1
perPageintόχιΣτοιχεία ανά σελίδα, προεπιλογή 20
postIdintόχιΦιλτράρισμα κατά αναγνωριστικό ταχυδρομείου
parentCommentIdintόχιΠαιδικά σχόλια (απαντήσεις) ενός δεδομένου σχολίου
platformstringόχι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Ημερομηνία δημιουργίας
platformfacebook ή instagram
replyStatusnull για ένα εισερχόμενο σχόλιο χρήστη. "pending" / "sent" / "failure" για την απάντησή μας
author.type"meta_user" εξωτερικός χρήστης, "owner" κάτοχος σελίδας
author.nameΌνομα συγγραφέα
author.metaUserIdΑναγνωριστικό χρήστη με εμβέλεια στο Meta. null για "owner"
postΗ ανάρτηση, ο κύλινδρος ή η ιστορία το σχόλιο ανήκει στο
post.mediaTypepost, 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
  }'
ΠεδίοΤύποςΠεριγραφή
urlstringΤο τελικό σας σημείο
sourceSendingSourceCallbackΤύπος συμβάντος, βλέπε §8.2
headerName / headerValuestringΕπικεφαλίδα αυθαίρετης ταυτότητας που επισυνάπτουμε στο αίτημα (προαιρετικό)
channelTypeChatSourceΚανάλι. 7 για το Instagram. Προαιρετικό
channelEntityIdintΈνας συγκεκριμένος επαγγελματικός λογαριασμός. Απαιτεί 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Αναγνωριστικά συνομιλίας και μηνυμάτων
Author0 χρήστης, 1 χειριστής
UsernameΕμφανιζόμενο όνομα ή λαβή Instagram / Facebook
UserIdΕσωτερικό αριθμητικό αναγνωριστικό χρήστη στο SMSBAT
MetaUserIdΑναγνωριστικό εύρους του συνομιλητή στο Meta. Σε ένα εξερχόμενο μήνυμα χειριστή αυτό εξακολουθεί να προσδιορίζει τον χρήστη Meta της συνομιλίας και όχι τον χειριστή
ShopIdΕσωτερικό αναγνωριστικό του επαγγελματικού λογαριασμού Instagram / Facebook
ShopNameΌνομα επαγγελματικού λογαριασμού όπως ελήφθη από τη Meta κατά τη στιγμή της σύνδεσης
MessageTextΚείμενο μηνύματος
MessageMediaURL πολυμέσων όταν το μήνυμα είναι πολυμέσα
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 Προτεινόμενος βρόχος

  1. Δημοσκόπηση GET /api/chat/callback-events σε πρόγραμμα.
  2. Επεξεργαστείτε τα συμβάντα στην υπηρεσία σας.
  3. Στείλτε την επεξεργασμένη λίστα event_guid στο /callback-events/processed.
  4. Επαναλάβετε.

8. Αριθμός αναφοράς

8.1 ChatSource — κανάλι (0–9)

ΚωδικόςΚανάλι
0Viber
1ViberBot
2TelegramBot
3Whatsapp
4Widget
5Ροζέτκα
6Facebook
7Instagram
8Prom
9Olx

8.2 SendingSourceCallback — τύπος συμβάντος επανάκλησης (0–13)

ΚωδικόςΕκδήλωση
3Chat — νέο μήνυμα συνομιλίας, συμπεριλαμβανομένων των απαντήσεων Story
5Η κατάσταση συνομιλίας άλλαξε
6Η κατάσταση του μηνύματος άλλαξε
7Δημιουργήθηκε νέα συνομιλία
8Ένδειξη πληκτρολόγησης
9Το μήνυμα ενημερώθηκε ή διαγράφηκε
11AnyChatMessage — οποιοδήποτε μήνυμα συνομιλίας
12MetaNewComment — νέο σχόλιο Instagram / Facebook
13MetaCommentStatus — κατάσταση παράδοσης της απάντησης σχολίου μας

Ο αριθμός εκτείνεται σε 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ΠΑΡΑΔΟΣΕ
7BLOCKED_BY_USER
8USER_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Πεδίο μετρητή στις απαντήσεις MetatotalCounttotalΊδιο αίτημα — διαβάστε το ριζικό κλειδί 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 πριν το χρησιμοποιήσετε σε έναν σύνδεσμο σε βάθος ή στο γραφικό στοιχείο.