20 KiB
Executable file
راهنمای یکپارچهسازی چت وب CRM (Hesabix) برای توسعهدهنده
این سند برای سازندهٔ افزونه، توسعهدهندهٔ فرانت سایت، یا هر کسی است که میخواهد سایت خود را به چت تحت وب CRM Hesabix وصل کند.
بکاند تنها REST API و WebSocket را ارائه میکند؛ رابط بصری (ویجت) را خودتان در سایت/افزونه مینویسید (وردپرس، نکست، لاراول، و غیره).
فهرست
- آنچه از ابتدا لازم است
- پیکربندی در Hesabix (کسبوکار)
- پایه آدرس و هدرها
- جریان کلی یکپارچهسازی
- APIهای عمومی (بدون ورود — بازدیدکننده)
- ارسال و دریافت فایل (بازدیدکننده)
- شکل پاسخ پیامها (شامل فایل)
- کدهای خطا (مخصوص فایل و تنظیمات)
- WebSocket (نسخه واقعزمان)
- API مدیریت (با API Key — داخل Hesabix یا ابزار ادمین)
- اتصال سایت: پلاگین وردپرس و نمونه کد
- CORS و دامنه مجاز (Origin)
- امنیت و نکات تولید
- ورکفلو (اتوماسیون داخل Hesabix)
- پایگاه داده و مایگریشن (برای ادمین/استقرار سرور)
- عیبیابی
آنچه از ابتدا لازم است
| مورد | توضیح |
|---|---|
| آدرس بکاند API | مثال: https://api.example.com (همان API_BASE که فراخوانی میزنید) |
public_key ویجت |
پس از ساخت ویجت چت در پنل CRM (چت وب)، از پنل کپی میشود. این کلید عمومی است (برای شروع مکالمه سمت سایت شما) |
| HTTPS | روی تولید، ترجیحاً هر دو طرف HTTPS باشند. |
| CORS | دامنهٔ سایت شما باید در allow_origins سرور Hesabix برای درخواستهای مرورگر به API مجاز باشد. |
| پلن فضای ذخیرهسازی (فقط اگر فایل میخواهید) | برای آپلود فایل توسط بازدیدکننده باید روی کسبوکار اشتراک/فضای ذخیرهسازی فعال و ظرفیت کافی وجود داشته باشد؛ بخش ارسال فایل را ببینید. |
پیکربندی در Hesabix (کسبوکار)
- ساخت ویجت:
CRM→چت وب→ ساخت ویجت، در صورت تمایل دامنههای مجاز (allowed_originsبهصورت hostname مثلshop.example.com). - تنظیمات CRM (اختیاری برای فایل):
تنظیمات کسبوکار→ تنظیمات CRM — گزینه «ارسال فایل در چت وب»- اگر خاموش باشد،
POSTآپلود فایل سمت بازدیدکننده رد میشود (با کدCRM_FILE_UPLOAD_DISABLED). - روشن بودن تضمین نمیکند که فایل پذیرفته شود؛ اگر پلن/سهمیه نباشد، بازدیدکننده خطای «فعلاً ارسال فایل ممکن نیست» میگیرد و مالک کسبوکار (در صورت پیکربندی نوتیفیکیشن) میتواند اطلاع بگیرد.
- اگر خاموش باشد،
پایه آدرس و هدرها
- همه مسیرها زیر
API_BASE، معمولاً به شکل:
https://<host>/api/v1/... - WebSocket بدون
/api/v1است، مثلاً:wss://<host>/ws/crm-chat(پورت و مسیر مثلws/notifications).
بازدیدکننده (عمومی): بدون Authorization — فقط Content-Type: application/json برای JSON (برای multipart نیاز نیست).
مدیریت (پنل / سرور امن):
Authorization: ApiKey <YOUR_API_KEY> (یا الگوی همان Bearer که در سایر مستندات Hessabix آمده) و در صورت نیاز همان الگوهای X-Business-ID مثل بقیه APIهای CRM.
جریان کلی یکپارچهسازی
[کاربر] → پر کردن فرم (نام، نامخانوادگی، ایمیل، موبایل) در سایت شما
→ POST .../conversations/start با public_key
→ ذخیرهٔ امن visitor_token + conversation_id (مثلاً sessionStorage)
↓
ارسال متن: POST .../messages
اختیاری: ارسال فایل: POST .../messages/file (فرم)
اختیاری: WebSocket + auth بازدیدکننده برای رویداد لحظهای
↓
نمایش تاریخچه: GET .../messages
اگر پیام فایل دارد: GET .../files/{file_id}/download?visitor_token=...
- برای هر مکالمه یک
visitor_token— با تب جدید یا دوباره «شروع» مکالمه، توکن و ID جدید میگیرید (طبق سیاست کسبوکار میتواند یک مکالمه ادامهدار روی سایت شما باشد اگر دوبارهstartنزنید و همانsessionStorageرا نگه دارید).
APIهای عمومی (بازدیدکننده)
همه زیر: https://<API_BASE>/api/v1/public/crm-chat/
۱) شروع مکالمه
POST /api/v1/public/crm-chat/conversations/start
بدنه (JSON):
{
"public_key": "<public_key از پنل>",
"first_name": "علی",
"last_name": "رضایی",
"email": "ali@example.com",
"phone": "09123456789",
"page_url": "https://shop.example.com/contact",
"device_type": "mobile"
}
فیلد device_type اختیاری است: یکی از "mobile"، "tablet"، "desktop" (ویجت رسمی Hesabix آن را از مرورگر میفرستد). سرور آدرس IP بازدیدکننده را در پایگاه ذخیره میکند و در پنل اپراتور با extra_metadata مکالمه برمیگردد.
پاسخ موفق (در data):
conversation_id(عدد)visitor_token(رشته محرمانه — فقط در سمت کلاینت/جلسه نگه دارید)widget_id
۲) بهروزرسانی صفحهٔ فعلی بازدیدکننده (برای اپراتور)
PATCH /api/v1/public/crm-chat/conversations/{conversation_id}/current-page
پس از شروع مکالمه، هر بار که بازدیدکننده در سایت شما به صفحهٔ دیگری میرود، این مسیر را با همان الویت توکن (X-Visitor-Token یا Authorization: Bearer) صدا بزنید تا فیلد page_url مکالمه بهروز شود و از طریق رویداد WebSocket conversation.updated نزد اپراتور همزمان دیده شود.
بدنه (JSON):
{
"page_url": "https://shop.example.com/products/42?utm=..."
}
۳) ارسال پیام متنی
POST /api/v1/public/crm-chat/messages
{
"visitor_token": "<token>",
"conversation_id": 123,
"body": "سلام"
}
۴) لیست پیامها (بازدیدکننده)
GET /api/v1/public/crm-chat/conversations/{conversation_id}/messages?limit=100
- اقدام لازم: ارسال توکن بازدیدکننده در هدر (روش جدید، توصیهشده):
X-Visitor-Token: <token>یاAuthorization: Bearer <token>. - سازگاری: همچنان میتوان
?visitor_token=<token>فرستاد (الویت: هدر). - CORS preflight: هدر
X-Visitor-Token(یاAuthorization) باید درAccess-Control-Allow-Headersاجازه داشته باشد (بکاند حسابیکسallow_headersرا باز دارد).
ساختار آیتمها: بخش شکل پاسخ پیامها.
ارسال و دریافت فایل (بازدیدکننده)
پیششرط
- در تنظیمات CRM کسبوکار: ارسال فایل در چت وب = فعال
- پلن/فضای ذخیرهسازی فعال و ظرفیت کافی (در غیر این صورت خطای
CRM_FILE_NOT_AVAILABLE— بخش کدها) - محدودیت حجم طبق تنظیمات سیستم (مشابه سایر آپلودها)
ارسال فایل (multipart)
POST /api/v1/public/crm-chat/messages/file
- Content-Type:
multipart/form-data - فیلدها:
| فیلد | نوع | اجباری | توضیح |
|---|---|---|---|
visitor_token |
string | ✓ | همان از شروع مکالمه |
conversation_id |
عدد (form) | ✓ | |
caption |
string | توضیح اختیاری روی فایل؛ اگر خالی باشد، متن پیام بهصورت خودکار مثل 📎 نام-فایل ثبت میشود |
|
file |
فایل | ✓ | باینری فایل |
مثال curl:
curl -X POST "$API_BASE/api/v1/public/crm-chat/messages/file" \
-F "visitor_token=$VISITOR_TOKEN" \
-F "conversation_id=123" \
-F "caption=مستندات سفارش" \
-F "file=@/path/to/doc.pdf"
مثال ساختار fetch (مرورگر):
const form = new FormData();
form.append("visitor_token", visitorToken);
form.append("conversation_id", String(conversationId));
form.append("caption", "");
form.append("file", fileInput.files[0], fileInput.files[0].name);
const res = await fetch(`${apiBase}/api/v1/public/crm-chat/messages/file`, {
method: "POST",
body: form,
// نگذارید browser Content-Type بزند اگر form را میدهید
});
const json = await res.json();
دانلود فایل (با همان visitor_token)
GET /api/v1/public/crm-chat/conversations/{conversation_id}/files/{file_id}/download
- همان هدر
X-Visitor-TokenیاAuthorization: Bearer([یا قدیم]?visitor_token=). file_idهمانfile.idداخل آبجکتfileدر آیتم پیام است.- پاسخ: باینری فایل با
Content-Disposition: attachment(مثل دانلود معمول)؛ درfetchبهتر است با هدر بگیرید وblobرا ذخیره کنید (نهwindow.openبا query توکن).
شکل پاسخ پیامها (شامل فایل)
هر آیتم پیام (لیست JSON) فیلدهای زیر را دارد (نامها ممکن است در خروجی format تاریخ به رشته تبدیل شوند):
| فیلد | توضیح |
|---|---|
id |
شناسه پیام |
conversation_id |
|
sender_role |
visitor | agent | (در آینده system …) |
body |
متن (برای فایل، معمولاً نام/کپشن) |
user_id |
در پیام عامل اگر مرتبط باشد |
file_storage_id |
اگر ضمیمه دارد، شناسه فایل در storage |
file |
null یا آبجکت: id, original_name, file_size, mime_type |
created_at |
زمان |
رویدادهای WebSocket همان message غنیشده را در payload قرار میدهند (با file در صورت وجود).
کدهای خطا
وقتی success: false (یا HTTP غیر 2xx) بررسی کنید. نمونههای رایج:
کد (در error.code) |
معنی برای یکپارچهساز | اقدام پیشنهادی |
|---|---|---|
CRM_FILE_UPLOAD_DISABLED |
کسبوکار ارسال فایل را در تنظیمات CRM فعال نکرده | به کاربر بگویید «فعلاً ارسال فایل فعال نیست» — در UI دکمهٔ آپلود را مخفی/غیرفعال کنید اگر از API تنظیمات بخوانید |
CRM_FILE_NOT_AVAILABLE |
اغلب: بدون پلن فعال یا پر شدن سهمیه | متن کلی به کاربر؛ مالک باید پلن/فضا را ارتقا دهد (نوتیف داخلی ممکن است برای مالک ارسال شود) |
details.storage_error |
در برخی پاسخها: no_plan یا quota |
اختیاری برای سفارشیسازی UI |
CRM_FILE_TOO_LARGE |
بیش از سقف حجم | پیام راهنما از message |
FORBIDDEN (مثلاً مبدأ) |
Origin دامنهٔ شما در allowed_origins ویجت نیست |
دامنه صحیح در پنل |
NOT_FOUND |
public_key اشتباه، یا توکن/مکالمه نامعتبر |
— |
نکته: دقیق ساختار detail ممکن است مثل بقیه APIهای FastAPI (شیء error داخل detail) باشد — در کلاینت همان پاسخ JSON را console/log کنید تا الگو را ببینید.
WebSocket
- URL:
wss://<host>/ws/crm-chat(یاws://فقط توسعه محلی) - اولین فریم حتماً JSON متنی احراز است.
بازدیدکننده
{
"type": "auth",
"role": "visitor",
"visitor_token": "<token>",
"conversation_id": 123
}
پاسخ موفق: {"type":"auth_ok","role":"visitor","conversation_id":123}
سپس رویدادها با type: "crm_chat.event" و مثلاً event: "message.created".
عامل CRM (مثلاً داشبورد سفارشی شما)
{
"type": "auth",
"role": "agent",
"api_key": "<api_key همان پنل>",
"business_id": 456
}
بعد: {"type":"subscribe","conversation_id": 123} برای هر مکالمه.
API مدیریت (با API Key)
پایه: https://<API_BASE>/api/v1/crm/businesses/{business_id}/chat/...
| متد | مسیر | توضیح | مجوز تقریبی |
|---|---|---|---|
| GET | .../widgets |
لیست ویجتها (شامل public_key) |
crm + view |
| POST | .../widgets |
ساخت ویجت | crm + write |
| PATCH | .../widgets/{id} |
ویرایش (نام، دامنهها، is_active, …) |
crm + write |
| GET | .../crm-settings |
تنظیمات CRM (مثلاً allow_web_chat_file_upload) |
crm + view |
| PATCH | .../crm-settings |
بدنه: {"allow_web_chat_file_upload": true/false} |
crm + write |
| GET | .../conversations |
صندوق مکالمات | crm + view |
| GET | .../conversations/{id}/messages |
لیست پیام (با file غنی) |
crm + view |
| POST | .../conversations/{id}/messages |
پاسخ عامل؛ میتواند body و/یا file_storage_id (پس از آپلود فایل در فضای کسبوکار با module_context=crm_web_chat و context_id = همان conversation_id) |
crm + write |
| PATCH | .../conversations/{id} |
وضعیت، ارجاع، lead_id, person_id |
crm + write |
دانلود فایل از سمت نماینده (واردشده به Hesabix): از API استاندارد فایل کسبوکار مثلاً:
GET /api/v1/business/{business_id}/storage/files/{file_id}/download (با همان احراز و دسترسی به کسبوکار) — الگو در اپ Hesabix استفاده میشود.
اتصال سایت و نمونه کد
وردپرس (ایدهٔ افزونه)
- تنظیمات ادمین (ذخیره امن):
API_BASE،public_key(فیلدهای اختیاری: متن دکمه، رنگ). - فرانت (shortcode / بلوک):
- لود سبک/اسکریپت شما.
- مودال چت: فرم هویت →
start→ نگه داشتنvisitor_tokenدرsessionStorageبا کلیدی وابسته بهpublic_key+page. - لیست پیام + ورودی متن.
- ارسال فایل (اختیاری):
- فقط اگر در تنظیمات CRM (از طریق API
crm-settingsکه در ادمین با transient/cache میکشید) فعال است،input type="file"نشان دهید.
- فقط اگر در تنظیمات CRM (از طریق API
- WebSocket (اختیاری):
new WebSocket(wss + '/ws/crm-chat')سپسauthمرحله WebSocket. - هرگز یوزر/پسورد ادمین Hesabix را در JS عمومی نگذارید — فقط
public_keyبرای مسیرهایpublic/...کافی است.
چکلیست توسعه
- CORS و دامنه تست روی production
- تست
allowed_originsبا دامنه واقعی (بدونhttps://در لیست — فقط hostname) - تگ خطا و UX برای
CRM_FILE_* - اگر WebSocket بسته شد، polling سبک (مثلاً هر ۱۵–۳۰ ثانیه) برای
GET .../messages
CORS و دامنه مجاز
- هدر
Originدرخواست باید با hostnameهای ثبتشده در ویجت (allowed_origins) سازگار باشد. - اگر
allowed_originsخالی باشد، بکاند مبدأ را محدود نمیکند (برای توسعه)؛ در تولید حتماً دامنهها را در پنل محدود کنید.
امنیت و نکات تولید
visitor_tokenرا شبیه session ببینید؛ در URLهای اشتراکی/لاگ تولیدی قرارش ندهید.public_keyرا عمومی میپذیرید (برای شروع مکالمه)؛ اما مدیریت ویجت و دادههای حساس فقط با API Key.- محدودیت نرخ این مسیرها از فایروال مرکزی (جدول
firewall_rate_policiesدر دیتابیس، ارزیابی درinternal_firewall_middleware) اعمال میشود؛ از پنل ادمین APIهایGET/POST/PUT/DELETE .../admin/firewall/rate-policiesقابل مدیریت است. در Nginx استقرار، برای/api/v1/public/crm-chat/عمداًlimit_reqحذف شده تا فقط همین لایه حاکم باشد.
ورکفلو (اتوماسیون داخل Hesabix)
تریگرها برای نود Trigger در ورکفلو Hesabix:
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 است (در صورت ارسال فایل ممکن است file_storage_id نیز در داده مرتبط منطق ثبت شود — نسخه بکاند را در صورت نیاز راستیآزمایی کنید).
پایگاه داده و مایگریشن (برای ادمین/استقرار)
cd hesabixAPI
alembic upgrade head
- جداول/فیلدهای اولیه:
migrations/versions/20260505_000001_crm_chat_embed.py - فایل + تنظیمات CRM کسبوکار:
migrations/versions/20260525_000001_crm_chat_files_settings.py(جدولbusiness_crm_settingsو ستونfile_storage_idرویcrm_chat_messages).
import مدل در migrations/env.py برای Alembic لازم است (در مخزن فعلی اضافه شده است).
عیبیابی
| پدیده | بررسی |
|---|---|
| 403 روی public | CORS؟ Origin و allowed_origins؟ |
404 روی start |
public_key؟ ویجت is_active؟ |
ارسال فایل 403 CRM_FILE_UPLOAD_DISABLED |
تنظیمات CRM در Hesabix |
ارسال فایل 400 CRM_FILE_NOT_AVAILABLE |
پلن/فضای ذخیرهسازی — از پنل کسبوکار بررسی شود |
| WebSocket بسته میشود | پروکسی/timeout؛ fallback به polling |
| فایل در لیست «نیست» | نسخه بکاند/مایگریشن جدید نصب شده؟ GET messages باید file برگرداند |
آخرین بهروزرسانی سند: همراستا با پشتیبانی ارسال فایل، تنظیمات crm-settings و دانلود عمومی فایل ضمیمه.