00:00 / 00:00

LAPLACE Chat

LAPLACE Event Bridge

Monorepo 結構

本儲存庫包含多個套件:

  • 伺服器(Go)packages/server):WebSocket 橋接的獨立 Go 實作(推薦)
  • 伺服器(Bun,已棄用)packages/server-bun):最初的 Bun/Node.js 實作,僅供參考保留
  • SDKpackages/sdk):用於連線至橋接服務的 TypeScript/JavaScript 用戶端
  • 範例examples/):SDK 的使用範例

功能特色

  • 以角色為基礎的連線系統(伺服器/用戶端)
  • 伺服器向用戶端廣播訊息
  • SDK 可作為用戶端接收事件,或以伺服器角色產生事件
  • 以權杖為基礎的身分驗證
  • 支援斷線重連

環境需求

  • Bun v1.2.0 或更高版本(管理 monorepo 以及執行 SDK / Bun 伺服器時必需)
  • Go 1.23.0 或更高版本(僅從原始碼建置或執行 Go 伺服器時需要;專案會選擇 Go 1.24.2 工具鏈)

安裝

您可以透過以下幾種方式執行伺服器:

  • 預先編譯的二進位檔(對非技術使用者最簡單)
  • Go 伺服器(易於部署,推薦)
  • laplace-event-fetcher 橋接模式(追求穩定性時推薦)
  • Bun 伺服器(已棄用,僅供參考)
  • 原始碼(適合進階使用者與開發者)

預先編譯的二進位檔

