Asosiy mazmunga o'tish
Socialift
CRM integratsiya

Instagram, Lead Ads va Telegram'ni amoCRM va Bitrix24 bilan integratsiya qilish

Instagram Lead Ads yoki Telegram'dan kelgan murojaatni amoCRM yoki Bitrix24 ga avtomatik yozish uchun o'rtada o'z backend'ingiz turadi. U platforma webhook'ini qabul qiladi, imzoni tekshiradi, lead ma'lumotini oladi, telefonni +998 formatiga keltiradi va CRM API'siga yozadi. Socialift'da bu CRM'lar uchun tayyor konnektor yo'q: SDK platforma tomonini beradi, CRM chaqiruvlari esa sizning kodingizda.

Yangilangan:

Instagram'ni amoCRM yoki Bitrix24 ga qanday ulash mumkin?

Ikki yo'l bor. Birinchisi — CRM'ning o'z kanal integratsiyasi (masalan, Bitrix24 Open Channels): chat yozishmalari uchun qulay. Ikkinchisi — o'z backend'ingiz: Meta webhook'i → imzo tekshiruvi → lead ma'lumotini olish → normallashtirish → CRM API. Reklama atributsiyasi, o'z dublikat qoidalaringiz va marshrutlash kerak bo'lsa, ikkinchi yo'l to'liq nazorat beradi.

Bitrix24 yordam markazida Open Channels (Открытые линии) uchun ulanadigan kanallar ro'yxatida Instagram va Telegram bor. amoCRM esa integratorlar uchun Chats API taqdim etadi. Bular suhbatlarni CRM ichiga olib kiradi, lekin Lead Ads formasidagi kampaniya, reklama va forma identifikatorlarini siz xohlagan maydonlarga yozish odatda o'z kodingizni talab qiladi.

Socialift'da amoCRM, Bitrix24 yoki boshqa CRM uchun tayyor konnektor yo'q. Socialift — Python SDK: u webhook imzosini tekshiradi, hodisalarni ajratadi, lead'ni Graph API'dan oladi va forma javoblarini normallashtiradi. CRM'ga yozadigan 20–40 qator kodni quyida ko'rsatamiz.

Arxitektura: webhook'dan CRM yozuvigacha 6 qadam

