使用手冊
開發者 SDK 與界接
校務系統、CRM、校友系統、學習系統與 BI 都從這裡接上 Herald。所有入口都是 HTTPS + JSON;TypeScript 用 @hizexai/herald-sdk,其他語言用 OpenAPI 參考 產生 client 或直接呼叫。原始碼與完整界接指南在 GitHub,套件在 npm。
1. 安裝
npm install @hizexai/herald-sdk # Node 22+、Bun、Deno;零依賴
MIT 授權。版本與變更紀錄在 GitHub 的 CHANGELOG.md;問題請開 issue 或寫信 hizexai@gmail.com。
2. 三十行看完
import { HeraldClient, HeraldError } from '@hizexai/herald-sdk';
const herald = new HeraldClient({ baseUrl: 'https://api.example.edu', producerKey: process.env.HERALD_PRODUCER_KEY });
// 代發通知:create → submit → 自動核准檢查,一次做完
const sent = await herald.messages.send(
{
categoryId: 'course_change',
templateId: 'tpl-course-change-1',
variables: { course: '資料結構', change: '教室改為 E302', when: '2026-11-02 09:10' },
audience: { kind: 'individual', uids: ['s1120001'] },
topicId: '01J…', // 主題:收件人可只退訂這個主題
remindAt: '2026-11-01T09:00:00+08:00', // 提醒:回「不用提醒」的人不再收到
},
'cls-chg-20261101-0042', // Idempotency-Key:重送不會發兩次
);
// 校務事件:只說發生了什麼,事件綁定決定發什麼
await herald.sendEvent('academic', { keyId: 'academic-2026', secret: process.env.ACADEMIC_EVENT_SECRET }, {
eventId: 'cls-chg-20261101-0042', type: 'course.changed', subjectUids: ['s1120001'],
data: { course: '演算法', change: '停課一次', when: '2026-11-03' },
});
// CRM / 校友系統同步(行政單位 credential)
await herald.subjects.update('s1120001', { stage: 'alumni', tags: { add: ['cohort:2026', 'interest:ai'] } });
// 戰情室數字給 BI(只有數字)
const metrics = await herald.metrics.executive({ days: 30 });
try { await herald.messages.create({ categoryId: 'x', audience: { kind: 'all' } }, 'k'); }
catch (e) { if (e instanceof HeraldError) console.error(e.status, e.code, e.details); }
| 命名空間 | 方法 | 憑證 |
|---|---|---|
messages | create、dryRun、submit、approve、reject、cancel、get、list、send | producer key 或主控台 session |
topics | list、create、get、update | producer key 或主控台 session |
subjects | bind、unbind、grantConsent、revokeConsent、get、update | 行政單位的 producer key |
metrics | executive、trend | producer key(自己的單位)或 approver session |
sendEvent(source, key, event) | HMAC 簽章事件 | 簽章金鑰(EVENT_SIGNING_KEYS) |
request(method, path, opts) | 其他任何端點 | 同上 |
3. 沒有 TypeScript 的系統
事件簽章在任何語言都是三行:對「unix 秒.raw body」算 HMAC-SHA256。簽的是送出的原始位元組,序列化後不要再動。
import hmac, hashlib, time, json, requests
body = json.dumps(event, separators=(',', ':'), ensure_ascii=False)
ts = str(int(time.time()))
sig = hmac.new(secret.encode(), f"{ts}.{body}".encode(), hashlib.sha256).hexdigest()
requests.post(f"{base}/v1/events/academic", data=body.encode("utf-8"), headers={
"content-type": "application/json",
"x-herald-key-id": key_id, "x-herald-timestamp": ts, "x-herald-signature": f"v1={sig}"})
curl -X POST "$BASE/v1/messages" -H "authorization: Bearer $KEY" -H "idempotency-key: evt-1" \
-H "content-type: application/json" \
-d '{"categoryId":"course_change","templateId":"tpl-course-change-1","variables":{"course":"資料結構","change":"教室改為 E302","when":"2026-11-02 09:10"},"audience":{"kind":"individual","uids":["s1120001"]}}'
curl "$BASE/v1/metrics/executive?unitId=academic" -H "authorization: Bearer $KEY"
4. 界接入口總表
| 入口 | 方向 | 憑證 | 用途 |
|---|---|---|---|
Producer API /v1/messages、/v1/topics、/v1/templates、/v1/groups、/v1/schedules | 你方 → Herald | producer key | 系統代發通知、主題、模板 |
Identity API /v1/subjects/{uid}/…、PATCH /v1/subjects/{uid} | 你方 → Herald | 行政單位 producer key | 綁定/解綁、同意、階段、來源歸因、標籤 |
事件 POST /v1/events/{source} | 你方 → Herald | HMAC | 「發生了什麼」,事件綁定決定分類、模板、受眾 |
| Lookup 端點 | Herald → 你方 | Herald 以同一套 HMAC 簽章呼叫 | 對話中查即時資料(借閱、進度、CRM 欄位) |
Metrics /v1/metrics/executive、/trend | 你方 ← Herald | producer key 或 approver session | BI/CRM 拉戰情室數字 |
報表 GET /v1/messages/{id}、GET /v1/patterns/{id}/report | 你方 ← Herald | producer key 或 session | 單則通知投遞統計、單一活動完成率 |
5. 來源歸因、階段、標籤:三個慣例
- 來源歸因
- 綁定時帶
acquisition: { source, ref },第一次接觸寫一次、之後不覆寫。source:liff、directory、import、event:<source>(加官方帳號好友自動記line_follow);ref是活動、QR 或招生檔期,例如open-day-2026。 - 階段
visitor → lead → member → alumni只前進;PATCH /v1/subjects/{uid}給stage,倒退會被忽略。- 標籤
interest:<主題>(戰情室統計興趣)、source:<ref>、cohort:<年>、alumni:<系所>;ASCII、以冒號分名字空間;受眾查詢的tags直接可用。
- 招生(高中生興趣),招生 QR 進 LIFF 綁定時帶
acquisition,同意範圍用admission,階段lead;問卷答案寫成interest:*標籤。入學後名冊同步升成member,來源保留,漏斗就能依檔期看轉換。 - 校友追蹤,畢業時
PATCH成alumni,加cohort:、alumni:標籤,記alumni同意。校友活動用活動報名 pattern;捐款、雇主、通訊地址留在校友系統。 - CRM,CRM 是名單與商機的 system of record,Herald 是觸達與回應的 system of record。CRM → Herald 走
PATCH /v1/subjects與事件;Herald → CRM 走 metrics 與報表端點;對話中查 CRM 走 Lookup 端點。
6. Lookup 端點契約(你方要實作的)
Herald 以設定好的 URL 呼叫你方:GET 時 query 帶 subject=<Herald subject id> 與指定的對話變數,POST 時 body 為 { subject, …vars };header 帶同一組 X-Herald-Key-Id / X-Herald-Timestamp / X-Herald-Signature,簽的是 query string(GET)或 raw body(POST)。5 秒內回一個 JSON 物件,整個物件成為劇本變數;非 2xx 或逾時走劇本的 error 分支。要對回學號,綁定時保存回傳的 subjectId,或用 GET /v1/subjects/{uid} 反查。
7. 戰情室數字給 BI
GET /v1/metrics/executive?unitId=academic&days=30
GET /v1/metrics/trend?unitId=academic&days=90
executive 回觸達(送出、觸達人數、已讀率、封鎖率)、主題與分類退訂、每則設了提醒的訊息的回應狀態(觸達、已讀、不用提醒、提醒後補送)、轉真人與回話、每個活動的完成率、依來源的漏斗、興趣標籤、校友活躍度;trend 回每晚一個點。每個欄位都是計數或比率,沒有姓名、地址或內文。