Files
ROLAC/docs/NOTIFICATIONS.md
2026-06-23 19:23:22 -07:00

4.7 KiB
Raw Permalink Blame History

ROLAC — 通知系統設計

文件版本: v0.1 (2026-05-24)


通知渠道總覽

渠道 技術 適用場景 狀態
Email SendGrid / SMTP 年度收據、週報、重要公告 Phase 0
Push Notification Capacitor Push 服事提醒、排班更新、活動通知 Phase 1
SMS Twilio 緊急通知、服事前一天提醒 Phase 2
App 內通知 Angular 元件 所有通知的 in-app 備份 Phase 1

各渠道設計

實作狀態 (2026-06-23) Email (SMTP/MailKit) + Line 已於 API 端實作,見 docs/superpowers/specs/2026-06-23-notification-service-email-line-design.md。 本檔早期願景中的 SendGrid/Push/SMS 仍為未來規劃。

Email (SendGrid)

觸發時機

事件 收件人 說明
年度奉獻收據產生 個別教友 含 PDF 附件
歡迎新教友 新教友 帳號啟用信
密碼重設 帳號持有人 OTP / Reset Link
服事排班確認 當週服事同工 每週四自動發送
系統 Build 失敗 admin@rolac.org Jenkins CI 通知

Email 範本要求

  • 雙語(EN / zh-TW),依教友語言偏好發送
  • 教會 Logo header
  • 手機版 Responsive HTML
  • Unsubscribe 連結(行銷類)

Push Notification (Capacitor)

使用 @capacitor/push-notifications
後端使用 Firebase Cloud Messaging (FCM) 作為推播服務(Android + iOS 共用)。

推播事件

事件 時機 內容範例
服事提醒 服事前 2 天 09:00 "您下週日的敬拜服事提醒"
排班更新 立即 "您的服事排班已更新,請查閱"
新消息公告 發佈後立即 "[公告] 復活節特別聚會"
生日祝福 當天 08:00 可選,需教友同意

裝置 Token 管理

UserDevice
├── Id
├── UserId
├── DeviceToken       (FCM token)
├── Platform          (ios | android)
├── AppVersion
├── LastSeenAt
└── IsActive
  • Token 登入時更新,登出時標記 IsActive = false
  • FCM token 失效時(delivery failure)自動清理

SMS (Twilio)

使用時機:輔助通知,非主要渠道

事件 觸發條件 說明
服事前一天提醒 前一天 16:00 確保沒裝 App 的同工也收到
緊急取消通知 手動觸發 主日緊急狀況(天氣、設備)
新教友歡迎 首次建立帳號 可選

教友設定

  • 預設 關閉 SMS,教友自行在個人設定開啟
  • 須明確同意才接收(Opt-in 機制)
  • 每則 SMS 結尾附 "Reply STOP to unsubscribe"

Twilio 設定

// appsettings.json(實際值存環境變數)
"Twilio": {
  "AccountSid": "${TWILIO_ACCOUNT_SID}",
  "AuthToken": "${TWILIO_AUTH_TOKEN}",
  "FromNumber": "${TWILIO_FROM_NUMBER}"   // e.g. +1-xxx-xxx-xxxx
}

費用估算(50100 人教會)

  • 假設 30 人開啟 SMS、每月約 8 次通知
  • 30 人 × 8 次 = 240 SMS/月
  • Twilio 美國 SMS ~$0.0079/則 → 約 $2/月

通知偏好設定(教友端)

教友在 App 個人設定頁面可控制:

通知設定
├── Email 通知
│   ├── ✅ 服事排班(必開,不可關)
│   ├── ✅ 重要公告
│   └── ☐ 活動資訊
├── Push 通知
│   ├── ✅ 服事提醒
│   ├── ✅ 排班更新
│   └── ☐ 生日祝福
└── SMS 通知(預設關閉)
    ├── ☐ 服事前一天提醒
    └── ☐ 緊急通知

後端通知服務架構

// INotificationService 統一介面
public interface INotificationService
{
    Task SendEmailAsync(NotificationRequest request);
    Task SendPushAsync(NotificationRequest request);
    Task SendSmsAsync(NotificationRequest request);
    Task SendAllAsync(NotificationRequest request);  // 依偏好自動選渠道
}

// NotificationRequest
public record NotificationRequest(
    string UserId,
    string TemplateKey,          // e.g. "roster.reminder"
    Dictionary<string, string> Data,
    NotificationChannel[] Channels
);

排程通知(Hangfire 或 Quartz.NET

  • 服事提醒:每週六 09:00 掃描下週服事表,批次發送
  • SMS 提醒:每週六 16:00 補發 SMS(對已開啟 SMS 的教友)
  • 生日提醒:每天 08:00 掃描當天生日教友

通知語言規則

  1. 以教友個人語言偏好為準(Member.LanguagePreference: en | zh-TW
  2. 若未設定,預設英文
  3. 批次發送(如年度收據)依每人偏好分別產生對應語言的郵件