Har bir qadam alohida ishlaydi — shuning uchun biri yiqilsa, qolganlari ma'lumotni yo'qotmaydi.

  1. Webhook'ni ulang

    Meta App'da leadgen maydoniga obuna bo'ling va har bir Page'ni app'ga ulang (SDK'da fb.subscribe_page(page_id, page_token, fields=["leadgen"])). Telegram bot uchun set_webhook(url, secret_token=...).

  2. Imzoni tekshiring

    Meta so'rovi X-Hub-Signature-256 bilan keladi: verify_request(app_secret, body, headers). Telegram tanani imzolamaydi — verify_telegram_request(headers, secret_token) sarlavhadagi maxfiy satrni solishtiradi.

  3. Hodisalarni ajrating va dedupe qiling

    parse_events(payload) har bir hodisani WebhookEvent ga aylantiradi. event.key ni bazadagi unikal ustunga yozing: Meta bir hodisani qayta yuborishi mumkin.

  4. Lead ma'lumotini oling

    leadgen webhook'ida forma javoblari yo'q — faqat leadgen_id, page_id, form_id, ad_id kabi identifikatorlar. To'liq yozuv fb.lead(leadgen_id, page_token) bilan olinadi.

  5. Normallashtiring

    normalize(lead.field_data) turli nomlangan maydonlarni full_name, phone, email ga keltiradi. Telefonni E.164 (+998...) ga o'zingiz yakunlang.

  6. CRM'ga navbat orqali yozing

    Webhook'ga darhol 200 qaytaring, CRM chaqiruvini fon ishchisiga bering: telefon bo'yicha dublikat qidiring, keyin yarating. 429/503 da kechikish bilan qayta urining.

Webhook qabul qiluvchi (aiohttp)

Handler faqat tekshiradi, dedupe qiladi va navbatga qo'yadi — og'ir ish keyin.

webhook.py
import json, os
from aiohttp import web
from socialift.webhooks import verify_request, parse_events

APP_SECRET = os.environ["META_APP_SECRET"]

async def meta_webhook(request: web.Request) -> web.Response:
    body = await request.read()  # xom baytlar — imzo shular bo'yicha
    if not verify_request(APP_SECRET, body, request.headers):
        return web.Response(status=403)
    for event in parse_events(json.loads(body)):
        if event.field == "leadgen" and await mark_seen(event.key):
            await queue.put({"leadgen_id": event.leadgen_id, "page_id": event.page_id})
    return web.Response(text="ok")

mark_seen — sizning funksiyangiz: INSERT ... ON CONFLICT DO NOTHING va yangi yozuv bo'lsa True. queue — Redis, RabbitMQ yoki bazadagi jadval.

Lead'ni olish va telefonni +998 formatiga keltirish

SDK'ning normalize() bo'shliq va chiziqchalarni olib tashlaydi, + ni saqlaydi, lekin davlat kodini qo'shmaydi.

lead.py
import re
from socialift import Facebook
from socialift.leads import normalize

def to_e164_uz(raw: str | None) -> str | None:
    digits = re.sub(r"\D", "", raw or "")
    if digits.startswith("00"):
        digits = digits[2:]
    if len(digits) == 12 and digits.startswith("998"):
        return "+" + digits
    if len(digits) == 9:  # 90 123 45 67
        return "+998" + digits
    return None  # qo'lda tekshirish uchun

async def load_lead(fb: Facebook, leadgen_id: str, page_token: str) -> dict:
    lead = await fb.lead(leadgen_id, page_token)
    person = normalize(lead.field_data)
    return {"lead_id": lead.id, "name": person.full_name, "email": person.email,
            "phone": to_e164_uz(person.phone), "phone_raw": person.phone,
            "form_id": lead.form_id, "ad_id": lead.ad_id,
            "campaign": lead.campaign_name, "organic": lead.is_organic}

O'zbekiston raqami +998 dan keyin 9 raqamdan iborat. Formatga tushmagan raqamni tashlab yubormang: phone_raw ni CRM izohiga yozing va menejer ko'rsin.

amoCRM va Bitrix24 API: nima bilan yoziladi

amoCRM va Bitrix24 API: nima bilan yoziladi — Platformalar bo'yicha imkoniyatlar jadvali
amoCRM (API v4)Bitrix24 (REST)
KirishOAuth 2.0; xususiy integratsiya uchun uzoq muddatli tokenKiruvchi webhook (maxfiy kod URL ichida) yoki OAuth ilova
Token muddatiHujjat namunasida expires_in 86400 (24 soat); refresh token 3 oy, faqat bir marta almashtiriladiOAuth: access 1 soat, refresh 180 kun; webhook yaratgan xodim huquqlari bilan ishlaydi
Lead yaratishPOST /api/v4/leads/complex — sdelka + kontakt + kompaniya bitta so'rovda, 50 tagachacrm.item.add (entityTypeId: 1); crm.lead.add ishlaydi, lekin rivojlantirish to'xtatilgan
Telefon maydonicustom_fields_values: field_code PHONE, enum_code WORK/MOBfm: typeId PHONE, valueType WORK/MOBILE
Dublikat qidirishGET /api/v4/contacts?query=...; complex'da dubl nazorati (integratsiya uchun yoqilgan bo'lsa)crm.duplicate.findbycomm — PHONE/EMAIL, bir so'rovda 20 tagacha qiymat
LimitIntegratsiyaga 7 so'rov/s, akkauntga 50 so'rov/s; oshsa 429, qayta-qayta buzilsa 403 (blok)Leaky bucket: 2 so'rov/s, 50 da blok (Enterprise: 5/s, 250); 503 QUERY_LIMIT_EXCEEDED
Xato401 — avtorizatsiya yo'q, 400 — noto'g'ri ma'lumotTanada error va error_description; noto'g'ri webhook — 401 INVALID_CREDENTIALS

Qiymatlar amoCRM va Bitrix24 rasmiy hujjatlaridan (2026-09-17). Limitlar o'zgarishi mumkin — ishga tushirishdan oldin qayta tekshiring.

amoCRM: sdelka va kontaktni bitta so'rovda yaratish

leads/complex sdelka, kontakt va telefonni birga yaratadi. request_id javobda qaytadi — uni lead ID bilan bog'lang.

amocrm.py
import os, aiohttp

AMO = f"https://{os.environ['AMO_SUBDOMAIN']}.amocrm.ru/api/v4"
HEADERS = {"Authorization": f"Bearer {os.environ['AMO_ACCESS_TOKEN']}"}

