API

Bitimlar uchun ochiq API va CRM vebxuklari

Yangilandi 18-oktabr, 202613 daqiqa o'qish

Chato bitimlarini o‘z dasturingizdan boshqarish mumkin. Masalan, sayt ariza bo‘yicha bitim yaratadi, 1C to‘lovdan keyin uni yopadi, ombor menejerga vazifa qo‘yadi. Teskari yo‘nalishda Chato dasturingizga CRMda nima bo‘lganini xabar qiladi: bitim ko‘chirildi, yutildi yoki mas’ul o‘zgardi.

Hammasi kabinetda sozlanadi: CRM → ⋯ → CRM sozlamalari → API va vebxuklar. Bu yorliqni administrator va egasi ko‘radi. U yerda Swagger dagi barcha so‘rovlar ma’lumotnomasiga havola ham bor: https://chato.kz/api/v1/public/docs. OpenAPI formatidagi tavsif https://chato.kz/api/v1/public/openapi.json manzilida.

API kaliti

Yangi kalit ni bosing, unga nom bering («Sayt», «1C») va huquqlarni belgilang:

Huquq Nimaga ruxsat beradi
deals:read bitimlar va ularning izohlarini o‘qish
deals:write bitimlarni yaratish, o‘zgartirish, ko‘chirish, yopish, o‘chirish va tiklash, izoh yozish
contacts:read / contacts:write kontaktlarni qidirish va o‘qish / kontaktlarni yaratish va o‘zgartirish
tasks:read / tasks:write vazifalarni o‘qish / vazifalarni qo‘yish va bajarish
pipelines:read voronkalar, bosqichlar, qo‘shimcha maydonlar va rad etish sabablarini o‘qish
users:read xodimlar ro‘yxatini o‘qish (responsibleUserId uchun)
messages:send mijozlarga yozish

Kalit yaratish ni bosing. Kalit bir marta ko‘rsatiladi, shuning uchun uni darhol nusxalab oling. Chato faqat kalitning izini saqlaydi va uni qayta ko‘rsata olmaydi. Kalitlar ro‘yxatida kalitni kim chiqargani va oxirgi marta qachon ishlatilgani ko‘rinadi. Bekor qilish bosilgandan keyin kalit darhol ishlashdan to‘xtaydi va dastur 401 oladi.

Kalitni parol kabi saqlang: serverda, muhit o‘zgaruvchilarida. Uni tashrif buyuruvchi brauzeri ko‘radigan sayt kodiga hech qachon joylamang.

Dastur kalit orqali qilgan hamma narsa bitim tarixiga kalitni chiqargan odam nomidan «API orqali» belgisi bilan yoziladi. Kalit o‘z muallifidan ortiq narsa qila olmaydi: agar voronka xodimdan yashirilgan bo‘lsa, uning kalitidan ham yashirilgan. Agar kalit muallifi kompaniyadan ketsa, kalit ishlamay qoladi (401). Bosqich avtomatlashtirishlari, bildirishnomalar va hamkasblar doskasining jonli yangilanishi kabinetdagi ish kabi ishlaydi.

So‘rovlarni qanday yuborish kerak

https://chato.kz/api/v1/public
Authorization: Bearer chato_sk_...
Content-Type: application/json

Kalitni X-Api-Key sarlavhasida ham berish mumkin. Muvaffaqiyatli javob har doim data maydonida bo‘ladi. Kalitni GET /me so‘rovi bilan tekshirish mumkin: u kompaniyani, kalit id sini va uning huquqlarini qaytaradi.

