member_center/docs/MESSMAIL.md
warrenchen 4fbf2e5497 feat: Enhance OAuth client management and add one-click unsubscribe functionality
- Updated OpenAPI documentation to include new OAuth2 usage types: `send_api`.
- Added endpoints for issuing one-click unsubscribe tokens in both single and batch requests.
- Modified OAuth client creation and management to enforce new usage types and redirect URI requirements.
- Implemented logic in the Newsletter service to handle one-click unsubscribe token issuance.
- Updated UI to reflect changes in OAuth client usage options and redirect URI handling.
- Enhanced token generation logic to support new scopes and audience settings for Send Engine.
2026-02-25 14:29:26 +09:00

4.5 KiB
Raw Blame History

租戶站台介接指引Member Center + Send Engine

此文件給租戶站台使用,描述如何:

  • 訂閱 / 確認 / 退訂 / 偏好管理Member Center
  • 建立發信任務Send Engine

不包含 Member Center ↔ Send Engine 的內部事件同步細節。


1. 系統流程圖(租戶站台角度)

Tenant Site
  |
  | (1) Subscribe
  v
Member Center
  |
  | (2) Send confirmation email
  v
End User
  |
  | (3) Confirm link
  v
Member Center

Tenant Site
  |
  | (4) Request unsubscribe token
  v
Member Center
  |
  | (5) Unsubscribe with token
  v
Member Center

Tenant Site
  |
  | (6) Create send job
  v
Send Engine
  |
  | (7) Deliver via ESP
  v
End User

2. Auth / Scope租戶站台

租戶站台沒有真人帳號,使用 Client Credentials 取得 access token。

  • 向 Member Center 申請 OAuth Client
  • OAuth Client 建議使用 usage=send_api(專供發送);tenant_api 留給其他租戶 API
  • scope 依用途最小化

建議 scopes

  • newsletter:send.writeSend Engine 建立發信任務)
  • newsletter:send.read(查詢發信狀態,若需要)

Send Engine 會驗證 token 內的 tenant_id 與 scope。

取得 Token範例

curl -s -X POST https://{member-center}/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=<CLIENT_ID>&client_secret=<CLIENT_SECRET>&scope=newsletter:send.write"

使用 Token範例

curl -s -X POST https://{send-engine}/api/send-jobs \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{ \"tenant_id\": \"<TENANT_ID>\", \"list_id\": \"<LIST_ID>\", \"subject\": \"Weekly\", \"body_text\": \"Hello\" }'

Send Engine 驗證 TokenJWT / JWKS

  • Send Engine 以 Member Center 的 JWKS 驗簽 access tokenJWS
  • 驗證重點:issaudscopetenant_idexp
  • iss:由 Member Center Auth__Issuer 設定(例:http://localhost:7850/
  • audSend Engine 流程預設 send_engine_api(可用 Auth__SendEngineAudience 覆寫)

3. API 表格(租戶站台 → Member Center

功能 Method Path 必填 說明
訂閱 POST /newsletter/subscribe list_id, email 回傳 confirm_token
確認訂閱 GET /newsletter/confirm token double opt-in 確認
申請退訂 token POST /newsletter/unsubscribe-token list_id, email 回傳 unsubscribe_token
退訂 POST /newsletter/unsubscribe token 單一清單退訂
讀取偏好 GET /newsletter/preferences list_id, email 需 list_id + email
更新偏好 POST /newsletter/preferences list_id, email, preferences 需 list_id + email

訂閱(範例)

curl -s -X POST https://{member-center}/newsletter/subscribe \
  -H "Content-Type: application/json" \
  -d '{
    "list_id": "<LIST_ID>",
    "email": "user@example.com",
    "preferences": {"lang": "zh-TW"}
  }'

申請退訂 token範例

curl -s -X POST https://{member-center}/newsletter/unsubscribe-token \
  -H "Content-Type: application/json" \
  -d '{
    "list_id": "<LIST_ID>",
    "email": "user@example.com"
  }'

退訂(範例)

curl -s -X POST https://{member-center}/newsletter/unsubscribe \
  -H "Content-Type: application/json" \
  -d '{
    "token": "<UNSUBSCRIBE_TOKEN>"
  }'

4. API 表格(租戶站台 → Send Engine

功能 Method Path 必填 說明
建立發信任務 POST /api/send-jobs list_id, subject, body_html/body_text 發送排程
查詢發信任務 GET /api/send-jobs/{id} id 讀取狀態
取消發信任務 POST /api/send-jobs/{id}/cancel id 取消發送

建立發信任務(範例)

curl -s -X POST https://{send-engine}/api/send-jobs \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant_id": "<TENANT_ID>",
    "list_id": "<LIST_ID>",
    "name": "Weekly Update",
    "subject": "Weekly Update",
    "body_html": "<p>Hello</p>",
    "body_text": "Hello",
    "scheduled_at": "2026-02-11T02:00:00Z"
  }'

5. 安全注意事項(租戶站台)

  • list_id + email 為租戶隔離最小邊界,必須一併提供
  • 不要保存退訂 token使用時再向 Member Center 申請
  • Token 必須妥善保管,避免跨租戶濫用