API арқылы бір хабарлама жіберу: WhatsApp пен Telegram-дағы бір клиентке бір сұраныс, өз мәтіні мен тіркемесі, рассылкасыз. Кодтар мен еске салулар үшін.
Кешкі рассылкаға дейін күте алмайтын хабарламалар болады. Клиент тапсырысты төледі. Қабылдауға жазылды. Оператормен телефонда сөйлесіп тұрып, растау кодын сұрады.
Мұндай хабарлама бір адамға арналған, бірнеше минут қана өзекті және ешқашан қайталанбайды. Оған бола рассылка жинау оғаш: аудитория бір нөмірден тұрады, мәтін бір жағдайға жазылған, бәрі бір ғана хабарлама үшін.
Енді бұл үшін бөлек әдіс бар. Бір HTTP-сұраныс нақты адамға өз мәтіні мен тіркемесі бар бір хабарлама жібереді. Мұнда тек бір адамға жіберу туралы сөз болады, ал рассылка туралы рассылка API-і мақаласында жазылған.
Бұл қалай жұмыс істейді
Схемасы қарапайым: жүйеңіздегі оқиға → API-ге сұраныс → клиентке хабарлама.
Бүкіл әдіс бір POST /v1/message сұранысынан тұрады, онда үш нәрсе бар: қай аккаунттан, кімге және не жіберу керек. Кілт рассылкалардағымен бірдей, оны кабинеттің «API» бөлімінен аласыз:
curl -X POST https://api.wsender.io/v1/message \
-H "Authorization: key СІЗДІҢ_ТОКЕНІҢІЗ" \
-H "Content-Type: application/json" \
-d '{
"channelId": "АККАУНТ_ID",
"phone": "+7 701 123-45-67",
"message": { "kind": "text", "text": "84421 тапсырысыңыз төленді, ертең 12:00-де күтеміз." },
"idempotencyKey": "order-84421-paid"
}'
Жауапта өз идентификаторы мен статусы бар хабарлама келеді:
{
"id": "0f3c9a6e-4b12-4d8a-9f31-6c5a71e08d42",
"mid": null,
"status": "Queued",
"channelId": "АККАУНТ_ID",
"target": "Phone",
"phone": "77011234567",
"dialogId": null,
"errorReason": null,
"sendDate": null,
"failDate": null,
"wait": null,
"expiresAt": "2026-09-07T21:15:04Z",
"idempotencyKey": "order-84421-paid"
}
Аккаунт идентификаторы қосылған аккаунттар тізімінен, GET /v1/channel арқылы алынады, ал idempotencyKey сұранысқа өзіңіз беретін кілт, ол туралы төменде айтамыз. dialogId өрісі сервис осы адаммен хат алмасуды тапқанда толтырылады, кейін сол диалогқа жауапты осы өріс арқылы жіберуге болады. Егер бұл адамға бұрын жазған болсаңыз, өріс бірден, осы жауаптың өзінде толтырылады. mid жіберілгеннен кейін пайда болады: бұл хабарламаның хат алмасудағы идентификаторы. wait хабарламаны кезекте не ұстап тұрғанын түсіндіреді, ал expiresAt жіберілмеген хабарлама қай уақытқа дейін кезекте күтетінін көрсетеді: одан кейін ол Expired себебімен аяқталады.
Сұранысқа жауап бірден келеді, бірақ оның мағынасы «кезекке алынды». Хабарлама әлі жеткен жоқ. Оны сіздің қосылған аккаунтыңыз, мессенджер қосымшасында жұмыс істеп тұрған нақты аккаунт жібереді. Оған бірнеше секунд кетеді, ал бейтаныс нөмірге екі минутқа дейін: мессенджерлер нөмірлерді лезде тексергенді ұнатпайды. Боттан жылдамырақ: ол қосымшасыз, тікелей Bot API арқылы жібереді.
Бұл айырмашылық қоңырау қабылдайтын оператор үшін маңызды. Телефонда «қазір хабарлама жіберемін» деген дұрыс, «хабарлама келді» деуге әлі ерте.
Кімге жіберуге болады: WhatsApp, Telegram және боттар
Адресат бірнеше тәсілдің бірімен беріледі, нөмір мүлде керек пе, жоқ па, соны да осы шешеді:
- Телефон нөмірі кез келген әдеттегі түрде. Ең жиі кездесетін жағдай: нөмір клиент карточкасында бұрыннан бар.
- Аккаунт аты Telegram-да, егер ол сіздің аккаунтыңызға бұрынғы хат алмасудан таныс болса.
- Диалог API-дегі идентификаторы немесе мессенджердің өзіндегі диалог мекенжайы бойынша. Диалог сіздің аккаунтыңызға бұрыннан таныс болуы керек: бейтаныс мекенжаймен сұраныс қабылданбайды, сервис «кездейсоқ» жіберіп көрмейді.
Сұраныста бұл төрт өріс, олардың тек біреуі толтырылады. Сервис кімге жазғыңыз келгенін болжамайды:
"phone": "+7 701 123-45-67"
"username": "@aigerim_s"
"dialogId": "API_ДИАЛОГ_ID"
"dialogMid": "123456789"
Соңғы нұсқа мессенджердің өзіндегі диалог мекенжайы, мысалы, Telegram боттарындағы chat_id. Жүйеңіз мессенджер мекенжайларын бұрыннан сақтап жүрсе және біздің идентификаторларды өзінде жүргізгісі келмесе, бұл ыңғайлы.
Боттар үшін тек диалог арқылы адрестеу жұмыс істейді. Мұны платформа талап етеді: бот жазылушысында нөмір де, аккаунт аты да болмауы мүмкін, ал диалог әрқашан бар. Бот бәрібір бірінші болып жаза алмайды, бұл платформаның шектеуі.
API арқылы не жіберуге болады
Мәтін, сурет, бейне, аудио, құжат немесе контакт карточкасы. Мәтін тік жақшадағы нұсқаларды қолдайды: [Сәлеметсіз бе|Қайырлы күн] екеуінің біріне айналады, сонда хабарламалар бір қалыптан шыққандай көрінбейді.
Мұнда бір тұзақ бар, оны бірінші сұранысқа дейін білген жөн: тік жақшалар ішінде нұсқалар болмаса да спинтакс болып саналады. [Маңызды] кодыңыз 1234 мәтіні клиентке жақшасыз, Маңызды кодыңыз 1234 болып келеді. Үлгілеріңізде жақшалар безендіру үшін тұрса, оларды басқа таңбаға ауыстырыңыз.
Файл бөлек сұраныспен бір рет жүктеледі, әрі қарай кез келген санды хабарламада идентификатор арқылы беріледі. Жүз клиентке жіберілген бір прайс-парақ бір файлдың ғана орнын алады. Шектеулер қарапайым: бір файл 10 МБ-қа дейін, ал пайдаланылмаған файл бір тәулік сақталып, өзі жойылады.
Жүктеу файлы бар кәдімгі форма арқылы жасалады, жауаптағы басты өріс id:
curl -X POST https://api.wsender.io/v1/file \
-H "Authorization: key СІЗДІҢ_ТОКЕНІҢІЗ" \
-F "file=@price-2026.pdf"
Файл ашық сілтемеде тұрса, форманың орнына url өрісі бар POST /v1/file/url әдісін қолданыңыз: сервер оны өзі жүктеп алады. Әрі қарай идентификатор хабарламаға қойылады, ал түрі kind өрісімен беріледі: text, image, video, audio, file немесе contact. Суретте, бейнеде және құжатта caption сипаттамасы бар, кез келген тіркемеде алушы көретін fileName аты бар:
{
"channelId": "АККАУНТ_ID",
"phone": "+7 701 123-45-67",
"message": {
"kind": "file",
"fileId": "ЖҮКТЕЛГЕН_ФАЙЛ_ID",
"fileName": "Күзгі прайс-парақ",
"caption": "Сәлеметсіз бе! Айтқан прайсымызды жіберіп отырмыз. Бағалар ай соңына дейін жарамды."
},
"idempotencyKey": "price-request-1187"
}
Атын беру міндетті емес: ол болмаса жүктелген файлдың аты алынады, ал кеңейтімі кез келген жағдайда өзі қойылады, оны берудің қажеті жоқ. Сурет те осылай, "kind": "image" арқылы жіберіледі, ал контакт карточкасына файл керек емес: { "kind": "contact", "phone": "+7 701 000-00-00" }.
Жалғыз ерекшелік: контакт карточкасын боттан жіберуге болмайды, боттарда бұл хабарлама түрі қолдау таппайды. Мұндай сұраныс бірден қабылданбай қайтарылады, сондықтан жіберу кезінде үнсіз жоғалып кетпейді.
Хабарлама жеткенін қалай білуге болады
Сұранысқа жауапта «қабылданды» деп тұр. Әрі қарай немен аяқталғанын сервис вебхуктың үш оқиғасымен өзі хабарлайды:
message.sent. Хабарлама мессенджерге кетті.message.failed. Жіберу сәтсіз болды, оқиғада себебі көрсетіледі: алушы аккаунтты бұғаттаған, оған бірінші болып жазуға болмайды, жіберуші аккаунт ажыратылған. Немесе жіберу бірнеше минут бойы мессенджердің уақытша ақауына тіреліп, әрекеттер таусылды: мұндай хабарламаны қайта кезекке қоя салуға болады.message.notfound. Адресат мессенджерде жоқ: мұндай нөмір де, мұндай аккаунт та жоқ. Бұл қате емес, сондықтан оған бөлек оқиға бөлінген: түзейтін ештеңе жоқ, бірақ контактіні өз базаңызда белгілеп қойған жөн.
Оларға арнайы жазылу керек. Вебхук мекенжайын көрсетіп, оның сүзгісінде осы оқиғаларды тізіп шығыңыз: онсыз олар келмейді, тіпті вебхук рассылка оқиғаларына бапталып қойса да. Бұл әдейі жасалған. Күніне жүз хабарлама жіберетін адамға әр хабарлама бойынша ағын пайдалы, ал он мыңдаған алушыға рассылка жасайтын адам оны кездейсоқ алмауы керек.
Оқиғада не келеді: хабарлама идентификаторы, жіберуші аккаунт, сіз берген түрдегі адресат, статус, сәтсіздік себебі және күндер. Ең бастысы, өз кілтіңіз, сұраныспен бірге берген сол кілт. Ол бойынша өз жүйеңізден өтініміңізді табасыз да, біздің идентификаторларды мүлде сақтамайсыз.
Мысалы, алушы аккаунтыңызды бұғаттағанда сәтсіздік туралы оқиға былай көрінеді:
{
"id": "7d1e0b58-3a44-4f2c-9c81-15b0f7a9d6e3",
"type": "message.failed",
"date": "2026-09-07T09:15:42Z",
"payload": {
"message": {
"id": "0f3c9a6e-4b12-4d8a-9f31-6c5a71e08d42",
"channelId": "АККАУНТ_ID",
"phone": "77011234567",
"status": "Failed",
"errorReason": "Blocked",
"failDate": "2026-09-07T09:15:41Z",
"idempotencyKey": "order-84421-paid"
}
}
}
Себебі не істеу керегін көрсетеді. Blocked пен RestrictedSend бұл адамға осы аккаунттан жазуға болмайтынын білдіреді. ChannelDisconnected аккаунт ажыратылғанын білдіреді: оны қайта қосып, хабарламаны қайта жіберіңіз. Expired пен Unavailable берілген мерзімде жіберу мүмкін болмағанын білдіреді, хабарламаны жаңа кілтпен қайта қоюға болады.
Өңдеушіні жасағанда үш нәрсені ескеріңіз:
- Бір оқиға қайта келуі мүмкін. Мысалы, серверіңіз оны қабылдап қойған, бірақ жауап жолда жоғалған. Оқиғаның
idмәнін тексеріп, жүйеңіздегі әрекетті екінші рет орындамаңыз. - Өз болдырмау сұранысыңыз бойынша оқиға келмейді. Болдырмау сұранысын өзіңіз жібердіңіз және оған жауап алдыңыз: өз әрекетіңіз туралы екінші рет хабарлаудың қажеті жоқ.
- Нәтижені API арқылы тексеруге болады. Жіберудің уақытша ақауларын сервис өзі өңдейді. Хабарламаны берілген мерзімде жіберу мүмкін болмаса, ол
Failedстатусын алады, ал бапталған белсенді вебхук үшін себебі көрсетілгенmessage.failedоқиғасы жасалады. Қабылдаушы қолжетімсіз болса, оқиға жетпеуі мүмкін; ағымдағы нәтиженіGET /v1/message/{id}арқылы әрқашан алуға болады.
Вебхук жеткізу әрекеттері ұзарып отыратын үзіліспен қайталанады, бірақ әр оқиға бір тәуліктен артық сақталмайды. Бір тәулік бойы бірде-бір сәтті жеткізусіз қателер болса, вебхук тоқтатыла тұрады: жаңа оқиғалар жинақталмайды.
GET /v1/webhook жауабындағы health өрісін тексеріп, қабылдаушыны түзетіңіз де, POST /v1/webhook/resume шақырыңыз. Тексеру сәтті өтсе, сақталып қалған оқиғаларды жеткізу қайта басталады; үзіліс кезінде өткізіп алынған және мерзімі өткен оқиғалар қалпына келмейді.
Вебхук жасағыңыз келмесе, хабарлама статусын оның идентификаторы бойынша сұрауға болады. GET /v1/message/{id} жіберуге келген жауаппен бірдей құрылымды ағымдағы status мәнімен қайтарады: Queued, Sending, Sent, Failed немесе NotFound. Бірақ шынын айтсақ, сұраныстан кейін бірден статус «кезекте» болады, нәтижені бір сұраумен білу мүмкін емес, қайта-қайта сұрауға тура келеді. Әдісте «жіберілгенше күт» режимі әдейі жоқ: HTTP-сұранысыңызды бір минут ашық ұстағаннан гөрі оқиға жіберген дұрыс. Сондықтан мұнда вебхуктарды қосқан дұрыс.
Кіріс хабарламаға сол әдіспен жауап беру
Әдіс тек шығыс хабарламаларға арналмаған. Клиенттен жаңа хабарлама келгенін сервис message.received оқиғасымен хабарлайды: онда мәтін, жіберуші және диалог бар. Әрі қарай сол жіберу сұранысымен, адресат ретінде оқиғадағы диалогты көрсетіп, жауап бересіз. Осылайша бір әдістің негізінде екі жақты хат алмасу құрылады: өз инбоксыңыз, чат-бот немесе CRM-мен байланыс. Өз инбоксыңызды жасаудың қажеті болмаса, операторларға кабинеттен ашылатын Dialogs жеткілікті: онда сол хат алмасу көрінеді, ал API арқылы жіберілген жауаптарда «API» белгісі тұрады.
Жауапты нақты хабарламаға дәйексөз ретінде қоюға болады, әңгіменің ортасындағы сөзге мессенджердің өзінде жауап бергендегідей. Ол үшін сұраныста дәйексөзге алынатын хабарламаның идентификаторы беріледі: ол кіріс хабарлама туралы оқиғада да, API беретін диалог тарихында да бар.
Сол POST /v1/message, тек адресат енді диалог және replyToMid өрісі қосылған:
{
"channelId": "АККАУНТ_ID",
"dialogId": "ОҚИҒАДАҒЫ_ДИАЛОГ_ID",
"replyToMid": "КЛИЕНТ_ХАБАРЛАМАСЫНЫҢ_MID",
"message": { "kind": "text", "text": "Иә, бар. Кешке дейін сізге сақтап қояйын ба?" },
"idempotencyKey": "reply-5c2e-1"
}
Екі идентификатор да кіріс хабарлама туралы оқиғада келеді: диалог payload.dialog.id өрісінде, хабарламаның өзі payload.message.mid өрісінде. Дәйексөзге тек сол диалогтағы хабарламаны алуға болады. Басқа диалогтың хабарламасын сервис қабылдамайды: тексеру сұраныс сәтінде өтеді, сондықтан қате жіберу кезінде үнсіз жоғалып кетпейді. Мессенджер аккаунттарында да, Telegram боттарында да хабарламаның кез келген түрін дәйексөзге алуға болады.
Түпнұсқа сіздің сұранысыңыздан кейін жойылуы мүмкін. Онда мессенджер аккаунты хабарламаны дәйексөзсіз, кәдімгідей жібереді: безендіру үшін мәтінді жоғалтудың мәні жоқ. Боттар бұлай істей алмайды: хабарлама қатемен аяқталады, ал оның себебінен не істеу керегі түсінікті болады, яғни дәйексөзсіз қайта жіберу керек.
API сұранысын қайталау екінші хабарлама жасамайды
Транзакциялық хабарламалардың өз проблемасы бар: жауап келер сәтте желі үзіледі, кодыңыз сұранысты қайталайды, ал клиент екі бірдей хабарлама алады.
Сұраныспен бірге өзіңіздің бірегей кілтіңізді беріңіз. Сол кілтпен қайталанған сұраныс екінші хабарлама жібермейді, ол сол хабарламаның өзін ағымдағы статусымен қайтарады. Бұл идемпотенттіліктің стандартты механикасы, мұнда ол хабарламаның өз деңгейінде жұмыс істейді.
Хабарлама кезекте күтіп тұрғанда, оны бөлек сұраныспен болдырмауға болады: DELETE /v1/message/{id}. Жіберуші аккаунт оны жұмысқа алған сәттен бастап болдырмау кеш: 409 коды мен жауап денесінде ағымдағы статус келеді, ал нәтижені жіберудің өзі шешеді. Болдырмаудан кейін хабарлама Failed статусымен және Canceled себебімен оқылады, «болдырылды» деген бөлек статус жоқ.
API арқылы нені істеуге болмайды
Артық нәрсені жобаламас үшін шекаралар туралы ашық айтамыз.
- Тыйым салынған тақырыптарды тексеру мұнда да жұмыс істейді. Хабарлама сұраныс сәтінде тексеріледі, қабылданбаған хабарлама кезекке түспейді, жауапта себебі көрсетіледі. Тікелей жіберу модерацияны айналып өтуге мүмкіндік бермейді.
- Тарифтің күндік лимиті рассылкалармен ортақ. Тікелей хабарламалар оны рассылкалармен тең жұмсайды: жіберілген бір хабарлама тарифтің бір хабарламасы, әдістің өз лимиті жоқ. Бұл әдісте лимиттен асқаны үшін қосымша төлем қарастырылмаған: лимит таусылса, сұраныс қабылданбайды, ақылы жіберу болмайды. Қалдық жобаның кезегінде тұрған хабарламалар есебінен де азаяды.
- Бір аккаунттан жіберулер арасында бірнеше секунд үзіліс сақталады. Ол аккаунтты «циклдан» келетін ағыннан қорғайды: клиентпен тірі әңгімеге үзіліс кедергі келтірмейді, ал осы әдіс арқылы мың хабарлама таратуға тырыссаңыз, соған тірелесіз.
- Сервис өз нөмірлерін бермейді. Хабарлама сіздің қосылған аккаунтыңыздан немесе ботыңыздан кетеді: нөмірдің беделі сізде қалады, ал клиенттердің жауаптары мессенджердің әдеттегі қосымшасына келеді.
Әрі қарай не істеу керек
Әдіс кәдімгі тарифтерде жұмыс істейді және қазір тестілеуден өтіп жатыр: оның әзірге бөлек бағасы жоқ, хабарламалар тарифтің кәдімгі хабарламалары ретінде есептеледі. Тегін тарифте күніне 15 хабарлама бар, интеграцияны жинауға бұл жеткілікті.
Өз нөміріңізге бір сұраныстан бастаңыз: аккаунтты қосып, кабинеттің «API» бөлімінен кілт алыңыз да, өзіңізге сынақ хабарлама жіберіңіз. Әрі қарай оқиғаларға жазылуды қосып, API шақыруын жүйеңіздегі оқиға пайда болатын жерге қойыңыз.
Барлық әдістердің толық сипаттамасы және сұранысты браузерден бірден орындау мүмкіндігі API құжаттамасында бар, клиент генерациялауға арналған спецификация OpenAPI файлында.