{ "data": { "workspaceId": "cmulak1n90001295a8kf4ruhe", "keyId": "cmv2sreij000j293db87lukst", "scopes": ["deals:read", "deals:write"] } }
  • Cheklov: bitta kalitga daqiqasiga 120 so‘rov. Har bir kalitning o‘z hisoblagichi bor, shuning uchun bir dastur boshqasining cheklovini yemaydi. Har bir javobda X-RateLimit-Limit, X-RateLimit-Remaining va X-RateLimit-Reset (hisoblagich necha soniyadan keyin nolga tushishi) sarlavhalari bor. Cheklovdan oshsa, Retry-After sarlavhasi bilan 429 keladi: necha soniyadan keyin takrorlash kerakligi. Agar bitta IP-manzildan bir daqiqada noto‘g‘ri kalit bilan 30 ta so‘rov kelsa, shu manzildan keyingi so‘rovlar daqiqa oxirigacha 429 oladi.
  • Dublsiz takrorlash: POST ga Idempotency-Key sarlavhasini qo‘shing. 255 belgigacha istalgan satr mos keladi, masalan tizimingizdagi ariza id si. Bir sutka ichida xuddi shu kalit bilan takrorlash birinchi javobni Idempotent-Replayed: true sarlavhasi bilan qaytaradi va ikkinchi bitim yaratmaydi. Birinchi so‘rov hali bajarilayotgan bo‘lsa, takror 409 IDEMPOTENCY_IN_PROGRESS oladi. Xuddi shu kalit boshqa so‘rov tanasi bilan 422 IDEMPOTENCY_KEY_REUSED beradi. Agar birinchi so‘rov xato bilan tugagan bo‘lsa, takror qaytadan bajariladi.

Xatolar

Xato har doim bir ko‘rinishda keladi:

{
  "error": {
    "code": "REQUIRED_FIELDS",
    "message": "Заполните поля, чтобы перенести в «Договор подписан»",
    "textCode": "REQUIRED_FIELDS",
    "params": { "stage": "Договор подписан" },
    "details": {
      "stageId": "dmo_p1_s5",
      "stageName": "Договор подписан",
      "missing": [{ "id": "dmo_f4", "key": "data_dogovora", "label": "Дата договора", "type": "DATE", "options": [] }]
    }
  },
  "statusCode": 422
}

message har doim rus tilida. Xatoni boshqa tilda ko‘rsatish uchun uni code yoki textCode bo‘yicha tarjima qiling.

Kod Qachon
400 VALIDATION_FAILED ma’lumotlar noto‘g‘ri; xatolar ro‘yxati details.validation da
400 CONTACT_IDENTITY_REQUIRED kontaktni qidirish yoki yaratish uchun na telefon, na e-mail bor
400 PHONE_TOO_SHORT telefonda 10 tadan kam raqam
401 UNAUTHORIZED kalit yo‘q, noto‘g‘ri yoki bekor qilingan
403 FORBIDDEN_SCOPE kalitda kerakli huquq yo‘q (qaysi biri — params.scope da)
404 DEAL_NOT_FOUND va shunga o‘xshashlar kompaniyangizda bunday obyekt yo‘q (begona id lar har doim 404 beradi)
404 CRM_DISABLED kompaniyada CRM yoqilmagan
409 IDEMPOTENCY_IN_PROGRESS xuddi shu Idempotency-Key bilan so‘rov hali bajarilmoqda
422 REQUIRED_FIELDS bosqich uchun majburiy maydonlar kerak; qaysilari — details.missing da
422 LOSS_REASON_REQUIRED sababsiz «Rad etilgan» ga ko‘chirish, voronka esa sababni talab qiladi
422 IDEMPOTENCY_KEY_REUSED xuddi shu Idempotency-Key boshqa so‘rov tanasi bilan keldi
429 RATE_LIMITED cheklov oshib ketdi; Retry-After ni qarang

Ma’lumotnomalar

curl https://chato.kz/api/v1/public/pipelines -H "Authorization: Bearer $CHATO_KEY"

Bu so‘rov bosqichlari bilan voronkalarni qaytaradi:

{
  "data": [
    {
      "id": "cmulbined000f29fg1na5uhw2",
      "name": "Sotuvlar",
      "position": 0,
      "lossReasonRequired": true,
      "stages": [
        { "id": "cmulbinee000g29fg7o2ep8ev", "name": "Yangi ariza", "color": "#3B82F6", "position": 0, "kind": "OPEN" },
        { "id": "cmulbinee000j29fgem0qk8ti", "name": "Muvaffaqiyatli", "color": "#10B981", "position": 3, "kind": "WON" },
        { "id": "cmulbinee000k29fgkfdfjzdk", "name": "Rad etilgan", "color": "#EF4444", "position": 4, "kind": "LOST" }
      ]
    }
  ]
}