如果您不熟悉程式設計或命令列工具,執行 LAPLACE Event Bridge 伺服器最簡單的方式,是從我們的 GitHub Releases 下載預先編譯的二進位檔:

  1. 下載伺服器

    • 前往 GitHub Releases 頁面
    • 找到名稱中帶有 @laplace.live/event-bridge-server 的最新版本
    • 下載與您作業系統對應的檔案:
      • Windowsleb-server-windows-x64.exe
      • macOSleb-server-darwin-arm64
      • Linux(x64)leb-server-linux-x64
      • Linux(arm64)leb-server-linux-arm64
  2. 賦予執行權限(僅 macOS/Linux)

    • 開啟終端機
    • 進入下載資料夾:cd ~/Downloads
    • 執行:chmod +x leb-server-*(將 * 換成實際的檔案名稱)
  3. 執行伺服器

    • Windows:連按兩下 .exe
    • macOS:在終端機中執行 ./leb-server-darwin-arm64
    • Linux:在終端機中執行 ./leb-server-linux-x64(依需求將 x64 換成 arm64

伺服器會啟動,並在可以接受連線時輸出一則提示訊息

橋接伺服器(Go)

建議使用的橋接伺服器現在是位於 packages/server 的單一二進位 Go 應用程式。建置或執行它需要 Bun,只需要 Go 工具鏈

完整文件見 packages/server/README.md,快速上手如下:

# Enter the Go module and run from source
cd packages/server
go run . --debug

# Or build a native binary
go build -o leb-server .
./leb-server --host 0.0.0.0 --auth "your-secure-token"

伺服器預設監聽 http://localhost:9696

Event Fetcher 橋接模式

在最新版 laplace-event-fetcher(v2.2.0 及以上)中,您可以啟用 WebSocket 橋接模式,讓 event fetcher 兼作橋接伺服器,以獲得更好的穩定性。使用此模式時無須讓 LAPLACE Chat 控制台保持執行,它會替您同時擔任 event fetcher 與橋接伺服器

橋接伺服器(Bun,已棄用)

最初的 Bun/Node.js 實作位於 packages/server-bun。它與 Go 版功能等價,但出於效能與部署便利性已由 Go 版取代。我們仍會為依賴它的使用者繼續提供

# Start the Bun server
bun run --cwd packages/server-bun start --debug --auth "your-secure-token"

伺服器比較

特性橋接伺服器(Go)Event Fetcher 橋接模式
安裝單一二進位檔或 Go 工具鏈需要 LAPLACE Event Fetcher v2.2.0+
環境本機(獨立二進位檔)容器
部署簡單 - 單一檔案部署需要有伺服器持續執行
事件來源LAPLACE Chat 控制台或 SDK 伺服器角色Event Fetcher 內建
重複使用本機連線
設定命令列參數Event fetcher 設定
穩定性取決於您的本機網路更穩定
適用情境個人專案整合、小規模使用針對 MCN 機構的正式環境大規模部署,或已在使用 event fetcher 的使用者

LLM 提示詞

把下面的提示詞貼給你的 AI 助理,或者存進專案的 CLAUDE.mdAGENTS.md 這類規則檔案,它就有了替你撰寫整合所需的全部背景。提示詞以英文寫成,方便各家模型理解;裡面引用的文件網址都可以直接抓取

You are helping me build an integration on top of LAPLACE Event Bridge, the WebSocket
bridge that relays real-time Bilibili live events — chat messages, gifts, super chats,
guard purchases, stream state — from LAPLACE Chat (https://chat.laplace.live) to local
clients.

Before writing any code, fetch the reference documents listed at the end — they are
the single source of truth for event types, payload fields and the client API. Do
not rely on memory and do not invent names.

## Setup

- Install `@laplace.live/event-bridge-sdk`. It runs anywhere with `WebSocket` and
  `fetch` globals: Node.js 22+, Bun and browsers. Event payload interfaces live in
  its dependency `@laplace.live/event-types`.
- A bridge server must be running: either the `leb-server` binary fed by LAPLACE Chat
  or an SDK v1.2.0+ producer using `role: 'server'`, or LAPLACE Event Fetcher v2.2.0+
  in bridge mode (standalone). Default endpoint: `ws://localhost:9696`.
- Auth is optional: when the server was started with `--auth`, pass the same string
  as `token`.

## Client

```ts
import { LaplaceEventBridgeClient } from "@laplace.live/event-bridge-sdk";

const bridge = new LaplaceEventBridgeClient({
  url: "ws://localhost:9696", // default
  token: "your-auth-token", // only when the server enables auth
});

bridge.on("message", (event) => {
  console.log(`${event.username}: ${event.message}`); // typed as Message
});
const offAny = bridge.onAny((event) => console.log(event.type, event.origin));

await bridge.connect();
// later: offAny(); bridge.disconnect();
```

## Producer (Server Role)

SDK v1.2.0+ can instead occupy the event-producing server role. This connects to
a running standalone Event Bridge server; it does not start the bridge server itself.

```ts
const producer = new LaplaceEventBridgeClient({
  url: "ws://localhost:9696",
  token: "your-auth-token",
  role: "server",
});

await producer.connect();
producer.send(event); // event must be a LaplaceEvent
```

Only server-role messages are broadcast. A client-role `send()` is acknowledged by
the bridge but is not relayed to other connections.

The bridge is one-way — servers broadcast, clients listen — and reconnection is
automatic. Handlers are typed from the event name. Every event carries `type`, `id`
and `origin` (the canonical room id — filter on it when one bridge serves several
rooms). The exact event names, payload fields and the rest of the client API live in
the reference below — look them up instead of guessing.

## Reference

Fetch these before writing code:

- https://laplace.live/chat/event-bridge.en.mdx — this page as raw Markdown: server
  setup, SDK client and producer roles, connection state, room discovery
- https://chat.laplace.live/event-types/ — every event type and payload field
- https://github.com/laplace-live/event-bridge — server and SDK source with runnable
  examples

SDK

SDK 提供了用於連線至 event bridge 的型別安全用戶端;它既能接收事件,也能以伺服器角色產生事件

安裝

npm install @laplace.live/event-bridge-sdk

用法

import { LaplaceEventBridgeClient } from "@laplace.live/event-bridge-sdk";

const client = new LaplaceEventBridgeClient({
  url: "ws://localhost:9696",
  token: "your-auth-token", // If auth is enabled
});

// Connect to the bridge
await client.connect();

// Listen for specific events
client.on("message", (event) => {
  console.log("Received message:", event);
});

// Listen for all events
client.onAny((event) => {
  console.log("Received event:", event.type);
});

連線選項

LaplaceEventBridgeClient 接受以下連線選項,所有選項皆可省略:

Prop

Type

伺服器角色

SDK v1.2.0 起也可以作為事件產生端連線。設定 role: 'server' 後,send() 傳送的 LaplaceEvent 會由橋接服務廣播給所有用戶端:

import { LaplaceEventBridgeClient } from "@laplace.live/event-bridge-sdk";

const producer = new LaplaceEventBridgeClient({
  url: "ws://localhost:9696",
  token: "your-auth-token",
  role: "server",
});

await producer.connect();

function broadcast(event: Parameters<typeof producer.send>[0]) {
  producer.send(event);
}

這裡的伺服器角色是連線至正在執行的獨立 Event Bridge 伺服器的事件產生端,並不會啟動橋接服務本身。預設的 client 角色用於接收事件;它呼叫 send() 時,訊息只會收到確認,不會轉送給其他連線。Event Fetcher 橋接模式會在內部自行產生事件,並忽略心跳 pong 以外的傳入訊息,因此無法轉送 SDK 產生端的訊息

連線狀態

onConnectionStateChange() 會在註冊時立即以目前狀態呼叫一次處理函式,此時 detail 可能為 undefined。後續狀態變更會在可用時提供斷線原因與目前的重新連線次數:

client.onConnectionStateChange((state, detail) => {
  console.log(state, detail?.reconnectAttempts);

  if (detail?.closeEvent) {
    console.log(detail.closeEvent.code, detail.closeEvent.reason);
  }
});

console.log(client.getReconnectAttempts());

getReconnectAttempts() 會回傳目前中斷期間已進行的重新連線次數;連線正常或閒置時為 0

Prop

Type

直播間探索

當伺服器是執行在橋接模式下的 LAPLACE Event Fetcher 時,它會提供一個 /info HTTP 端點,列出已設定的直播間。SDK 無須建立 WebSocket 連線即可取得它——適合讓使用者自行挑選要接收哪些直播間

使用 client.getInfo() 方法(重複使用用戶端的 url / token):

const client = new LaplaceEventBridgeClient({
  url: "ws://localhost:9696",
  token,
});

const info = await client.getInfo();
if (info) {
  console.log(`Fetcher v${info.version} exposes ${info.rooms.length} room(s)`);
  for (const room of info.rooms) {
    console.log(`${room.roomId}: ${room.username ?? "unknown"}`);
  }
} else {
  // Plain Event Bridge server or an older fetcher — fall back to manual entry.
}

也可以使用獨立的 fetchInfo() 函式,它不需要用戶端物件:

import { fetchInfo } from "@laplace.live/event-bridge-sdk";

const info = await fetchInfo({ url: "ws://localhost:9696", token, signal });

/info 無法使用時——舊版 fetcher、一般的 Event Bridge 伺服器、請求被中止,或任何網路/解析錯誤——兩者都會解析為 null(而不會擲出例外),因此呼叫端可以靜默回退到手動輸入直播間

回傳的型別是 FetcherInfoFetcherRoom,兩者皆由 SDK 匯出:

import type { FetcherInfo, FetcherRoom } from "@laplace.live/event-bridge-sdk";

interface FetcherRoom {
  status: number; // 0 when resolved, otherwise an error code (e.g. 404)
  uid: number;
  roomId: number; // Canonical room id; matches the `origin` field on incoming events
  shortRoomId: number;
  username: string | null;
}

interface FetcherInfo {
  version: string;
  uptime: string;
  connectedAt: number;
  websocketBridge: boolean;
  websocketClients: number;
  rooms: FetcherRoom[];
}

LaplaceEvent

LaplaceEvent 是 event bridge 系統的核心型別,代表 LAPLACE Chat 與已連線用戶端之間交換的事件。每個事件都包含來自嗶哩嗶哩直播各類彈幕串流的標準化資料

所有事件都有一個共同的 type 欄位用於標示事件類別,以及各自事件類型特有的額外欄位

事件類型的更多說明見 事件類型文件

使用情境

  • 與 Discord、OBS、VTube Studio 整合
  • 在您偏好的前端中打造自訂的彈幕版面
  • 串接 streamer.bot、SAMMI 等第三方服務
  • ……以及任何您想得到的其他情境

開發

SDK 發布流程

SDK(@laplace.live/event-bridge-sdk)遵循結構化的發布流程,並使用 changesets 管理版本

  1. packages/sdk/修改 SDK

  2. 建立 changeset 以記錄本次變更:

    bunx @changesets/cli
    • 從套件清單中選擇 @laplace.live/event-bridge-sdk
    • 選擇合適的版本遞增方式(patch/minor/major)
    • 寫清楚本次變更的說明
  3. 提交變更,包含產生的 changeset 檔案:

    git add .
    git commit -m "feat(sdk): your change description"

授權條款

AGPL 與 MIT

最後更新於 2026年9月19日

Tech otakus destroy the world