@blandsdk/client

中文文档
1.0.1发布于 2025/10/22MITTypeScriptESM + CJS近 30 天下载 6218

布兰德客户SDK为Node,React,和香草JS.

中文使用文档
文档目录7 节
  1. 开始
  2. 安装
  3. 概览
  4. 用法:服务器系统(Admin SDK)
  5. 用法:客户端-Side (Webchat SDK) - 反应
  6. 客户选项
  7. 需要帮忙吗?

@blanddk/ 客户端

布兰德SDK是一款JavaScript/TypeScript SDK,用于与布兰德平台相融合. 它既提供服务器端组件,也提供客户端端组件来方便与布兰德的服务通信.

npm version npm downloads license

开始

布兰德SDK有两个组成部分:

  • Admin SDK:用于创建会话,处理认证,并使用您特权的API密钥与布兰德互动的服务器-Side SDK.
  • 客户端 SDK : Webchat SDK 用于嵌入 Bland 在您的应用程序中 。 您的 API 密钥不应该在这里使用 .

安装

npm install @blandsdk/client

概览

SDK被设计用于服务器端和客户端端环境. 服务器侧组件(Admin SDK)负责创建会话,使用一个特权的API密钥来请求bland并管理认证,而客户端组件(Webchat SDK)则处理用户界面和与Bland的交互.

Browser Client -> Your Server (which uses the Admin SDK) -> Bland

然后,当客户端有会话符号时:

Browser Client -> Bland

用法:服务器系统(Admin SDK)

管理员SDK用于为代理创建会话. 以下是为给定创建会话的Express路由示例: agentId 并返回会话符号。 此指使随后被Webchat SDK在客户端使用.

import express from "express";
import bodyParser from "body-parser";
import Bland from "@blandsdk/client";

const app = express();
app.use(bodyParser.json());

const bland = new Bland({
  admin: {
    apiKey: process.env.BLAND_API_KEY,
    endpoint: "https://api.bland.ai" // enterprise users: contact your account executive for the correct endpoint.
  },
  webchat: {}
});

app.post("/api/agent-authorize", async (req, res) => {
  try {
    const agentId = req.body?.agentId;
    if (!agentId) {
      return res.status(400).json({ error: "missing agentId" });
    }

    const admin = await bland.AdminClient();

    const session = await admin.sessions.create({ agentId });

    res.json({ token: session.token });
  } catch (err: any) {
    res.status(500).json({ error: err?.message || "internal error" });
  }
});

const port = 5174;
app.listen(port, () => {
  console.log(`Admin server running on http://localhost:${port}`);
});

用法:客户端-Side (Webchat SDK) - 反应

以下是一个最小的例子, 请求您的管理者 SDK 提供会话符号, 连接 Webchat, 聆听事件, 并显示笔录 。 与返回的管理员区的快车路线对等 { token } 给定的 agentId。 。 。 .

import { useEffect, useMemo, useRef, useState } from "react";
import { useWebchat } from "@blandsdk/client/react";

type Token = { token: string };

async function authorizeAgent(agentId: string): Promise<Token> {
  const r = await fetch("<your server url>", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ agentId })
  });
  if (!r.ok) throw new Error(`authorize error ${r.status}`);
  return r.json();
}