kind — bosqich turi: OPEN — ishchi, WON — «Muvaffaqiyatli», LOST — «Rad etilgan». lossReasonRequired: true — «Rad etilgan» uchun sabab kerak.

Boshqa ma’lumotnomalar:

  • GET /deal-fields — qo‘shimcha maydonlar: key (maydon kodi, qiymatlar shu bo‘yicha yoziladi), label, type, options ({id, label} variantlari), pipelineIds (maydon qaysi voronkalarda bor; bo‘sh ro‘yxat — hammasida), requiredStageIds (maydon qaysi bosqichlarda majburiy);
  • GET /loss-reasons — rad etish sabablari {id, name};
  • GET /users — xodimlar: id, name, email, role (users:read huquqi kerak).

Bitimlar

Yaratish

curl -X POST https://chato.kz/api/v1/public/deals \
  -H "Authorization: Bearer $CHATO_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: site-order-10542' \
  -d '{
    "pipelineId": "PIPELINE_ID",
    "title": "Saytdan ariza",
    "amount": 150000,
    "contact": { "name": "Aigerim", "phone": "+7 701 555 11 22", "email": "aigerim@example.com" },
    "tags": ["sayt"],
    "fields": { "gorod": "almaty", "obem": 40 }
  }'

201 javobi:

{
  "data": {
    "id": "cmv2srw0l000l293dy0wyl3kk",
    "title": "Saytdan ariza",
    "amount": 150000,
    "currency": "KZT",
    "status": "open",
    "pipeline": { "id": "cmulbined000f29fg1na5uhw2", "name": "Sotuvlar" },
    "stage": { "id": "cmulbinee000g29fg7o2ep8ev", "name": "Yangi ariza", "kind": "OPEN" },
    "contact": { "id": "cmulm6bkt0007299yv6tep4fx", "name": "Aigerim", "phone": "77015551122", "email": "aigerim@example.com", "createdAt": "2026-09-28T19:01:56.381Z" },
    "responsible": { "id": "cmulak1n60000295aiftvjchb", "name": "Askhat", "email": "askhat@example.com" },
    "tags": ["sayt"],
    "fields": { "gorod": "almaty", "obem": 40 },
    "source": "api",
    "utm": null,
    "description": null,
    "lossReason": null,
    "lossComment": null,
    "conversationId": null,
    "channelId": null,
    "createdBy": { "id": "cmulak1n60000295aiftvjchb", "name": "Askhat", "email": "askhat@example.com" },
    "createdAt": "2026-10-10T19:38:45.333Z",
    "updatedAt": "2026-10-10T19:38:45.333Z",
    "closedAt": null,
    "deletedAt": null,
    "contactCreated": true
  }
}

Barcha so‘rovlarning javoblarida bitim xuddi shunday ko‘rinadi. status — open, won, lost yoki unsorted (saralanmagan).

Kontakt contactId yoki contact maydoni bilan beriladi. contact bo‘yicha Chato avval odamni qidiradi: telefon bo‘yicha (oxirgi 10 raqam, format istalgan), keyin e-mail bo‘yicha (registrga qaramay). Topmasa, yangisini yaratadi. Topilgan kontaktda faqat bo‘sh maydonlar to‘ldiriladi. Javobdagi contactCreated yangi kontakt yaratilgan-yaratilmaganini ko‘rsatadi.

Agar pipelineId ko‘rsatilmasa, bitim birinchi voronkaga tushadi. Agar stageId ko‘rsatilmasa, bitim voronkaning birinchi bosqichiga tushadi. title bo‘lmasa, nomi «Сделка: » bo‘ladi. Standart mas’ul — kalit muallifi; "responsibleUserId": null — mas’ulsiz. description ni ham berish mumkin. Bitim manbai — api.

