forked from hesabix/arc
23 KiB
Executable file
23 KiB
Executable file
سناریو جامع: افزودن پیامرسان بله به کانالهای اطلاعرسانی
این سند یک سناریوی کامل و گامبهگام برای افزودن پیامرسان بله به عنوان یک کانال نوتیفیکیشن در سیستم Hesabix است؛ از بخش مدیریت و تنظیمات تا استفاده در نوتیفیکیشنها و کوچکترین نقاط تماس.
۱. نمای کلی معماری فعلی کانالها
در حال حاضر کانالهای اطلاعرسانی به این شکل کار میکنند:
| کانال | Provider (Backend) | تنظیمات سیستم (Admin) | شناسه کاربر (User) | تنظیمات کاربر (فعال/غیرفعال) |
|---|---|---|---|---|
| telegram | TelegramProvider |
telegram_bot_token, webhook, proxy |
users.telegram_chat_id |
user_notification_settings.channel='telegram' |
EmailProvider |
(SMTP/سیستم) | users.email |
همانطور | |
| sms | SmsProvider |
sms_* در system_settings |
users.mobile |
همانطور |
| inapp | InAppProvider |
— | — | همانطور |
برای بله باید همان الگو را تکرار کنیم: Provider، تنظیمات سیستم، فیلد شناسه در User، و تنظیمات per-user.
۲. سناریو به تفکیک لایهها
۲.۱ لایه دیتابیس و مدلها
۲.۱.۱ مدل User
- فایل:
hesabixAPI/adapters/db/models/user.py - تغییرات:
- افزودن فیلد
bale_chat_id: Mapped[int | None](مشابهtelegram_chat_id، نوعBigIntegerدر صورت نیاز API بله). - افزودن فیلد
bale_connected_at: Mapped[datetime | None](اختیاری، برای نمایش زمان اتصال).
- افزودن فیلد
- مایگریشن: یک مایگریشن Alembic برای اضافه کردن این دو ستون به جدول
users.
۲.۱.۲ توکن اتصال بله (مشابه تلگرام)
- جدول جدید (پیشنهاد):
bale_link_tokensبا ساختار مشابهtelegram_link_tokens:id,user_id,token,expires_at,used_at,created_ip,user_agent,created_at
- فایل مدل: مثلاً
hesabixAPI/adapters/db/models/bale.py(یا اضافه کردن به یک فایل integrations). - Repository:
BaleRepositoryبا متدهایcreate_link_token,get_by_token,mark_used(مشابهTelegramRepository).
۲.۱.۳ جداول نوتیفیکیشن (بدون تغییر اساسی)
notification_outbox.channel: مقدار"bale"به مقادیر مجاز اضافه شود (در عمل با ذخیرهchannel='bale'در همان ستون String(32) کار میکند).notification_delivery_attempts.channel: همان.user_notification_settings.channel: مقدار"bale"به مقادیر مجاز اضافه شود.notification_templates(سیستم): در جایی که قالبها بر اساسchannelفیلتر میشوند، مقدار"bale"باید شناخته شود.- قالبهای نوتیفیکیشن کسبوکار (business): در سرویس و API مربوط به قالبهای sms/email، در صورت نیاز آینده به «ارسال از کسبوکار به بله» میتوان کانال
baleرا اضافه کرد (در این سناریو اولیه میتوان فقط نوتیفیکیشن سیستمی را در نظر گرفت).
۲.۲ تنظیمات سیستم (Admin)
۲.۲.۱ Environment و Settings
- فایل:
hesabixAPI/app/core/settings.py - تغییرات: افزودن متغیرهای محیطی (اختیاری، برای override از env):
bale_bot_token: str | None = Nonebale_bot_username: str | None = None(برای ساخت deep link)bale_webhook_secret: str | None = None- در صورت استفاده از پروکسی برای بله:
bale_proxy_enabled,bale_proxy_base_url,bale_proxy_api_key
۲.۲.۲ System Settings Service
- فایل:
hesabixAPI/app/services/system_settings_service.py - ثابتها: تعریف کلیدهایی مثل
NOTIFY_BALE_BOT_TOKEN,NOTIFY_BALE_BOT_USERNAME,NOTIFY_BALE_WEBHOOK_SECRET, و در صورت نیاز پروکسی بله. - تابع
get_notifications_settings(db): خواندن مقادیر این کلیدها از جدولsystem_settingsو برگرداندن در دیکشنری (مثلاًbale_bot_token,bale_bot_username, ...). - تابع
get_effective_notifications_settings(db): ادغام مقادیر DB با env (مشابه تلگرام) و برگرداندن کلیدهای بله در خروجی. - تابع
set_notifications_settings(...): پذیرش پارامترهای اختیاریbale_bot_token,bale_bot_username,bale_webhook_secretو ذخیره در DB.
۲.۲.۳ API ادمین
- فایل:
hesabixAPI/adapters/api/v1/admin/system_settings.py - Payload: در
NotificationsConfigPayloadفیلدهایbale_bot_token,bale_bot_username,bale_webhook_secret(و در صورت نیاز پروکسی بله) اضافه شود. - Endpoint PUT
/notifications: در فراخوانیset_notifications_settingsاین پارامترها پاس داده شوند. - Endpoint GET
/notifications: خروجیget_notifications_settingsاز قبل شامل مقادیر بله میشود اگر در سرویس اضافه شده باشد. - وبهوک بله (اختیاری): در صورت وجود API ثبت webhook در بله، یک endpoint مثل
POST /notifications/bale/webhookبرای ثبت آدرس وبهوک با استفاده ازbale_bot_tokenوbale_webhook_secretاضافه شود.
۲.۳ Provider ارسال پیام (Backend)
۲.۳.۱ BaleProvider
- فایل جدید:
hesabixAPI/app/services/providers/bale_provider.py - الگو: مشابه
TelegramProviderبا توجه به API بله:- متد
__init__(self, *, bot_token=None, proxy_config=None). - متد
is_configured() -> bool. - متد
send_text(chat_id: int, text: str, parse_mode: Optional[str] = None) -> boolکه درخواست را بهhttps://tapi.bale.ai/bot<token>/sendMessage(یا معادل رسمی بله) بفرستد. - در صورت استفاده از پروکسی (مثل تلگرام)، متد کمکی برای ارسال از طریق پروکسی.
- متد
- نکته: مستندات رسمی API بله (مثلاً sendMessage، فرمت chat_id و پاسخ) باید ملاک نهایی باشد.
۲.۳.۲ NotificationService
- فایل:
hesabixAPI/app/services/notification_service.py - در
__init__: خواندنnotify_cfg = get_effective_notifications_settings(db)و ساختself.bale = BaleProvider(bot_token=notify_cfg.get("bale_bot_token"), proxy_config=notify_cfg.get("bale_proxy")). - در متد
send:- در لیست پیشفرض کانالها، اضافه کردن
"bale"در جای مناسب (مثلاً بعد از telegram:["telegram", "bale", "sms", "email", "inapp"]). - بلوک
elif channel == "bale":با منطق مشابه تلگرام:- بررسی
self.bale.is_configured(). - خواندن
bale_chat_idاز user؛ در صورت نبود، outbox را failed با خطایno_bale_chat_idو ادامه به کانال بعد. - رندر قالب با
render_for("bale")و بررسی خالی نبودن body. - فراخوانی
self.bale.send_text(chat_id=..., text=body_bale)و ثبت نتیجه در outbox و_log_attempt.
- بررسی
- در لیست پیشفرض کانالها، اضافه کردن
- در
notify_support_operators: درpreferred_channelsمیتوان"bale"را اضافه کرد (مثلاً["inapp", "email", "telegram", "bale", "sms"]) تا در صورت اتصال اپراتور به بله، از آن کانال هم استفاده شود.
۲.۴ قالبهای نوتیفیکیشن (سیستم)
- Repository قالبها:
NotificationTemplateRepositoryبا متدget(event_key=..., channel=..., locale=...). با ذخیره قالبهایی کهchannel='bale'باشند، بدون تغییر در repository کار میکند. - ادمین قالبها: در
hesabixAPI/adapters/api/v1/admin/notification_templates.py(یا هر جایی که لیست/فیلتر کانال دارد)، مقدار"bale"به انتخابهای کانال اضافه شود تا بتوان برای رویدادهایی مثلauth.otp_login,support.operator_replyو غیره قالب مخصوص بله تعریف کرد. - Seed/داده اولیه: در صورت وجود اسکریپت seed برای قالبهای پیشفرض، یک قالب برای
channel='bale'برای رویدادهای مهم (مثلاًauth.otp_login,system.test) اضافه شود.
۲.۵ API تنظیمات نوتیفیکیشن کاربر و تست
۲.۵.۱ تنظیمات کاربر (فعال/غیرفعال کردن کانال)
- فایل:
hesabixAPI/adapters/api/v1/notifications.py SettingsPayload: فیلدbale_enabled: Optional[bool] = Noneاضافه شود.- GET
/notifications/settings: در دیکشنری پاسخ، مقدارbale_enabledبا منطق مشابه تلگرام (خواندن ازuser_notification_settingsبرایchannel='bale'، پیشفرض True) اضافه شود. - PUT
/notifications/settings: در صورت ارسالpayload.bale_enabled، فراخوانیrepo.upsert(user_id=..., channel="bale", event_key=None, enabled=payload.bale_enabled).
۲.۵.۲ ارسال تست
- Endpoint POST
/notifications/test: پارامترchannelاز Query با الگوی مجاز بهروز شود تاbaleرا هم بپذیرد؛ مثلاًpattern="^(telegram|email|sms|inapp|bale)$".
۲.۶ اتصال/قطع اتصال کاربر به بله (Integrations)
۲.۶.۱ API اتصال بله
- مسیر پیشنهادی:
hesabixAPI/adapters/api/v1/integrations/bale.py(یا زیرمجموعه یک router یکپارچه integrations). - Endpoints (مشابه تلگرام):
- POST
/integrations/bale/link:- بررسی پیکربندی:
get_effective_notifications_settings(db)و وجودbale_bot_token. - ایجاد توکن اتصال با
BaleRepository.create_link_token(TTL مثلاً ۶۰۰ ثانیه). - ساخت deep link به ربات بله با
bale_bot_usernameو token (فرمت deep link بله را از مستندات بگیرید). - برگرداندن
deep_link,link_token,expires_at.
- بررسی پیکربندی:
- GET
/integrations/bale/status:- برگرداندن
linked: boolو در صورت اتصال،chat_idو در صورت وجودbale_connected_at.
- برگرداندن
- DELETE
/integrations/bale/unlink:- صفر کردن
user.bale_chat_idوuser.bale_connected_atو commit.
- صفر کردن
- POST
/integrations/bale/webhook/{secret}(وبهوک بله):- اعتبارسنجی secret و در صورت تمایل header امنیتی.
- پردازش payload بله: تشخیص دستور
/start <token>برای لینک کردن کاربر (خواندن token، پیدا کردنBaleLinkToken، ست کردنuser.bale_chat_idوuser.bale_connected_at، mark_used کردن توکن، ارسال پیام تأیید در بله). - در صورت وجود دستور
/unlinkدر بله، قطع اتصال مشابه تلگرام. - برگرداندن پاسخ مناسب برای API بله.
- POST
۲.۶.۲ ثبت router
- در
hesabixAPI/app/main.py(یا جایی که روترهای v1 شامل میشوند)، روترintegrations/baleبه API اضافه شود.
۲.۷ ورود با OTP و کانالهای موجود
- فایل:
hesabixAPI/app/services/otp_login_service.py get_available_channels:- اگر ربات بله پیکربندی شده باشد و کاربر پیدا شده و
user.bale_chat_idداشته باشد، کانال"bale"بهavailable_channelsاضافه شود (مشابه تلگرام).
- اگر ربات بله پیکربندی شده باشد و کاربر پیدا شده و
send_login_otp:- در شاخه
channel == "bale": بررسی پیکربندی بله و وجودuser.bale_chat_id، سپس ارسال OTP با استفاده ازBaleProvider.send_text(یا از طریق NotificationService باpreferred_channels=["bale"]تا از قالب و outbox یکسان استفاده شود).
- در شاخه
- فایل:
hesabixAPI/adapters/api/v1/auth.py - در پاسخ endpoint ارسال OTP، در
available_channelsوchannel_namesمقدار"bale"و نام نمایشی «بله» اضافه شود. - مدل/Repo OTP: در
otp_login_session.channelو هر جای دیگری که مقدار کانال ذخیره میشود، مقدار"bale"مجاز باشد.
۲.۸ نقاط دیگر Backend که به کانال اشاره میکنند
notification_processor.py: در صورت retry بر اساسoutbox.channel، با اضافه شدن رکوردهایchannel='bale'بهصورت خودکار پردازش میشوند اگر درNotificationService.sendشاخهbaleاضافه شده باشد.- Workflow / Communication actions: در
communication_actions.pyو هر جایی کهpreferred_channelsبه صورت لیست ثابت استفاده میشود (مثلاً برای اپراتورها یا صاحبان کسبوکار)، در صورت تمایل میتوان"bale"را به لیست اضافه کرد. - Support (تیکت، اپراتور): در
adapters/api/v1/support/operator.pyو مشابه، در لیستpreferred_channelsمیتوان"bale"را اضافه کرد. - Business notifications: در
business_notification_service.pyفعلاً کانالهاsmsوemailهستند؛ افزودن بله به نوتیفیکیشن کسبوکار (مثلاً برای مشتری) سناریوی جداگانه است و میتوان در فاز بعد در نظر گرفت (شامل قالبهای کسبوکار برای کانال بله و احتمالاً شناسه بله در پروفایل مشتری/شخص).
۲.۹ UI – مدیریت (ادمین)
۲.۹.۱ تنظیمات نوتیفیکیشن سیستم
- فایل:
hesabixUI/hesabix_ui/lib/pages/profile/notifications_settings_page.dart(همان صفحهای که برای ادمین بخش تلگرام و SMS وجود دارد). - تغییرات:
- در حالت ادمین، یک کارت/بخش «بله» اضافه شود (مشابه کارت تلگرام).
- فیلدهای: توکن ربات بله، نام کاربری ربات (برای لینک)، رمز وبهوک (در صورت نیاز)، و در صورت پشتیبانی، پروکسی بله.
- در
_collectAdvancedPayload(یا معادل) این مقادیر به payload درخواست PUT تنظیمات اضافه شوند. - در بارگذاری اولیه از
getNotificationsConfig، فیلدهای مربوط به بله از پاسخ خوانده و در کنترلرها قرار گیرند.
- سرویس:
hesabixUI/hesabix_ui/lib/services/admin_system_settings_service.dart(یا مشابه): در متد مربوط به دریافت/ارسال تنظیمات نوتیفیکیشن، فیلدهای بله در map درخواست/پاسخ در نظر گرفته شوند.
۲.۱۰ UI – تنظیمات نوتیفیکیشن کاربر (فعال/غیرفعال کانال)
- فایل:
hesabixUI/hesabix_ui/lib/pages/profile/notifications_settings_page.dart - تغییرات:
- یک سوئیچ/کارت «بله» برای فعال/غیرفعال کردن دریافت نوتیفیکیشن از طریق بله (مشابه تلگرام، ایمیل، SMS، InApp).
- متغیرهای state مثل
_baleو در_loadمقدارbale_enabledاز API خوانده شود؛ در_saveمقدارbaleEnabledبهupdateSettingsپاس داده شود.
- سرویس:
hesabixUI/hesabix_ui/lib/services/notifications_service.dart: درgetSettingsوupdateSettingsفیلدهایbale_enabledدر request/response لحاظ شوند. - دکمه «ارسال تست»: برای کانال بله اضافه شود (فراخوانی همان endpoint تست با
channel=bale).
۲.۱۱ UI – اتصال/قطع اتصال اکانت بله (پروفایل کاربر)
- سرویس: ایجاد سرویس مشابه
TelegramIntegrationServiceبرای بله، مثلاًBaleIntegrationServiceبا متدهای:createLink()→ POST/api/v1/integrations/bale/linkgetStatus()→ GET/api/v1/integrations/bale/statusunlink()→ DELETE/api/v1/integrations/bale/unlink
- صفحه پروفایل/نوتیفیکیشن: در جایی که اتصال تلگرام نمایش داده میشود (مثلاً
user_notifications_page.dartیا account_settings)، یک بخش «اتصال بله» اضافه شود:- نمایش وضعیت اتصال (متصل است یا نه، و در صورت تمایل تاریخ اتصال).
- دکمه «اتصال به بله»: درخواست لینک، نمایش deep link / QR برای باز کردن ربات بله با توکن، و polling وضعیت تا زمانی که کاربر در بله /start را بزند و اتصال تأیید شود.
- دکمه «قطع اتصال بله»: فراخوانی unlink و بهروزرسانی وضعیت.
- ترجمهها: در
app_fa.arb,app_en.arbو فایلهای تولید شده، رشتههایی مثل «اتصال بله»، «قطع اتصال بله»، «بله متصل است» و پیامهای خطا/موفقیت اضافه شوند.
۲.۱۲ UI – لیست کانالها در جاهای مختلف
- تاریخچه نوتیفیکیشن: در صفحه تاریخچه، مقدار
channelممکن استbaleباشد؛ نمایش برچسب «بله» برای این رکوردها (مشابه تلگرام، ایمیل، SMS). - ورود با OTP: در صفحه ورود با OTP، اگر API کانال
baleرا درavailable_channelsبرگرداند، گزینه ارسال کد به «بله» نمایش داده شود و درchannel_namesنام «بله» استفاده شود. - ادمین قالبهای نوتیفیکیشن: در فرم/لیست قالبهای سیستمی، در dropdown یا لیست کانالها گزینه «بله» اضافه شود.
۲.۱۳ مستندات و تست
- مستندات API: بهروزرسانی OpenAPI/Swagger برای endpointهای جدید (integrations/bale، تنظیمات بله در admin، و فیلدهای بله در notifications/settings و test).
- تست دستی/اتوماسیون:
- تنظیم توکن ربات بله در ادمین و تست ارسال نوتیفیکیشن تست به کانال بله.
- سناریوی لینک: ایجاد لینک، باز کردن بله و /start ، بررسی بهروزرسانی وضعیت و ارسال نوتیفیکیشن به کاربر از طریق بله.
- ورود با OTP از طریق کانال بله.
- قطع اتصال و اطمینان از عدم ارسال به بله بعد از unlink.
۳. خلاصه فهرست کارها (چکلیست)
| ردیف | لایه | مورد |
|---|---|---|
| 1 | DB | فیلدهای bale_chat_id, bale_connected_at در مدل User و مایگریشن |
| 2 | DB | مدل و جدول bale_link_tokens و BaleRepository |
| 3 | Backend | تنظیمات: Settings، system_settings_service (get/set + effective)، کلیدهای بله در DB |
| 4 | Backend | BaleProvider (ارسال پیام با API بله) |
| 5 | Backend | NotificationService: اضافه کردن بله به کانالها و شاخه ارسال برای channel=bale |
| 6 | Backend | API ادمین: NotificationsConfigPayload و PUT/GET notifications برای بله |
| 7 | Backend | API notifications: SettingsPayload، GET/PUT settings، تست با channel=bale |
| 8 | Backend | API integrations/bale: link, status, unlink, webhook |
| 9 | Backend | OTP login: get_available_channels و send_login_otp برای کانال bale؛ auth API و channel_names |
| 10 | Backend | قالبهای ادمین و seed: پشتیبانی کانال bale و قالبهای پیشفرض |
| 11 | Backend | نقاط دیگر: support، workflow، notification_processor در صورت نیاز |
| 12 | UI | صفحه تنظیمات نوتیفیکیشن ادمین: کارت بله و فیلدها |
| 13 | UI | صفحه تنظیمات نوتیفیکیشن کاربر: سوئیچ بله و ارسال تست |
| 14 | UI | اتصال/قطع بله در پروفایل: سرویس و UI لینک/وضعیت/قطع |
| 15 | UI | تاریخچه و OTP و ادمین قالبها: نمایش/انتخاب کانال بله |
| 16 | l10n | ترجمههای مربوط به بله در arb و تولید شده |
| 17 | مستندات/تست | بهروزرسانی API docs و سناریوهای تست |
۴. نکات تکمیلی
- API بله: پایه API معمولاً روی
https://tapi.bale.aiاست؛ مستندات رسمی بله برای متدهایsendMessage، ساختار webhook و فرمت deep link باید ملاک باشد. - پروکسی: در صورت نیاز به استفاده از پروکسی برای دسترسی به API بله (مشابه تلگرام)، همان الگوی telegram_proxy در تنظیمات و در BaleProvider قابل تکرار است.
- اولویت کانال: در لیست پیشفرض کانالها، قرار دادن بله در کنار تلگرام منطقی است تا کاربران ایرانی بتوانند یکی از این دو (یا هر دو) را انتخاب کنند.
- نوتیفیکیشن کسبوکار: افزودن بله به «نوتیفیکیشن به مشتری/شخص» (مثل قالب فاکتور/تعمیر از نوع sms/email) نیاز به تعریف نحوه نگهداری شناسه بله برای «شخص» دارد و میتوان در فاز دوم انجام شود.
این سناریو تمام لایهها از مدیریت و تنظیمات تا استفاده در ارسال نوتیفیکیشن و کوچکترین بخشهای UI و API را پوشش میدهد و میتوان آن را به صورت تدریجی (مثلاً ابتدا Backend و ادمین، سپس لینک کاربر و OTP، و در آخر بهبودهای UI) پیادهسازی کرد.