Skip to main content

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ì?

Rất quan trọng

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.

FieldTypeRequiredMô tả
user_idnumberID người nhận thông báo
hostnamestringHostname hệ thống gọi (được forward sang Producer)
action_codestringMã hành động dùng để tra cứu notification setting
student_idnumberHọc sinh liên quan (phục vụ Notification Center theo học sinh)
typeNotificationTypePhân loại tab Notification Center (SYSTEM, TO_ME)
pushNotiMobilePushNotiMobilePayload gửi Push Notification Mobile
sendEmailV3SendEmailV3Payload gửi Email
Bắt buộc

Phải có ít nhất một trong hai field sau:

  • pushNotiMobile
  • sendEmailV3

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

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_codeKEY 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
Lưu ý

PHXPushNotificationService chỉ gửi payload.
Việc có gửi hay khônggử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:FACEID
  • BUS_ROUTE:DELAY
  • HRM_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:FACEIDCheck-in bằng FaceID
HRM_CHECKIN:LAMTHEM:DUYETDANGKYDuyệt đăng ký làm thêm
BUS_ROUTE:DELAYXe tuyến đến muộn
FEE:NOTICEThô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 format TEN_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_code trướ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
Lưu ý

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ỗiNguyên nhânCách xử lý
Producer trả về HTTP 400Thiếu field bắt buộc (to, subject, title, previewText, ...)Kiểm tra lại payload theo SendEmailV3
Email không được gửiUser tắt nhận Email theo action_codeKiểm tra notification setting của user
EmailType không đúngTruyền sai emailTypeSử dụng đúng enum EmailType
Thiếu contentemailType = TRANSACTION_BASIC nhưng không truyền contentBổ sung content
Thiếu listRequestsemailType = HRM_REMIND nhưng không truyền listRequestsBổ sung listRequests theo template
Người nhận không nhận được emailSai địa chỉ email hoặc email bị vào spamKiểm tra lại field to, domain, spam box
Email hiển thị sai nội dungContent không đúng format templateChuẩn hoá nội dung theo template email
Gửi email nhưng không thấy notificationaction_code chưa cấu hình notification settingKiểm tra / cấu hình lại action_code