Qo‘shimcha maydonlar /deal-fields dagi kodlar bo‘yicha fields obyekti bilan beriladi. Ro‘yxat uchun variant id sini bering, ko‘p tanlov uchun — id lar massivini, sana uchun — 2026-09-28 ko‘rinishidagi satrni, belgi uchun — true yoki false. Noto‘g‘ri qiymat maydon nomi bilan 400 qaytaradi. 20 tagacha teg berish mumkin, har biri 40 belgigacha.

O‘zgartirish

curl -X PATCH https://chato.kz/api/v1/public/deals/DEAL_ID \
  -H "Authorization: Bearer $CHATO_KEY" -H 'Content-Type: application/json' \
  -d '{"amount": 180000, "tags": ["sayt", "vip"], "fields": {"oplata": "invoice"}}'

Faqat yuborilgani o‘zgaradi: title, amount, responsibleUserId, description, tags, fields, source. tags avvalgi ro‘yxatni almashtiradi. Maydondagi null uni tozalaydi. stageId ni ham berish mumkin (lossReasonId, lossComment bilan): unda bitim /move dagi qoidalar bo‘yicha bosqichga o‘tadi.

Ko‘chirish, yopish

# bosqichga — doskadagi kabi qoidalar bilan
curl -X POST https://chato.kz/api/v1/public/deals/DEAL_ID/move \
  -H "Authorization: Bearer $CHATO_KEY" -H 'Content-Type: application/json' \
  -d '{"stageId": "STAGE_ID", "fields": {"data_dogovora": "2026-09-28"}}'

# muvaffaqiyatli
curl -X POST https://chato.kz/api/v1/public/deals/DEAL_ID/close \
  -H "Authorization: Bearer $CHATO_KEY" -H 'Content-Type: application/json' \
  -d '{"result": "won"}'

# rad etish bilan — /loss-reasons dagi sabab bilan
curl -X POST https://chato.kz/api/v1/public/deals/DEAL_ID/close \
  -H "Authorization: Bearer $CHATO_KEY" -H 'Content-Type: application/json' \
  -d '{"result": "lost", "lossReasonId": "REASON_ID", "lossComment": "boshqasini tanlashdi"}'

move, close va restore bitimni 200 kodi bilan qaytaradi. Agar bosqichda majburiy maydonlar bo‘lsa-yu, bitimda ular bo‘sh bo‘lsa, maydonlar ro‘yxati bilan 422 REQUIRED_FIELDS keladi. Ularni fields ga qo‘shib, so‘rovni takrorlang. move orqali «Rad etilgan» ga ko‘chirish ham lossReasonId va lossComment ni qabul qiladi. close bitimni uning voronkasidagi birinchi «Muvaffaqiyatli» yoki «Rad etilgan» bosqichiga ko‘chiradi. Shu turdagi boshqa bosqich kerak bo‘lsa, uning stageId sini bering.

Topish, o‘qish, o‘chirish

curl 'https://chato.kz/api/v1/public/deals?pipelineId=PIPELINE_ID&status=open&limit=50' \
  -H "Authorization: Bearer $CHATO_KEY"

Javob: {"data": {"items": [...], "nextCursor": "..."}}. Yangi bitimlar birinchi keladi. limit — 1 dan 100 gacha, standart 50. Keyingi sahifa — xuddi shu so‘rov &cursor=<nextCursor> bilan. nextCursor: null — boshqa sahifa yo‘q.

Filtrlar:

  • pipelineId, stageId;
  • status: open, won, lost, closed (yutilgan va yutqazilganlar), unsorted yoki all (standart; o‘chirilganlardan tashqari hammasi);
  • responsibleUserId (yoki none — mas’ulsiz), contactId, tag;
  • search — nomi, mijoz ismi yoki raqami bo‘yicha;
  • updatedSince va createdSince — ISO sana. Sinxronlash uchun qulay: «oxirgi martadan beri nima o‘zgardi».

Boshqa so‘rovlar:

  • GET /deals/DEAL_ID — bitta bitim;
  • DELETE /deals/DEAL_ID — 30 kunga savatga (204 javobi, tanasiz); POST /deals/DEAL_ID/restore — savatdan qaytarish.