export default function App() {
  const [agentId, setAgentId] = useState("abc123");
  const [status, setStatus] = useState("idle");
  const [streamSid, setStreamSid] = useState<string | null>(null);
  const [transcript, setTranscript] = useState<string>("");
  const logRef = useRef<HTMLPreElement | null>(null);

  const getToken = useMemo(() => {
    return async () => authorizeAgent(agentId);
  }, [agentId]);

  const { state, start, stop, webchat } = useWebchat({
    agentId,
    getToken
  });

  useEffect(() => {
    const off = [
      webchat.on("open", () => {
        setStatus("open");
        log("[Websocket][open]");
      }),
      webchat.on("text", (raw: string) => {
        log(`[Websocket][text] ${raw}`);
      }),
      webchat.on("message", (m: any) => {
        log(`[Websocket][message] ${JSON.stringify(m)}`);
        if (!streamSid && m?.streamSid) setStreamSid(m.streamSid);
      }),
      webchat.on("update", (m: any) => {
        log(`[Websocket][update] ${JSON.stringify(m)}`);
        const who = m?.payload?.type === "assistant" ? "assistant" : "human";
        const t = m?.payload?.text;
        if (typeof t === "string" && t.length) {
          setTranscript((cur) => (cur ? `${cur}\n${who}: ${t}` : `${who}: ${t}`));
        }
      }),
      webchat.on("closed", () => {
        setStatus("closed");
        log("[Websocket][closed]");
      }),
      webchat.on("error", (e: unknown) => {
        setStatus("closed");
        log(`[Websocket][error] ${stringify(e)}`);
      })
    ];
    return () => off.forEach((u) => u());
  }, [webchat, streamSid]);

  function stringify(v: unknown) {
    try { return typeof v === "string" ? v : JSON.stringify(v) } catch { return String(v) }
  }

  function log(line: string) {
    const ts = new Date().toISOString();
    if (logRef.current) {
      logRef.current.textContent += `[${ts}] ${line}\n`;
      logRef.current.scrollTop = logRef.current.scrollHeight;
    }
  }

  const onStart = async () => {
    try {
      setStatus("authorizing");
      await start();
    } catch (e) {
      setStatus("closed");
      log(String(e));
    }
  };

  const onStop = () => {
    try { stop() } finally { setStatus("closed") }
  };

  return (
    <div style={{ maxWidth: 760, margin: "0 auto", padding: 24, fontFamily: "system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif" }}>
      <h1 style={{ fontSize: 22, margin: "0 0 16px" }}>Bland React SDK</h1>
      <div style={{ display: "flex", gap: 8, alignItems: "center", margin: "12px 0" }}>
        <label htmlFor="agent">Agent</label>
        <input id="agent" value={agentId} onChange={(e) => setAgentId(e.target.value)} />
        <button onClick={onStart} disabled={state !== "closed" && state !== "connecting"}>Start</button>
        <button onClick={onStop} disabled={state === "closed"}>Stop</button>
      </div>
      <div style={{ padding: "8px 10px", background: "#f5f5f5", borderRadius: 6, marginTop: 12 }}>{status}</div>
      <h2 style={{ fontSize: 16, marginTop: 16 }}>Transcript</h2>
      <pre style={{ whiteSpace: "pre-wrap", background: "#fafafa", padding: 12, borderRadius: 6 }}>{transcript}</pre>
      <h2 style={{ fontSize: 16, marginTop: 16 }}>Log</h2>
      <pre ref={logRef} style={{ whiteSpace: "pre-wrap", background: "#0b1020", color: "#e6edf3", padding: 12, borderRadius: 6, maxHeight: 300, overflow: "auto" }} />
    </div>
  );
}

客户选项

export interface BlandClientOptions {
    admin: {
        apiKey?: string;
        endpoint?: string;
    }
    webchat?: {
        endpoint?: string;
    }
}

需要帮忙吗?

加入我们 不对 支持我们! 我们的文档也有 这里。 。 。 .

版本与发布记录

@blandsdk/client 共发布 2 个版本,首次发布于 2025/09/16;过去 12 个月发布了 0 个版本。

版本发布日期距今
1.0.1latest2025/10/221 年前
1.0.02025/09/161.1 年前

关于 @blandsdk/client 的常见问题

@blandsdk/client 是什么?

布兰德客户SDK为Node,React,和香草JS.

如何安装 @blandsdk/client?

在项目目录运行 npm install @blandsdk/client,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(>=18)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@blandsdk/client 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@blandsdk/client 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@blandsdk/client 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@blandsdk/client 可以商用吗?

@blandsdk/client 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@blandsdk/client 的下载量有多少?

根据 npm 官方下载统计,@blandsdk/client 在 2026/10/09 – 2026/11/07 这 30 天内被下载 6,218 次,日均约 207 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@blandsdk/client 还在维护吗?

最新版本 1.0.1 发布于 2025/10/22(1 年前);至今共发布 2 个版本,其中过去 12 个月发布了 0 个;首次发布于 2025/09/16。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。