開發者 · 整合功能

讓傳譯跟著聚會,去到每一個角落。

直播用的字幕疊加層、通知你系統的已簽署 Webhooks,以及一套精簡的 REST API。所有方案均已包括,免費試用亦可使用。

01

字幕疊加層

一個透明背景的網頁,顯示單一語言的即時字幕。它像聽眾一樣加入你的房間,但只收字幕——沒有聲音、沒有按鈕、毋須點擊。聚會不在傳譯中時會自動隱藏。

https://acts2.prebabel.ai/overlay/HK7CMN?lang=cmn&style=lower-third&bg=transparent&size=2&lines=2

可在「帳戶 › 整合功能」(或主持人應用程式「設定 › 整合功能」)複製現成網址。

參數可用值預設
lang房間內任何語言,例如 cmn、yue、en,或 orig(講員原聲字幕)cmn
stylelower-third(下三分一,最多 2 行,置中)· full(全螢幕字幕)lower-third
bgtransparent(透明)· black(黑色)transparent
size1 · 2 · 32
lineslower-third 為 1–2,full 為 1–32
scripthans(简)· hant(繁)——只適用於中文按原文

OBS Studio

  1. 來源 › + › 瀏覽器。
  2. 貼上疊加層網址,寬度 1920,高度 1080。
  3. 「自訂 CSS」留空;剔選「場景啟用時重新整理瀏覽器」。
  4. 將來源放在鏡頭畫面之上,背景會保持透明。

ProPresenter

  1. 在 Props 或 Stage 圖層加入 Web Fill(ProPresenter 7.9 或以上),或使用 Media › Web Page。
  2. 貼上疊加層網址,尺寸設為輸出解像度(1920 × 1080)。
  3. 提示螢幕或分場螢幕可用 bg=black 配合 style=full。

亦適用於 vMix(Web Browser 輸入)及 Ecamm Live(Overlay › Web)。

02

Webhooks

聚會開始、暫停、繼續及結束時通知你的系統,並在結束後送上完整講稿。每個機構最多 3 個 https 端點,由管理員在「帳戶 › 整合功能」設定。

事件data
service.started{service_id, source, targets, started_at}
service.paused{service_id, at}
service.resumed{service_id, at}
service.ended{service_id, started_at, ended_at, billable_seconds, peak_listeners, end_reason}
transcript.ready{service_id, languages: {yue: "…", cmn: "…"}}——合併所有定稿字幕,於聚會結束後送出

每個事件都是 JSON 內容 {id, type, created, org_id, data},以 POST 送出:

範例
POST /your/endpoint
content-type: application/json
Acts2-Event-Id: evt_01J9Z6Q4T8
Acts2-Signature: t=1760436000,v1=5f2b…c9e1

{
  "id": "evt_01J9Z6Q4T8",
  "type": "service.ended",
  "created": 1760436000,
  "org_id": "7c1e…",
  "data": {
    "service_id": "b3f0…",
    "started_at": "2026-10-12T02:00:11Z",
    "ended_at": "2026-10-12T03:31:40Z",
    "billable_seconds": 3180,
    "peak_listeners": 128,
    "end_reason": "host"
  }
}
  • 標頭:Acts2-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>、Acts2-Event-Id、content-type: application/json。
  • 任何 2xx 回應即視為送達。逾時 10 秒。失敗會按間隔重試:1 分鐘、5 分鐘、30 分鐘、2 小時、12 小時。
  • 端點必須是公開的 https——localhost 及私人 IP 一律拒絕。
  • 講稿只用來建立 transcript.ready,送出後即刪除(最遲 7 天)。
  • 同一事件可能送達多於一次,請以 id 去重。

驗證簽署

在解析之前以原始內容計算 HMAC,以固定時間比較,並拒絕過舊的時間戳。

Node.js
import crypto from "node:crypto";

// rawBody: the exact request body string (verify before JSON.parse)
export function verifyActs2(rawBody, signatureHeader, secret, toleranceSec = 300) {
  const parts = Object.fromEntries(
    String(signatureHeader).split(",").map((kv) => kv.trim().split("=", 2)),
  );
  const t = Number(parts.t);
  if (!Number.isFinite(t) || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
  const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  const a = Buffer.from(expected, "utf8");
  const b = Buffer.from(String(parts.v1 ?? ""), "utf8");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

// Express: app.post("/acts2", express.raw({ type: "application/json" }), (req, res) => {
//   if (!verifyActs2(req.body.toString("utf8"), req.get("Acts2-Signature"), process.env.ACTS2_WEBHOOK_SECRET))
//     return res.sendStatus(400);
//   const event = JSON.parse(req.body);   // dedupe on event.id (Acts2-Event-Id)
//   res.sendStatus(204);
// });
Python
import hashlib, hmac, time

def verify_acts2(raw_body: bytes, signature_header: str, secret: str, tolerance: int = 300) -> bool:
    try:
        parts = dict(kv.strip().split("=", 1) for kv in signature_header.split(","))
        t = int(parts["t"])
    except (KeyError, ValueError):
        return False
    if abs(time.time() - t) > tolerance:
        return False
    signed = f"{t}.".encode() + raw_body
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts.get("v1", ""))

# Flask:
# @app.post("/acts2")
# def acts2():
#     if not verify_acts2(request.get_data(), request.headers.get("Acts2-Signature", ""), SECRET):
#         abort(400)
#     event = request.get_json()   # dedupe on event["id"]
#     return "", 204
03

REST API

在你自己的工具中讀取機構資料、聚會紀錄及房間即時狀態。

以機構 API 金鑰驗證:Authorization: Bearer acts2_sk_…。管理員在「帳戶 › 整合功能」建立及撤銷金鑰;金鑰只會顯示一次。速率限制:每個金鑰每分鐘 60 次請求。

GET /api/v1/org

機構名稱、房間代碼、聆聽網址、方案、可用時數

curl https://acts2.prebabel.ai/api/v1/org \
  -H "Authorization: Bearer $ACTS2_KEY"

GET /api/v1/services?limit=&before=

聚會紀錄,最新在前

curl "https://acts2.prebabel.ai/api/v1/services?limit=10" \
  -H "Authorization: Bearer $ACTS2_KEY"

GET /api/v1/services/:id

單一聚會

curl https://acts2.prebabel.ai/api/v1/services/SERVICE_ID \
  -H "Authorization: Bearer $ACTS2_KEY"

GET /api/v1/rooms/current

即時狀態、各語言聽眾人數

curl https://acts2.prebabel.ai/api/v1/rooms/current \
  -H "Authorization: Bearer $ACTS2_KEY"

錯誤格式為 {"error": {"code", "message"}},並附相應 HTTP 狀態碼(401 金鑰無效、404 找不到、429 超出速率限制)。

整合上有疑問?請電郵聯絡我們,每封信我們都會細讀。