Izohlar va vazifalar

curl -X POST https://chato.kz/api/v1/public/deals/DEAL_ID/notes \
  -H "Authorization: Bearer $CHATO_KEY" -H 'Content-Type: application/json' \
  -d '{"text": "To‘lov 1C da o‘tdi"}'

curl -X POST https://chato.kz/api/v1/public/deals/DEAL_ID/tasks \
  -H "Authorization: Bearer $CHATO_KEY" -H 'Content-Type: application/json' \
  -d '{"kind": "CALL", "text": "Qayta qo‘ng‘iroq qilish", "dueAt": "2026-10-12T09:00:00+05:00"}'

curl -X POST https://chato.kz/api/v1/public/tasks/TASK_ID/complete \
  -H "Authorization: Bearer $CHATO_KEY" -H 'Content-Type: application/json' \
  -d '{"result": "Bog‘lanildi"}'

Vazifa yaratishga javob:

{
  "data": {
    "id": "cmv2ssf3x000y293dabkcfivc",
    "dealId": "cmv2srw0l000l293dy0wyl3kk",
    "contactId": "cmulm6bkt0007299yv6tep4fx",
    "kind": "CALL",
    "customType": null,
    "text": "Qayta qo‘ng‘iroq qilish",
    "dueAt": "2026-10-12T04:00:00.000Z",
    "allDay": false,
    "responsible": { "id": "cmulak1n60000295aiftvjchb", "name": "Askhat", "email": "askhat@example.com" },
    "createdBy": { "id": "cmulak1n60000295aiftvjchb", "name": "Askhat", "email": "askhat@example.com" },
    "completedAt": null,
    "completedBy": null,
    "result": null,
    "createdAt": "2026-10-10T19:39:10.078Z"
  }
}

Ro‘yxatlar — GET /deals/DEAL_ID/notes va GET /deals/DEAL_ID/tasks. Izoh {id, dealId, text, author, pinned, createdAt} ko‘rinishida keladi.

Vazifa maydonlari:

  • dueAt — muddat, majburiy;
  • kind — vazifa turi: CALL (qo‘ng‘iroq, standart), MEETING (uchrashuv), WRITE (yozish), OTHER yoki o‘zingizning turingiz (CUSTOM va customTypeId bilan birga);
  • allDay — butun kunlik vazifa;
  • responsibleUserId — ijrochi. Standart holatda vazifani bitim mas’uli oladi.

Kontaktlar

  • GET /contacts?phone=87015551122 yoki ?email=... — topish, 20 tagacha kontakt qaytadi. phone va email bo‘lmasa, 400 keladi;
  • GET /contacts/CONTACT_ID — bitta kontakt;
  • {name, phone, email} tanasi bilan POST /contacts — yaratish. Agar odam allaqachon bo‘lsa, mavjud kontakt qaytadi (200, "created": false). Yangi kontakt 201 kodi va "created": true bilan qaytadi;
  • PATCH /contacts/CONTACT_ID — ism, telefon yoki e-mailni o‘zgartirish.

Kontakt: {id, name, phone, email, createdAt}.

Mijozga yozish

messages:send huquqi kerak. So‘rov — POST /messages. Tanada conversationId yoki phone ni ko‘rsating, yangi raqam uchun — qo‘shimcha channelId. text va/yoki fileUrl ni qo‘shing (fileName bilan ham mumkin). Bu kiruvchi havolaning message amali kabi ishlaydi.

{ "data": { "status": "sent", "conversationId": "cmt9x1a2b0003o701abcd1234" } }

Agar bu raqam bilan suhbat bo‘lmasa va channelId berilmagan bo‘lsa, 404 keladi.

Vebxuklar: bitim hodisalari manzilingizga

Manzil qo‘shish ni bosing, https://… manzilini kiriting va hodisalarni belgilang. Saqlangandan keyin manzilning o‘z imzo siri paydo bo‘ladi: uni «Ko‘rsatish» tugmasi bilan ko‘rish mumkin. Kompaniyada 10 tagacha manzil bo‘lishi mumkin.

