PHXPushNotificationService
1. Tác dụng & phạm vi
PHXPushNotificationService là service thuộc PHX-Node, dùng để gửi In-app Notification (Noti Mobile / Email) thông qua Producer API.
Service này làm gì?
- Nhận payload từ hệ thống gọi
- Gửi payload tới Producer
- Không xử lý logic bật / tắt thông báo
Service này KHÔNG làm gì?
Service KHÔNG quyết định:
- Có gửi thông báo hay không
- Gửi qua Noti Mobile hay Email
Những quyết định này do Producer / Consumer xử lý dựa trên action_code. Mặc định là sẽ gửi tất cả các kênh thông báo
2. Tổng quan luồng xử lý
sequenceDiagram
participant Service
participant Producer
participant Consumer
Service->>Producer: send(payload)
Producer->>Producer: Tra cứu setting theo action_code
Producer->>Consumer: Emit event
Consumer->>Consumer: Noti Mobile / Email
Consumer->>Consumer: Lưu Notification Record
3. Cách sử dụng trong NestJS
import { PHXPushNotificationService } from "phx-node";
@Injectable()
export class ExampleService {
constructor(
private readonly phxPushNotificationService: PHXPushNotificationService
) {}
async notify(payload) {
await this.phxPushNotificationService.send(payload);
}
}
4. API
4.1 send(payload)
Phương thức dùng để gửi In-app Notification (Noti Mobile / Email) lên Producer.
send(payload: PushInappNoti): Promise<{
status: string;
message: string;
}>
Mô tả Nhận payload theo chuẩn PushInappNoti Gửi payload tới Producer endpoint /emit/inapp-noti Không kiểm tra logic bật / tắt notification Trả về kết quả xử lý từ Producer
5. Payload cần truyền vào (BẮT BUỘC ĐỌC)
Phần này mô tả toàn bộ dữ liệu cần truyền vào khi gọi
PHXPushNotificationService.send(payload).
5.1 PushInappNoti – Root Payload
Đây là payload gốc, bắt buộc phải truyền.
| Field | Type | Required | Mô tả |
|---|---|---|---|
user_id | number | ✅ | ID người nhận thông báo |
hostname | string | ✅ | Hostname hệ thống gọi (được forward sang Producer) |
action_code | string | ✅ | Mã hành động dùng để tra cứu notification setting |
student_id | number | ❌ | Học sinh liên quan (phục vụ Notification Center theo học sinh) |
type | NotificationType | ❌ | Phân loại tab Notification Center (SYSTEM, TO_ME) |
pushNotiMobile | PushNotiMobile | ❌ | Payload gửi Push Notification Mobile |
sendEmailV3 | SendEmailV3 | ❌ | Payload gửi Email |
Phải có ít nhất một trong hai field sau:
pushNotiMobilesendEmailV3
5.2 Nguyên tắc xử lý Payload
- Có thể gửi Push Mobile, Email, hoặc cả hai trong cùng một payload
- Service không kiểm tra user có bật thông báo hay không
- Producer sẽ:
- Tra cứu setting theo
action_code - Quyết định kênh gửi (Noti Mobile / Email)
- Từ chối gửi nếu user tắt thông báo
- Tra cứu setting theo
5.3 Ví dụ payload tối thiểu
Ví dụ: Gửi Push Noti Mobile tối thiểu
{
user_id: 8652,
hostname: "portal.phx.vn",
action_code: "HRM_CHECKIN:FACEID",
pushNotiMobile: {
title: "Check-in",
message: "Bé đã tới trường",
module_code: "HRM_CHECKIN",
app: "PHX_PARENT",
payload: {
action: "OPEN_CHECK_IN_PAGE"
}
}
}
6. NotificationType
NotificationType dùng để phân loại thông báo khi hiển thị trong Notification Center của người dùng.
Việc phân loại đúng giúp:
- Notification hiển thị đúng tab
- Dễ lọc, dễ quản lý
- Thống nhất hành vi hiển thị giữa các màn hình
6.1 Định nghĩa
export enum NotificationType {
SYSTEM = "SYSTEM",
TO_ME = "TO_ME",
}
7. action_code – Quy tắc & ý nghĩa (RẤT QUAN TRỌNG)
action_code là KEY DUY NHẤT để Producer/Consumer xác định:
- User có bật nhận thông báo không
- User nhận thông báo qua kênh nào (Noti Mobile / Email)
- Thông báo thuộc nhóm nghiệp vụ nào để mapping cấu hình
PHXPushNotificationService chỉ gửi payload.
Việc có gửi hay không và gửi qua Noti Mobile/Email phụ thuộc vào cấu hình notification setting theo action_code.
7.1 Cú pháp chuẩn
Cấp cơ bản (khuyến nghị) TEN_PHAN_HE:CHUC_NANG
Cấp chi tiết (khi cần phân nhánh theo chức năng con) TEN_PHAN_HE:CHUC_NANG:CHUC_NANG_CON
Mục tiêu của phân cấp là để cấu hình setting rõ ràng theo nhóm nghiệp vụ, tránh mơ hồ.
7.2 Quy ước bắt buộc
- VIẾT HOA (UPPERCASE)
- KHÔNG DẤU
- KHÔNG KHOẢNG TRẮNG
- Phân cấp bằng dấu
: - Không dùng ký tự đặc biệt ngoài
_(nếu cần tách từ)
✅ Ví dụ hợp lệ:
HRM_CHECKIN:FACEIDBUS_ROUTE:DELAYHRM_CHECKIN:LAMTHEM:DUYETDANGKY
❌ Ví dụ không hợp lệ:
hrm_checkin:faceid(không viết hoa)HRM CHECKIN:FACEID(có khoảng trắng)HRM_CHECKIN-FACEID(sai ký tự phân cấp)
7.3 Ví dụ action_code theo nghiệp vụ
| action_code | Ý nghĩa |
|---|---|
HRM_CHECKIN:FACEID | Check-in bằng FaceID |
HRM_CHECKIN:LAMTHEM:DUYETDANGKY | Duyệt đăng ký làm thêm |
BUS_ROUTE:DELAY | Xe tuyến đến muộn |
FEE:NOTICE | Thông báo học phí |
7.4 Best Practices khi đặt action_code
- 1 nghiệp vụ = 1 action_code (tránh reuse cho nghiệp vụ khác)
- Đặt tên theo phân hệ/module_code để dễ quản lý
- Nếu nghiệp vụ có nhiều nhánh (approve/reject/remind...) → dùng cấp 3:
TEN_PHAN_HE:CHUC_NANG:NHANH_XU_LY
- Tránh đặt quá dài hoặc quá chung chung
7.5 Checklist trước khi dùng action_code
-
action_codeđã đúng formatTEN_PHAN_HE:CHUC_NANG(:CHUC_NANG_CON)? - Đã viết HOA, không dấu, không khoảng trắng
- Đã có cấu hình notification setting tương ứng trên hệ thống Producer
- Không trùng / không reuse cho nghiệp vụ khác
- Nếu gửi Noti Mobile/Email không tới: kiểm tra setting theo
action_codetrước
7.6 Ví dụ dùng action_code trong payload
await phxPushNotificationService.send({
user_id: 8652,
hostname: "portal.phx.vn",
action_code: "HRM_CHECKIN:FACEID",
type: NotificationType.TO_ME,
pushNotiMobile: {
title: "Check-in",
message: "Bé đã tới trường",
module_code: "HRM_CHECKIN",
app: "PHX_PARENT",
payload: {
action: "OPEN_CHECK_IN_PAGE",
},
},
});
8. Push Notification Mobile
Phần này mô tả cách gửi Push Notification cho Mobile App thông qua PHXPushNotificationService.
Push Mobile thường dùng cho:
- Thông báo realtime
- Điều hướng người dùng tới màn hình cụ thể
- Các nghiệp vụ cần user phản hồi nhanh
8.1 PushNotiMobile
export interface PushNotiMobile {
title: string; // Tiêu đề hiển thị trên Push Notification
message: string; // Nội dung hiển thị trên Push Notification
module_code: string; // Mã phân hệ / module nghiệp vụ
app: string; // App nhận Push (VD: PARENT, TEACHER, ...)
payload: any; // Payload gửi xuống Mobile để điều hướng
}
9. Gửi Email (SendEmailV3)
Phần này mô tả cách gửi Email thông qua PHXPushNotificationService bằng field sendEmailV3.
Email thường dùng cho:
- Thông báo giao dịch (transaction)
- Nội dung dài, có format, cần lưu lại
- Nhắc nhở/nhóm yêu cầu (remind) theo template
Service chỉ đẩy payload lên Producer.
Việc Email có được gửi hay không vẫn phụ thuộc vào notification setting theo action_code.
9.1 SendEmailV3
export enum EmailType {
TRANSACTION_BASIC = "transaction-basic",
HRM_REMIND = "hrm-remind",
}
export interface SendEmailV3 {
emailType: EmailType; // Loại template email sử dụng
to: string; // Email người nhận
subject: string; // Subject của email
title: string; // Tiêu đề hiển thị trong body/template
previewText: string; // Đoạn preview (hiển thị ở inbox)
content?: string; // Nội dung email dạng text/html (tuỳ template)
listRequests?: IGroupRequestType[]; // Danh sách request (dùng cho template remind)
description?: string; // Mô tả bổ sung (tuỳ template)
}
9.2 Ví dụ gửi Email (TRANSACTION_BASIC)
await phxPushNotificationService.send({
user_id: 8652,
hostname: "portal.phx.vn",
action_code: "FEE:NOTICE",
type: NotificationType.TO_ME,
sendEmailV3: {
emailType: EmailType.TRANSACTION_BASIC,
to: "parent@example.com",
subject: "Thông báo học phí",
title: "Thông báo học phí",
previewText: "Nhà trường xin thông báo...",
content: "Nội dung chi tiết...",
},
});
9.3 Gửi đồng thời Push + Email trong 1 lần gọi
await phxPushNotificationService.send({
user_id: 8652,
hostname: "portal.phx.vn",
action_code: "FEE:NOTICE",
type: NotificationType.TO_ME,
pushNotiMobile: {
title: "Thông báo học phí",
message: "Bạn có thông báo học phí mới",
module_code: "FEE",
app: "PHX_PARENT",
payload: {
action: "OPEN_FEE_NOTICE",
type: "IMPORTANT",
},
},
sendEmailV3: {
emailType: EmailType.TRANSACTION_BASIC,
to: "parent@example.com",
subject: "Thông báo học phí",
title: "Thông báo học phí",
previewText: "Nhà trường xin thông báo...",
content: "Nội dung chi tiết...",
},
});
9.8 Lỗi thường gặp khi gửi Email
| Lỗi | Nguyên nhân | Cách xử lý |
|---|---|---|
| Producer trả về HTTP 400 | Thiếu field bắt buộc (to, subject, title, previewText, ...) | Kiểm tra lại payload theo SendEmailV3 |
| Email không được gửi | User tắt nhận Email theo action_code | Kiểm tra notification setting của user |
| EmailType không đúng | Truyền sai emailType | Sử dụng đúng enum EmailType |
Thiếu content | emailType = TRANSACTION_BASIC nhưng không truyền content | Bổ sung content |
Thiếu listRequests | emailType = HRM_REMIND nhưng không truyền listRequests | Bổ sung listRequests theo template |
| Người nhận không nhận được email | Sai địa chỉ email hoặc email bị vào spam | Kiểm tra lại field to, domain, spam box |
| Email hiển thị sai nội dung | Content không đúng format template | Chuẩn hoá nội dung theo template email |
| Gửi email nhưng không thấy notification | action_code chưa cấu hình notification setting | Kiểm tra / cấu hình lại action_code |