Bỏ qua, đến nội dung

Cấu hình chi tiết — In-App Message

Database Schema

Thông báo in-app được lưu trong collection messages (quản lý bởi notification-manager):

TrườngKiểuMô tả
idbigint (PK)ID thông báo
userIdbigintID người nhận
titlestringTiêu đề thông báo
contentjsonNội dung chi tiết (hỗ trợ rich content)
readbooleanTrạng thái đã đọc (mặc định: false)
channelNamestringTên kênh đã gửi
createdAtdatetimeThời gian tạo

Cấu trúc content

Trường content là JSON linh hoạt, hỗ trợ nhiều loại nội dung:

json
{
  "text": "Bạn có đơn hàng mới #1234",
  "link": "/orders/1234",
  "metadata": {
    "orderId": 1234,
    "status": "new"
  }
}

Cấu hình SSE

Tham sốGiá trịMô tả
Keepalive interval~30 giâyGửi comment SSE để giữ kết nối
ReconnectTự độngTrình duyệt tự reconnect khi mất kết nối
Event typemessageLoại SSE event mặc định

Cấu hình Nginx cho SSE

Nếu dùng Nginx làm reverse proxy, cần thêm cấu hình cho endpoint SSE:

nginx
location /api/sse {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Connection '';
    proxy_buffering off;
    proxy_cache off;
    proxy_read_timeout 86400s;
    chunked_transfer_encoding off;
}

Quan trọng

Nếu không tắt proxy_buffering, Nginx sẽ buffer SSE response và thông báo không real-time — người dùng phải đợi buffer đầy hoặc timeout mới nhận được.

API Reference

Lấy thông báo chưa đọc

typescript
const response = await api.resource('messages').list({
  filter: {
    userId: currentUserId,
    read: false,
  },
  sort: ['-createdAt'],
  pageSize: 20,
});

Đánh dấu đã đọc (một thông báo)

typescript
await api.resource('messages').update({
  filterByTk: messageId,
  values: { read: true },
});

Đánh dấu tất cả đã đọc

typescript
await api.resource('messages').markAllRead();

Đếm thông báo chưa đọc

typescript
const count = await api.resource('messages').count({
  filter: {
    userId: currentUserId,
    read: false,
  },
});

Thành phần Client

MessageManagerProvider

Context provider quản lý toàn bộ state thông báo, sử dụng immer cho immutable updates:

  • Danh sách thông báo
  • Số lượng chưa đọc
  • SSE connection state
  • Actions: markAsRead, markAllRead, refresh

Desktop Components

ComponentMô tả
InboxPopupPopup dropdown từ bell icon — danh sách thông báo
NotificationBadgeBadge đếm số chưa đọc trên bell icon
MessageItemRender một thông báo trong danh sách

Mobile Components

ComponentMô tả
InboxPageTrang inbox toàn màn hình (antd-mobile)
MobileMessageItemRender thông báo tối ưu cho mobile
MobileBadgeBadge trên tab bar

Tuỳ chỉnh giao diện

Bạn có thể override các component thông qua hệ thống component của Digiforce:

typescript
app.addComponents({
  'NotificationBadge': MyCustomBadge,
  'InboxPopup': MyCustomInbox,
});

Quan hệ với các plugin khác

  • notification-manager: Bắt buộc — cung cấp registry, dispatch, logging
  • mobile: Tuỳ chọn — plugin tự đăng ký mobile route nếu mobile plugin có mặt
  • workflow: Tuỳ chọn — gửi thông báo từ workflow trigger