Hodisa Qachon
deal.created bitim yaratildi (kabinetda, API orqali, murojaatdan)
deal.updated nomi, summasi, teglari, tavsifi, manbai, qo‘shimcha maydonlari yoki mas’uli o‘zgardi
deal.stage_changed bitim boshqa bosqichga o‘tdi
deal.won / deal.lost bitim muvaffaqiyatli / rad etish bilan yopildi
deal.deleted / deal.restored bitim savatga o‘chirildi / savatdan tiklandi
deal.responsible_changed mas’ul o‘zgardi
task.created / task.completed vazifa qo‘yildi / bajarildi
note.created izoh qo‘shildi

Xuddi shu manzilga chat hodisalarini ham olish mumkin: message.received, conversation.closed va boshqalar (Vebxuklar ga qarang). Chat hodisalarida data ichida assistent manzilidagi kabi maydonlar bo‘ladi.

Chato shunday tana bilan POST yuboradi (bitim qisqartirilgan):

{
  "id": "evt_28b44037b3de48b5b944430d9546c5c1",
  "event": "deal.stage_changed",
  "createdAt": "2026-09-29T04:46:42.196Z",
  "workspaceId": "cmulak1n90001295a8kf4ruhe",
  "data": {
    "deal": {
      "id": "cmulms3cp000r29eujik2dr1e",
      "title": "Saytdan ariza",
      "amount": 150000,
      "currency": "KZT",
      "status": "open",
      "pipeline": { "id": "...", "name": "Sotuvlar" },
      "stage": { "id": "...", "name": "Hisob yuborildi", "kind": "OPEN" },
      "contact": { "id": "...", "name": "Aigerim", "phone": "77015551122", "email": "aigerim@example.com", "createdAt": "2026-09-28T19:01:56.381Z" },
      "responsible": { "id": "...", "name": "Askhat", "email": "askhat@example.com" },
      "tags": ["sayt"],
      "fields": { "gorod": "almaty" },
      "closedAt": null
    },
    "changes": {
      "stage": {
        "from": { "id": "...", "name": "Ishda", "kind": "OPEN" },
        "to": { "id": "...", "name": "Hisob yuborildi", "kind": "OPEN" }
      }
    },
    "actor": { "type": "user", "userId": "cmulak1n60000295aiftvjchb" }
  }
}

data ichida nima bor:

  • deal — bitimning to‘liq surati, API qaytaradigan ko‘rinishda;
  • changes — nima o‘zgargani, from → to ko‘rinishida. Kalitlar: title, amount, tags, description, source, responsible, stage, fields.<kod>;
  • actor.type — o‘zgarishni kim qilgani: user (kabinetdagi xodim), api, webhook, automation (unda yonida automationId bor) yoki system;
  • reason — deal.deleted da o‘chirish sababini tushuntiradi;
  • task yoki note — task.* va note.created hodisalarida deal yonida turadi.

So‘rov sarlavhalari:

  • X-Chato-Event — hodisa;
  • X-Chato-Event-Id — barcha takrorlarda bir xil, dublikatlarni shu bo‘yicha tashlang;
  • X-Chato-Delivery — yetkazish id si;
  • X-Chato-Timestamp — yuborish vaqti, Unix soniyalari;
  • X-Chato-Signature — imzo;
  • User-Agent: Chato-Webhooks/1.0.

Imzoni tekshirish

X-Chato-Signature — bu sha256= va manzil siri bilan <X-Chato-Timestamp>.<xom tana> satridan hisoblangan HMAC-SHA256 (sir whsec_ bilan boshlanadi). Imzoni JSON tahlil qilinishidan oldin xom tana bo‘yicha hisoblang. 5 daqiqadan eski so‘rovlarni rad eting.

Node.js (Express):