async def amo_create(session: aiohttp.ClientSession, lead: dict) -> dict:
    payload = [{
        "name": f"Lead Ads: {lead['campaign'] or lead['form_id']}",
        "request_id": lead["lead_id"],
        "_embedded": {
            "tags": [{"name": "instagram-lead-ads"}],
            "contacts": [{
                "first_name": lead["name"] or "Lead",
                "custom_fields_values": [{"field_code": "PHONE",
                    "values": [{"enum_code": "MOB", "value": lead["phone"]}]}],
            }],
        },
    }]
    async with session.post(f"{AMO}/leads/complex", json=payload, headers=HEADERS) as r:
        if r.status == 429:
            raise RetryLater(r.status)
        r.raise_for_status()
        return (await r.json())[0]  # id, contact_id, merged

Javobdagi merged: true — amoCRM dubl nazorati mavjud kontakt topib birlashtirganini bildiradi. Nazorat o'chiq bo'lsa, avval GET /api/v4/contacts?query=<telefon> bilan qidiring.

Atributsiyani izohga yozish uchun: POST /api/v4/leads/{id}/notes — note_type: "common", params.text ichida forma, reklama va kampaniya.

Bitrix24: kiruvchi webhook va crm.item.add

Webhook URL'ining o'zi kalit: uni muhit o'zgaruvchisida saqlang va hech qachon frontend kodiga qo'ymang.

bitrix24.py
import os, aiohttp

B24 = os.environ["B24_WEBHOOK_URL"]  # https://<portal>/rest/<user_id>/<secret>/

async def b24(session: aiohttp.ClientSession, method: str, params: dict):
    async with session.post(f"{B24}{method}.json", json=params) as r:
        data = await r.json()
    if "error" in data:  # QUERY_LIMIT_EXCEEDED -> keyinroq qayta urining
        raise B24Error(data["error"], data.get("error_description"))
    return data["result"]

async def b24_create(session: aiohttp.ClientSession, lead: dict) -> int:
    dup = await b24(session, "crm.duplicate.findbycomm",
                    {"entity_type": "LEAD", "type": "PHONE", "values": [lead["phone"]]})
    if isinstance(dup, dict) and dup.get("LEAD"):
        return dup["LEAD"][0]
    res = await b24(session, "crm.item.add", {"entityTypeId": 1, "fields": {
        "title": f"Lead Ads: {lead['campaign'] or lead['form_id']}",
        "name": lead["name"],
        "utmCampaign": lead["campaign"],
        "sourceDescription": f"form={lead['form_id']} ad={lead['ad_id']}",
        "fm": [{"typeId": "PHONE", "valueType": "MOBILE", "value": lead["phone"]}],
    }})
    return res["item"]["id"]

Bitrix24 xatoni HTTP status bo'yicha emas, tanadagi error maydoni bo'yicha aniqlashni tavsiya qiladi — batch ichidagi xatolar 200 bilan qaytadi.

Portal "oddiy CRM" rejimida bo'lsa lead'lar yo'q: yaratilgan lead darhol sdelkaga aylanadi. Rejimni crm.settings.mode.get bilan tekshiring. sourceId uchun to'g'ri qiymatlar crm.status.list (ENTITY_ID = SOURCE) da.

Atributsiya: Lead Ads maydonlari CRM'da qayerga tushadi

SDK'dagi Lead obyekti forma va reklama identifikatorlarini qaytaradi. Ularni yo'qotmang — aks holda qaysi kampaniya sotuv berganini bilib bo'lmaydi.

Atributsiya: Lead Ads maydonlari CRM'da qayerga tushadi — Platformalar bo'yicha imkoniyatlar jadvali
Lead maydoniamoCRMBitrix24
form_idTeg yoki qo'shimcha maydon; izohdasourceDescription
ad_id, ad_nameQo'shimcha maydon yoki izohutmContent yoki comments
campaign_id, campaign_nameSdelka nomi va tegutmCampaign
is_organicTeg (organic / paid)sourceId (portalda sozlangan manba)
lead.idrequest_id va izohcomments yoki qo'shimcha maydon

Ad set, kampaniya maqsadi va targeting kerak bo'lsa: fb.ad_context(ad_id, token) — ads_management ruxsati bo'lmasa bo'sh lug'at qaytaradi va lead oqimini to'xtatmaydi.

