Communication — Luồng xử lý trong code
Ánh xạ pipeline gửi tới worker & file trong Tux.
Các worker
| Worker | Vai trò |
|---|---|
Tux.Workers.Notification.Scheduler | Quét NotificationScheduler (và MessagingJob) Ready; đánh giá Notification Settings; đẩy việc sang Generator. |
Tux.Workers.Notification.Generator | Render template, resolve recipients; sinh UserMessage và/hoặc OutgoingMessage. |
Tux.Workers.Notification.Distributor | "Claim" rồi gửi thật qua provider (SendGrid/Twilio). |
| Webhook & Tracker | Nhận callback provider, cập nhật trạng thái OutgoingMessage. |
Worker Automation Scheduler | Quét AutomationScheduler (reminder/report), đẩy việc giao hàng sang NotificationScheduler. |
Generator: route theo loại notification
Generator dựa trên loại để chọn handler render. Ví dụ các handler id-only (đọc EventData là entity id):
// Trong Generator
var id = JsonConvert.DeserializeObject<int>((string)job.EventData);
// route: IncidentSubmitted -> HandleNotificationAsync -> HandleIncidentSubmittedAsync
// -> NotificationService.SendIncidentSubmittedNotification(...)Một số handler mẫu: HandleAccountNewRegistration_EmployeeAsync, HandleStaffProfileUpdateAsync, HandleIncidentSubmittedAsync. Mỗi handler resolve recipients (từ NotificationSetting subscribers + dữ liệu trong job), render template, sinh OutgoingMessage.
Distributor: claim trước khi gửi
// Pseudo: cập nhật có điều kiện
// UPDATE OutgoingMessage SET Status = Sending
// WHERE PartitionKey=@pk AND RowKey=@rk AND Status IN (Created, RetryReady)
// Nếu 0 dòng bị đổi → tin đã/đang gửi → thoát, KHÔNG gọi providerSau khi gửi thành công → SentToProvider + lưu provider message id. Webhook đẩy tiếp tới Delivered/Opened.
Campaign
MessagingJob (SQL) điều phối payload campaign/report; MessageJobBlobName trỏ vào container messaging-job (chỉ tên/đường dẫn — API authorize trước khi lộ nội dung). Worker Notification Scheduler query cả NotificationScheduler và MessagingJob. Retry tái dùng blob payload tương thích; payload không tương thích → dừng gửi.
UserMessage (in-app)
Generator sinh UserMessage khi template yêu cầu hiển thị trong app. Khóa:
Customer: PartitionKey = user:{User.Id}
Staff: PartitionKey = employee:{Employee.Guid}
RowKey = {SourceReverseTicks}_{NotificationJob.RowKey}SourceReverseTicks từ timestamp nguồn ổn định (cơ sở tạo/schedule của NotificationJob), không từ write-time — nếu không, Generator retry tạo dòng trùng. Hộp thư phụ huynh gộp theo partition người nhận.
Notification Settings điều khiển gì
Bước Scheduler đọc cấu hình theo BU:
NotificationOption— danh mục loại notification (phải seed loại mới vào đây).NotificationSetting— bật/tắt + subscriber theo từng BU.
Loại chưa seed hoặc không có subscriber → handler skip gracefully (không gửi).
DeliveryDispatchResult
Kết quả mỗi lần dispatch lưu ở AutomationScheduler.DispatchResultJson: delivery path + tọa độ (notification/scheduler/messaging-job/user-message/outgoing-message) + SkippedReasonCode/ConflictReasonCode/Summary. Nhỏ gọn, merge khi retry, không bao giờ bị xóa.
Test trọng yếu
- Direct reminder retry → một
NotificationJob; Generator retry → mộtOutgoingMessageper recipient/method; tin Distributor trùng → không gọi provider lần hai. - UI-only reminder →
UserMessage, khôngOutgoingMessage; UserMessage retry với source ticks ổn định → một dòng. - Scheduler thiếu được tạo lại qua dispatch guard; hash không khớp → dừng gửi.
- Storage adapters giữ nguyên khóa do caller cấp.
- Report/campaign retry tái dùng
MessagingJob + Blobtương thích.
Tiếp theo: Case thường gặp.