const crypto = require('node:crypto');
app.post('/chato', express.raw({ type: 'application/json' }), (req, res) => {
  const ts = req.get('X-Chato-Timestamp');
  const expected = 'sha256=' + crypto
    .createHmac('sha256', process.env.CHATO_WEBHOOK_SECRET)
    .update(`${ts}.${req.body}`)
    .digest('hex');
  const given = req.get('X-Chato-Signature') || '';
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
  if (!fresh || given.length !== expected.length ||
      !crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected))) {
    return res.sendStatus(401);
  }
  const event = JSON.parse(req.body);
  res.sendStatus(200); // darhol javob bering, og‘ir ish — fonda
});

PHP:

$body = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_CHATO_TIMESTAMP'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $ts . '.' . $body, getenv('CHATO_WEBHOOK_SECRET'));
$given = $_SERVER['HTTP_X_CHATO_SIGNATURE'] ?? '';
if (abs(time() - (int) $ts) > 300 || !hash_equals($expected, $given)) {
    http_response_code(401);
    exit;
}
$event = json_decode($body, true);
http_response_code(200);

Python (Flask):

import hmac, hashlib, os, time
from flask import request, abort

@app.post("/chato")
def chato():
    body = request.get_data()  # xom baytlar
    ts = request.headers.get("X-Chato-Timestamp", "")
    expected = "sha256=" + hmac.new(
        os.environ["CHATO_WEBHOOK_SECRET"].encode(), f"{ts}.".encode() + body, hashlib.sha256
    ).hexdigest()
    given = request.headers.get("X-Chato-Signature", "")
    if abs(time.time() - int(ts or 0)) > 300 or not hmac.compare_digest(expected, given):
        abort(401)
    event = request.get_json()
    return "", 200

Qayta yuborishlar, jurnal, avto-o‘chirish

  • Agar serveringiz 10 soniya ichida istalgan 2xx kodi bilan javob bersa, yetkazish muvaffaqiyatli hisoblanadi. Aks holda Chato so‘rovni 1 daq, 5 daq, 30 daq, 2 soat va 6 soatdan keyin takrorlaydi. Jami 8,5 soat ichida olti urinish. Yo‘naltirishlarni (3xx) Chato bajarmaydi va muvaffaqiyatsizlik deb hisoblaydi.
  • Har bir manzil ostida Yetkazish jurnali bor: holat, javob kodi, urinishlar soni, nima yuborilgani va serveringiz nima javob bergani. Qayta yuborish tugmasi hodisaning o‘sha id si bilan yetkazishni takrorlaydi. Jurnal 30 kun saqlanadi.
  • Agar ketma-ket 25 urinish o‘tmasa va muvaffaqiyatsizliklar bir sutkadan ko‘p davom etsa, manzil o‘zi o‘chadi. Egasi va administratorlar bildirishnoma oladi. Qabul qiluvchini tuzating va Yoqish ni bosing.
  • Tekshirish data: {"message": "Проверка адреса вебхука Chato"} bilan ping sinov hodisasini yuboradi.
  • Yangi sir yangi imzo sirini chiqaradi. Eskisi darhol yaroqsiz bo‘ladi.

Darhol 200 javob bering, qayta ishlashni esa fonda bajaring. Uzoq javobni Chato muvaffaqiyatsizlik deb hisoblaydi va so‘rovni takrorlaydi. Takror o‘sha X-Chato-Event-Id bilan keladi, uni oson tanish mumkin.

Kiruvchi havola orqali bitimlar

Agar assistentning kiruvchi havolasidan allaqachon foydalansangiz, u bitimlar bilan ham ishlay oladi. Qoidalar API dagi kabi, bitim tarixida esa «vebxuk orqali» belgisi bo‘ladi. Amallar kompaniya egasi nomidan bajariladi.

{ "action": "deal.create", "contact": { "name": "Aigerim", "phone": "+77015551122" }, "deal": { "title": "1C dan buyurtma", "amount": 77000 } }
{ "action": "deal.move", "dealId": "DEAL_ID", "stageId": "STAGE_ID" }
{ "action": "deal.note", "dealId": "DEAL_ID", "text": "To‘lov o‘tdi" }

Javobda status (deal_created, deal_moved yoki note_added) va deal keladi, deal.note uchun esa yana note.