- 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.
4.5 KiB
4.5 KiB
租戶站台介接指引(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.write(Send 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 驗證 Token(JWT / JWKS)
- Send Engine 以 Member Center 的 JWKS 驗簽 access token(JWS)。
- 驗證重點:
iss、aud、scope、tenant_id、exp。 iss:由 Member CenterAuth__Issuer設定(例:http://localhost:7850/)aud:Send 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 必須妥善保管,避免跨租戶濫用