Telegram bot murojaatlarini CRM'ga qanday yozish mumkin?

Telegram bot webhook'i imzolanmaydi: set_webhook(url, secret_token=...) da bergan satringiz har so'rovda X-Telegram-Bot-Api-Secret-Token sarlavhasida qaytadi. Uni verify_telegram_request(headers, secret_token) bilan tekshiring.

Telefon raqamini so'rashning rasmiy yo'li — request_contact tugmasi: foydalanuvchi bosganda uning raqami contact xabari bo'lib keladi (faqat shaxsiy chatda). contact.phone_number ni xuddi Lead Ads dagidek +998 formatiga keltiring va o'sha amo_create yoki b24_create funksiyasiga bering.

Dedupe kaliti sifatida update_id yoki chat ID + xabar ID juftligini saqlang. Bitta mijoz botga bir necha marta yozsa, CRM'da yangi lead emas, mavjudiga izoh qo'shish odatda to'g'riroq.

Dublikat, qayta urinish va ishonchlilik

  • Ikki darajali dedupe: webhook darajasida event.key (unikal ustun), CRM darajasida telefon bo'yicha qidiruv.
  • amoCRM 429 va Bitrix24 QUERY_LIMIT_EXCEEDED — vaqtinchalik: eksponensial kechikish + jitter bilan qayta urining.
  • amoCRM limitni qayta-qayta buzsa akkaunt bloklanadi (403) — ishchilar sonini cheklang, 403 da to'xtab ogohlantirish yuboring.
  • amoCRM refresh token bir martalik: yangi access va refresh juftligini bitta tranzaksiyada saqlang.
  • Webhook o'tkazib yuborgan davr uchun fb.leads(form_id, page_token, since=...) bilan backfill qiling.
  • Telefon, email va tokenlarni log'ga yozmang; Bitrix24 webhook URL'ini maxfiy kalit sifatida saqlang.
  • Normallashtira olmagan raqamni tashlamang — xom qiymatni izohga yozib, menejerga qoldiring.

← Blogga qaytish

Ko'p so'raladigan savollar

Socialift'da amoCRM yoki Bitrix24 uchun tayyor konnektor bormi?

Yo'q. Socialift — dasturchilar uchun Python SDK va kabinet. U Instagram, Facebook, Telegram va boshqa platformalar tomonini beradi; CRM API'siga yozadigan kodni o'z backend'ingizda yozasiz. Bu maqoladagi namunalar shu kodning asosi.

Lead Ads webhook'ida mijozning telefon raqami keladimi?

Yo'q. leadgen webhook'i faqat identifikatorlarni yuboradi: leadgen_id, page_id, form_id, ad_id va vaqt. Forma javoblari alohida Graph API so'rovi bilan olinadi — SDK'da fb.lead(leadgen_id, page_token).

Bitrix24'da crm.lead.add yoki crm.item.add ishlataymi?

Yangi integratsiya uchun crm.item.add (entityTypeId: 1). Bitrix24 hujjatida crm.lead.add rivojlantirilishi to'xtatilgani va crm.item.add tavsiya etilishi yozilgan. Telefon crm.item.add da fm massivi orqali uzatiladi.

amoCRM API'da nechta so'rov yuborish mumkin?

Hujjatga ko'ra bitta integratsiya sekundiga 7 tagacha, butun akkaunt esa 50 tagacha so'rov yubora oladi. Oshsa 429 qaytadi, qayta-qayta buzilsa akkaunt bloklanib 403 qaytaradi. Bitta so'rovda 50 tagacha sdelka yuborish tavsiya etiladi.

Bitrix24 QUERY_LIMIT_EXCEEDED xatosi nima?

Bu so'rovlar intensivligi limiti: hisoblagich chegaradan oshganda Bitrix24 503 va QUERY_LIMIT_EXCEEDED qaytaradi. Oddiy tariflarda hisoblagich sekundiga 2 taga kamayadi va 50 da bloklaydi, Enterprise'da 5 va 250. Yechim — navbat va qisqa kechikish bilan qayta urinish.

Manbalar

  1. amoCRM — Сделки, комплексное добавление
  2. amoCRM — Рекомендации и ограничения API
  3. amoCRM — OAuth 2.0 пошагово
  4. Bitrix24 — crm.item.add
  5. Bitrix24 — REST API limits
  6. Meta — Retrieving Leads

Bog'liq sahifalar