مستند فنی چت وب CRM (Embed) برای توسعهدهندگان
[ویرایش | ویرایش مبدأ]این سند قرارداد REST API و WebSocket بستر چت وب را توصیف میکند. رابط کاربری ویجت روی سایت مشتری (مثلاً افزونهٔ وردپرس) جدا از این مخزن توسعه داده میشود؛ اینجا فقط بکاند Hesabix است.
پیشنیاز دیتابیس
[ویرایش | ویرایش مبدأ]پس از بهروزرسانی کد، مایگریشن زیر را اجرا کنید:
cd hesabixAPI
alembic upgrade head
فایل مایگریشن: migrations/versions/20260505_000001_crm_chat_embed.py
جداول: crm_chat_widgets, crm_chat_conversations, crm_chat_messages.
برای ثبت مدلها در metadata آل embیک، import adapters.db.models.crm_chat در migrations/env.py اضافه شده است. اگر در محیط شما جایی غیر از این، metadata بدون این مدلها لود میشود، میتوانید در adapters/db/models/__init__.py نیز ایمپورت مدلهای crm_chat را اضافه کنید.
اتصال روترها به اپلیکیشن
[ویرایش | ویرایش مبدأ]- مسیرهای مدیریتی چت زیر همان روتر CRM سوار شدهاند:
router.include_routerدر انتهایadapters/api/v1/crm.py. - مسیرهای عمومی در
adapters/api/v1/public_share_links.pyباinclude_routerبه روتر اشتراکلینکها اضافه شدهاند. - WebSocket در
adapters/api/v1/notifications_ws.pyباinclude_routerکنار/ws/notificationsثبت شده است.
نیازی به تغییر main.py برای این نسخه نیست.
جریان کاری (بازدیدکننده)
[ویرایش | ویرایش مبدأ]- قبل از چت، فرم سمت سایت شما نام، نام خانوادگی، ایمیل و تلفن را میگیرد.
- با
POST /api/v1/public/crm-chat/conversations/startمکالمه ساخته میشود وvisitor_token+conversation_idبرمیگردد. - سپس بازدیدکننده میتواند با
POST /api/v1/public/crm-chat/messagesپیام بفرستد و باGET .../messagesتاریخچه را بخواند. - اختیاری: برای رویداد لحظهای، WebSocket بازدیدکننده (پایین) با همان
visitor_tokenوconversation_id.
CORS و مبدأ (Origin)
[ویرایش | ویرایش مبدأ]- درخواستهای عمومی از دامنهٔ سایت مشتری به API Hesabix میآیند؛ باید دامنهٔ API در
allow_originsتنظیمات CORS سرور Hesabix برای آن دامنهها مجاز باشد (مثل سایر کلاینتهای وب). - برای هر ویجت میتوان فهرست
allowed_origins(لیست hostname، مثلexample.com) ذخیره کرد. اگر خالی باشد، از نظر بکاند مبدأ بررسی نمیشود (پیشنهاد: در تولید حتماً محدود شود). سرور هدرOriginیا در نبود آنRefererرا برای تشخیص host استفاده میکند.
REST — عمومی (بدون Authorization)
[ویرایش | ویرایش مبدأ]پایهٔ مسیرها: همان host بکاند (مثلاً https://api.example.com).
شروع مکالمه
[ویرایش | ویرایش مبدأ]POST /api/v1/public/crm-chat/conversations/start
بدنهٔ JSON نمونه:
{
"public_key": "<از پنل CRM پس از ساخت ویجت>",
"first_name": "علی",
"last_name": "رضایی",
"email": "ali@example.com",
"phone": "09123456789",
"page_url": "https://customer-site.com/contact"
}
پاسخ موفق (داخل data):
conversation_id(integer)visitor_token(رشتهٔ محرمانه؛ فقط برای همان مرورگر/نشست نگه دارید)widget_id
ارسال پیام بازدیدکننده
[ویرایش | ویرایش مبدأ]POST /api/v1/public/crm-chat/messages
{
"visitor_token": "...",
"conversation_id": 1,
"body": "سلام، سوال دارم"
}
لیست پیامها (بازدیدکننده)
[ویرایش | ویرایش مبدأ]GET /api/v1/public/crm-chat/conversations/{conversation_id}/messages?visitor_token=...&limit=100
خروجی: { "data": { "items": [ { "id", "sender_role", "body", "created_at", ... } ] } }
sender_role: visitor | agent | system (در حال حاضر عمدتاً visitor/agent).
REST — پنل CRM (با API key کاربر Hesabix)
[ویرایش | ویرایش مبدأ]همه با هدر:
Authorization: Bearer <api_key>
و همان الگوی سایر APIها (مثلاً X-Business-ID اگر در کلاینت شما لازم است).
پایه: /api/v1/crm/businesses/{business_id}/chat/...
| متد | مسیر | مجوز تقریبی |
|---|---|---|
| GET | /widgets
|
crm + view
|
| POST | /widgets
|
crm + write
|
| PATCH | /widgets/{widget_id}
|
crm + write
|
| GET | /conversations
|
crm + view
|
| GET | /conversations/{id}/messages
|
crm + view
|
| POST | /conversations/{id}/messages
|
crm + write (پاسخ عامل)
|
| PATCH | /conversations/{id}
|
crm + write (وضعیت، assign، lead_id، person_id)
|
فیلدهای ویجت مهم: public_key, allowed_origins, is_active, settings (JSON اختیاری برای آیندهٔ UI).
WebSocket
[ویرایش | ویرایش مبدأ]مسیر: /ws/crm-chat (بدون پیشوند /api/v1؛ همان الگوی /ws/notifications).
بلافاصله پس از اتصال TLS، اولین فریم باید JSON متنی باشد.
احراز بازدیدکننده
[ویرایش | ویرایش مبدأ]{
"type": "auth",
"role": "visitor",
"visitor_token": "...",
"conversation_id": 1
}
پاسخ موفق: { "type": "auth_ok", "role": "visitor", "conversation_id": 1 }
سپس سرور رویدادهای crm_chat.event را برای همان مکالمه push میکند (مثلاً message.created).
احراز عامل CRM
[ویرایش | ویرایش مبدأ]{
"type": "auth",
"role": "agent",
"api_key": "<همان Bearer>",
"business_id": 123
}
پاسخ: { "type": "auth_ok", "role": "agent", "business_id": 123 }
برای دریافت پیامهای یک ترد خاص، پس از auth_ok برای هر مکالمه یک بار بفرستید:
{ "type": "subscribe", "conversation_id": 1 }
قالب تقریبی رویداد:
{
"type": "crm_chat.event",
"event": "message.created",
"conversation_id": 1,
"message": { "id", "conversation_id", "sender_role", "body", "user_id", "created_at" }
}
رویدادهای conversation.started و conversation.updated روی کانال کسبوکار نیز برای عاملهای متصل broadcast میشوند.
ورکفلو (اتوماسیون)
[ویرایش | ویرایش مبدأ]تریگرهای ثبتشده (کلید برای نود Trigger در ویرایشگر ورکفلو):
crm.chat.conversation.startedcrm.chat.message.receivedcrm.chat.message.sentcrm.chat.conversation.assignedcrm.chat.conversation.resolvedcrm.chat.conversation.reopened
بدنهٔ trigger_data معمولاً شامل conversation_id, widget_id و برای پیامها message_id, body, sender_role است.
نمونهٔ حداقلی برای افزونهٔ وردپرس
[ویرایش | ویرایش مبدأ]- در تنظیمات افزونه:
API_BASE,public_key(و در صورت نیازbusiness_idفقط برای ابزارهای داخلی، نه برای سایت عمومی). - در فرانت سایت: فرم نام/نامخانوادگی/ایمیل/تلفن →
conversations/start→ ذخیرهٔvisitor_tokenدرsessionStorage. - ارسال پیامها با
POST .../messagesو نمایش تاریخچه باGET. - اختیاری:
new WebSocket(wsBase + '/ws/crm-chat')و ارسال فریمauthبازدیدکننده. public_keyرا هرگز در کد سرور وردپرس برای عملیات حساس بهتنهایی کافی نکنید؛ برای مدیریت ویجت فقط از توکنهای ادمین وردپرس و درخواست سمت سرور استفاده کنید. روی سایت عمومی فقطpublic_key(همان که در embed تعمداً عمومی است) کافی است.
اگر اسکریپت ویجت را خودتان روی CDN بگذارید، آدرس آن میتواند بعداً فقط public_key را به این APIها وصل کند؛ بکاند Hesabix فایل JS ویجت سرو نمیکند.
امنیت
[ویرایش | ویرایش مبدأ]visitor_tokenمانند نشست کوتاه برای همان مکالمه است؛ طولانی نگه ندارید و در لاگهای عمومی ننویسید.- محدودیت نرخ (rate limit) در این نسخهٔ اولیه روی اندپوینتهای عمومی بهصورت سراسری به عهدهٔ فایروال/زیرساخت است؛ در صورت نیاز بعداً در اپلیکیشن اضافه میشود.
سؤالات یا تغییرات قرارداد API را میتوان در کنار این سند نسخهگذاری کرد (مثلاً prefix v2 در آینده).