# @botbye/node-core 中文文档

规范地址：https://npmcn.com/package/%40botbye/node-core/

版本：2\.2\.1
npm 元数据更新时间：2026-10-14T11:53:37.761Z
中文译文更新时间：2026-11-08T12:08:46.732Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40botbye/node-core
原文对照：https://npmcn.com/package/%40botbye/node-core/?lang=original
项目主页：https://botbye.com/
源码仓库：https://github.com/botbye/botbye-node-core

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：115 kB，95 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：0 个
- 首次发布：2026-05-20T14:24:44.354Z
- 最新版本发布：2026-10-14T11:53:37.602Z
- 近 30 天下载量：20369（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：6（近 12 个月 6 个）

## 中文简介

Bot Bye! 节点核心模块 Js

## 安装

```sh
npm install @botbye/node-core
```

也可以使用：`pnpm add @botbye/node-core`、`yarn add @botbye/node-core`、`bun add @botbye/node-core`

## README

# @ botbye/ 节点核心

[再见!](https://botbye.com/) node.js的核心模块——所有BotBye框架集成所使用的低层构件.

当环境没有特定框架集成时使用此软件包,或者当您需要完全控制请求信息如何传递到SDK时使用此软件包.

对于大多数使用的情况,更喜欢针对具体框架的一揽子方案:

-   [`@botbye/express`](https://www.npmjs.com/package/@botbye/express) ——快递
-   [`@botbye/fastify`](https://www.npmjs.com/package/@botbye/fastify) - 速报
-   [`@botbye/node-http`](https://www.npmjs.com/package/@botbye/node-http) - 节点.js `http` 模块
-   [`@botbye/cloudflare-worker`](https://www.npmjs.com/package/@botbye/cloudflare-worker) ——云花岗工人
-   [`@botbye/nextjs`](https://www.npmjs.com/package/@botbye/nextjs) 下一个.js
-   [`@botbye/nuxt`](https://www.npmjs.com/package/@botbye/nuxt) - 坚果

完整文档: [https://botbye.com/docs/server-side/node-js/core 页面存档备份,存于互联网档案馆](https://botbye.com/docs/server-side/node-js/core)

## 安装

```bash
npm i @botbye/node-core
```

```bash
yarn add @botbye/node-core
```

## 配置

`@botbye/node-core` 不导出 `init` 财务报告和审定财务报表 `evaluate` 直接说 打电话 `moduleApiFactory` 创建 SDK 实例 :

```javascript
import { moduleApiFactory } from "@botbye/node-core";
import { nodeHttpClient } from "@botbye/node-core/node-http-client";

const { init, evaluate, dev } = moduleApiFactory({
  httpClient: nodeHttpClient,
});

init({
  // Use your project server-key
  serverKey: "00000000-0000-0000-0000-000000000000",
});
```

打电话 `init` 在应用程序启动时,在呼叫之前 `evaluate`。 。 。 .

### `moduleApiFactory` 选项

| 选项 | 类型 | 需求 | 说明 |
| --- | --- | --- | --- |
| `httpClient` | `THttpClient` | 对 | HTTP客户端用于API呼叫. 见 [HTTP 客户端](https://npmcn.com/package/%40botbye/node-core/#readme-http-clients)。 。 。 . |
| `requestInfoExtractor` | `(request: R, global: TGlobalOptions) => TRequestInfo` | 没有 | 将自定义请求对象转换为请求信息, 启用 `{ request: R }` 内 `evaluate`。见 [建立定制一体化](https://npmcn.com/package/%40botbye/node-core/#readme-building-a-custom-integration)。 。 。 . |
| `url` | `string` | 没有 | 取代Bot Bye API的终点. 也可以通过 `init`。 。 。 . |

### HTTP 客户端

有两个内置的HTTP客户端:

| 导入路径 | 何时使用 |
| --- | --- |
| `@botbye/node-core/node-http-client` | 标准节点.js环境(使用内置) `http`编号 :`https`(中文(简体) ) |
| `@botbye/node-core/fetch-http-client` | 带有获取 API (Deno, Bun, 边缘运行时间) 的运行时间 |

如果两者都不符合(海关代理、特殊认证头、重试逻辑),则执行 `THttpClient` 接口 :

```typescript
import type { THttpClient } from "@botbye/node-core";

const myHttpClient: THttpClient = {
  type: "my-client",
  call(url, init) {
    const controller = new AbortController();
    const result = fetch(url, {
      method: init.method,
      headers: init.headers,
      body: JSON.stringify(init.body),
      signal: controller.signal,
    }).then((r) => r.text());
    return { result, abort: () => controller.abort() };
  },
};
```

### `init` 选项

| 选项 | 类型 | 需求 | 说明 |
| --- | --- | --- | --- |
| `serverKey` | `string` | 对 | 来自您的 BotBye 项目的服务器密钥 |
| `url` | `string` | 没有 | 覆盖 Bot Bye API 端点( 默认 : `https://verify.botbye.com`(中文(简体) ) |
| `logger.level` | `"error" | "warn" | "info" | "debug" | "log"` | 没有 | 日志级别( 默认 ): `"info"`(中文(简体) ) |
| `logger.logger` | `TLogger` | 没有 | 自定义日志实例执行 `{ error, warn, info, debug, log }` |
| `timeouts.evaluate` | `number` | 没有 | 每个超时( 毫秒) `evaluate` 调用 |

## 建立定制一体化

`requestInfoExtractor` 允许您为任何尚未被官方软件包覆盖的框架构建一等集成。 它弥合了框架的本地请求对象与 `TRequestInfo` 形状 `evaluate` 内部需要.

**它会做什么:**

何时 `requestInfoExtractor` 提供, `evaluate` 获得第二个调用表: 而不是明确通过字段, 您可以通过 `{ request: YourRequestObject }`。提取器被自动调用以获取 `ip`, (中文(简体) ), `headers`, (中文(简体) ), `requestMethod`,以及 `requestUri` 从它.

```typescript
// Without requestInfoExtractor — explicit fields only
evaluate({ type: "validate", request: { ip, headers, requestMethod, requestUri, token } });

// With requestInfoExtractor — framework request object accepted directly
evaluate({ type: "validate", request: { request: req, token } });
```

这两种形式并存有效。 已经通过球场的路线继续明确发挥作用.

**控件处理 :**

提取器也可返回 a `token` 字段(例如从已知标题中取出)。 如果打电话者也通过 `token` 事件的价值优先。 这样可以让提取器提供合理的默认,同时允许每个调用时的覆盖.

**类型脚本 :**

通用参数 `R` 打开 `moduleApiFactory<R>` 流动到 `evaluate` 签名。 提供 `requestInfoExtractor` 是什么让输入 `{ request: R }` 窗体有效 :

```typescript
import { moduleApiFactory } from "@botbye/node-core";
import { nodeHttpClient } from "@botbye/node-core/node-http-client";
import type { Request } from "express";

const { init, evaluate, dev } = moduleApiFactory<Request>({
  httpClient: nodeHttpClient,
  requestInfoExtractor: (req, global) => {
    try {
      return {
        ip: req.ip ?? req.socket.remoteAddress ?? "0.0.0.0",
        headers: req.headers as Record<string, string>,
        requestMethod: req.method,
        requestUri: req.url,
        token: req.headers["x-botbye-token"] as string ?? null,
      };
    } catch {
      global.logger.warn("Failed to extract request info from Express request");
      return { ip: "0.0.0.0", headers: {} };
    }
  },
});

init({
  // Use your project server-key
  serverKey: "00000000-0000-0000-0000-000000000000",
});

// Now evaluate accepts Express Request directly
app.use(async (req, res, next) => {
  const result = await evaluate({
    type: "validate",
    request: {
      request: req,
      // "x-botbye-token" is an example — pass the token from wherever you store it
      token: req.headers["x-botbye-token"] as string,
    },
  });

  if (result.decision === "BLOCK") {
    return res.status(403).json({ error: "Forbidden" });
  }

  next();
});
```

这个 `global` 移交给提取器的参数 `global.logger` ——当请求对象畸形或出乎意料时用于警告.

## 使用量

打电话 `evaluate` 带有事件对象描述您对请求的了解。 它还带来一个决定决定的承诺.

有三种活动类型—— `validate`, (中文(简体) ), `risk`,以及 `full` 每一个都适合你申请的不同层次.

无 `requestInfoExtractor`,所有请求字段必须明确提供——没有任何框架请求可以通过.

* * *

### `validate` --边缘级机器人检查

在边缘使用 — API网关, 路由处理器, 中间软件—— 当你只想知道时 : **这是机器人提出的要求吗?** 不需要用户或域名上下文 .

**活动字段 :**

```typescript
{
  type: "validate";
  request:
    // Option A: custom request object — only available when requestInfoExtractor is configured
    | { request: R; token?: string | null }
    // Option B: explicit fields
    | { ip: string; headers: Record<string, string>; requestMethod?: string | null; requestUri?: string | null; token?: string | null };
  customFields?: Record<string, string>;
}
```

从您的运行时请求对象中取出 IP 和信头 。 备选案文A——直接传递框架请求对象——要求 `requestInfoExtractor` 将配置在 `moduleApiFactory`; 见 [建立定制一体化](https://npmcn.com/package/%40botbye/node-core/#readme-building-a-custom-integration)编辑 `token` 是一个一次性符号,由 [Bot 再见客户端 SDK](https://botbye.com/docs/client-side/npm-module) 包含关于用户设备的信息。 不论客户寄给什么,都通过;如果没有收到任何信使,将作出决定 `"BLOCK"` 由于一个无效的符号.

```javascript
async function handleRequest(ip, headers, method, url, token) {
  const result = await evaluate({
    type: "validate",
    request: {
      ip,
      headers,
      requestMethod: method,
      requestUri: url,
      token,
    },
  });

  if (result.decision === "BLOCK") {
    return { status: 403 };
  }

  // proceed normally
}
```

* * *

### `risk` ——域级风险评分

使用已经了解用户的内部服务:认证,支付,账户管理等. 目的从"这是机器人吗?"转移到了 **"对于这个用户来说,有什么可疑的吗?"** ——凭证填充,账户接管,账户共享,登录新地物.

**活动字段 :**

```typescript
{
  type: "risk";
  request:
    // Option A: custom request object — only available when requestInfoExtractor is configured
    | { request: R }
    // Option B: explicit fields
    | { ip: string; headers?: Record<string, string>; requestMethod?: string | null; requestUri?: string | null; token?: string | null };
  event: {
    type: string;
    status: "ATTEMPTED" | "SUCCESSFUL" | "FAILED" | "UNKNOWN";
  };
  user: {
    accountId: string;
    username?: string | null;
    email?: string | null;
    phone?: string | null;
  };
  customFields?: Record<string, string>;
  botbyeResult?: string;
}
```

`event` 财务报告和审定财务报表 `user` 它们是关键的领域——它们界定了正在采取什么行动,以及由谁采取行动,这是促使风险得分的因素. `ip` 同样重要的是: IP访问账户的 Bot Bye 轨迹可以探测到诸如账户共享、认证输入和可疑地理登录等模式。 直接传过来 `{ ip }`,或者如果 `requestInfoExtractor` 已配置 - 见 [建立定制一体化](https://npmcn.com/package/%40botbye/node-core/#readme-building-a-custom-integration)。 。 。 .

```javascript
// Inside an auth service, after a login attempt
async function onLoginAttempt({ ip, userId, email, loginSucceeded }) {
  const result = await evaluate({
    type: "risk",
    request: { ip },
    event: {
      type: "login",
      status: loginSucceeded ? "SUCCESSFUL" : "FAILED",
      // "SUCCESSFUL" | "FAILED" | "ATTEMPTED" | "UNKNOWN"
    },
    user: {
      accountId: userId,
      email,
    },
  });

  if (result.decision === "BLOCK") {
    // Lock account, trigger MFA, send alert, etc.
  }
}
```

#### 链接 `validate` 财务报告和审定财务报表 `risk` 事件

当对同一请求进行两层评价时——例如,一次在边缘(`type: "validate"`),然后再次在域服务内(`type: "risk"`) —— Bot Bye可以将这两起事件联系起来,并在仪表板上作为单个事件展示.

这个 `validate` 答复包括 `botbye_result` 绳子。 通过它作为 `botbyeResult` 输入 `risk` 要求建立链接:

```javascript
// Edge layer — validate the bot token
const edgeResult = await evaluate({
  type: "validate",
  request: {
    ip,
    headers,
    requestMethod: method,
    requestUri: url,
    token,
  },
});

// Pass edgeResult.botbye_result to your domain service however you like —
// a request header, a context object, a function argument, etc.
const edgeBotbyeResult = edgeResult.botbye_result;

// Domain service — risk scoring linked to the edge validation above
const riskResult = await evaluate({
  type: "risk",
  request: { ip },
  event: {
    type: "login",
    status: loginSucceeded ? "SUCCESSFUL" : "FAILED",
  },
  user: {
    accountId: userId,
    email,
  },
  botbyeResult: edgeBotbyeResult,
});
```

`botbye_result` 在答复中是可选的——如果没有,删去 `botbyeResult` 事件将被独立记录.

* * *

### `full` ——边缘检查和域评分在一个呼叫中

当您同时拥有全部上下文时使用:原始请求、 令牌、 用户和事件 。 登录端点是一个典型的例子——它接收到HTTP请求并立即知道用户和结果.

**活动字段 :**

```typescript
{
  type: "full";
  request:
    // Option A: custom request object — only available when requestInfoExtractor is configured
    | { request: R; token?: string | null }
    // Option B: explicit fields
    | { ip: string; headers: Record<string, string>; requestMethod?: string | null; requestUri?: string | null; token?: string | null };
  event: {
    type: string;
    status: "ATTEMPTED" | "SUCCESSFUL" | "FAILED" | "UNKNOWN";
  };
  user: {
    accountId: string;
    username?: string | null;
    email?: string | null;
    phone?: string | null;
  };
  customFields?: Record<string, string>;
}
```

等同运行 `validate` 财务报告和审定财务报表 `risk` 在一个电话。 备选案文A要求 `requestInfoExtractor` 看到了吗 [建立定制一体化](https://npmcn.com/package/%40botbye/node-core/#readme-building-a-custom-integration)。 。 。 .

```javascript
async function handleLogin({ ip, headers, method, url, token, email, password }) {
  const user = await findUser(email);
  const loginSucceeded = user && (await checkPassword(user, password));

  const result = await evaluate({
    type: "full",
    request: {
      ip,
      headers,
      requestMethod: method,
      requestUri: url,
      token,
    },
    event: {
      type: "login",
      status: loginSucceeded ? "SUCCESSFUL" : "FAILED",
    },
    user: {
      accountId: user?.id ?? "unknown",
      email,
    },
  });

  if (result.decision === "BLOCK") {
    return { status: 403 };
  }

  // proceed normally
}
```

* * *

## 回应

`evaluate` 总是返回 a `Promise<TEvaluationResult>`数字 :

```typescript
type TEvaluationResult =
  | {
      decision: "ALLOW" | "BLOCK" | "CHALLENGE";
      request_id: string;
      risk_score: number;
      scores: Record<string, number>;
      signals: string[];
      botbye_result?: string;
    }
  | {
      decision: "ALLOW";
      botbye_result?: string;
      error: { message: string };
    };
```

检查 `result.decision` 决定如何处理请求:

-   `"ALLOW"` - 请求似乎合法,正常进行
-   `"BLOCK"` - 探测到机器人或可疑活动,阻止请求
-   `"CHALLENGE"` - 不确定,考虑发布CAPTCHA、外交部或额外的核查步骤

当答复中包含 `error` 字段,该请求没有得到充分评价。 一个 **集成错误** 失败 **关闭** 与 `decision: "BLOCK"` 财务报告和审定财务报表 `signals: ["evaluation_error"]` 成型不良的有效载荷,或解决任何项目的钥匙(`Invalid server key`,或 `Invalid site key` 用于调用; 密钥是 UUID , 所以错误的密钥会清晰地分析, 并且只检查失败 。 A 类 **Bot Bye-side 失败** 失败 **打开** 与 `decision: "ALLOW"`,所以我们自己的过失 并不阻挡真正的用户,和 **SDK 软件** 做同样的,没有 `request_id`,当它从未收到任何决定时——请求超时,连接出错,或无法解析的反应. 监视器 `error.message` 无论是哪种方式,并解决根本原因.

### 你的计划是什么

`risk_score`, (中文(简体) ), `scores` 和探测器 `signals` 现从 **启动器** 计划好 打开 **免费** 页:1 判决是一样的,而且 `request_id` 仍然在那里, 但这三个回来空白: `risk_score` 实值 `0.0`, (中文(简体) ), `scores` 实值 `{}`,以及 `signals` 只保留你身边名字的原因 而不是 我们的探测器.. `token_expected`, (中文(简体) ), `script_loading_error`, (中文(简体) ), `token_generation_error`, (中文(简体) ), `raw_token_changed` 财务报告和审定财务报表 `banned_by_rule`你写的规则的判决.

每项计划的保护行为都相同;只有对决定的解释才不予考虑。 所以,分支 打开 `decision`永远不要 `risk_score` 上面的门槛 将每个自由计划请求都视为低风险.

### 反应实例

被屏蔽( 检测到的机器人) :

```json
{
  "request_id": "f77b2abd-c5d7-44f0-be4f-174b04876583",
  "decision": "BLOCK",
  "risk_score": 0.95,
  "scores": { "bot": 0.95 },
  "signals": ["AutomationTool"]
}
```

允许 :

```json
{
  "request_id": "f77b2abd-c5d7-44f0-be4f-174b04876583",
  "decision": "ALLOW",
  "risk_score": 0.05,
  "scores": { "bot": 0.05, "ato": 0.02 },
  "signals": []
}
```

挑战:

```json
{
  "request_id": "f77b2abd-c5d7-44f0-be4f-174b04876583",
  "decision": "CHALLENGE",
  "risk_score": 0.65,
  "scores": { "bot": 0.65 },
  "signals": ["SuspiciousFingerprint"],
  "challenge": { "type": "CAPTCHA", "token": "..." }
}
```

无效 `serverKey` 已知项目(未关闭):

```json
{
  "request_id": "f77b2abd-c5d7-44f0-be4f-174b04876583",
  "decision": "BLOCK",
  "risk_score": 1.0,
  "scores": {},
  "signals": ["evaluation_error"],
  "error": { "message": "Invalid server key" }
}
```

SDK从未收到决定( 未打开) :

```json
{
  "decision": "ALLOW",
  "error": { "message": "connection error" }
}
```

## 高级: 多个实例

使用 `moduleApiFactory` 创建独立的 SDK 实例( 当保护多个项目不受一个服务的影响时有用) :

```javascript
import { moduleApiFactory } from "@botbye/node-core";
import { nodeHttpClient } from "@botbye/node-core/node-http-client";

const sdkA = moduleApiFactory({ httpClient: nodeHttpClient });
const sdkB = moduleApiFactory({ httpClient: nodeHttpClient });

sdkA.init({
  // Use your project server-key
  serverKey: "00000000-0000-0000-0000-000000000000",
});

sdkB.init({
  // Use your project server-key
  serverKey: "11111111-1111-1111-1111-111111111111",
});
```

## 水电费

```javascript
import { moduleApiFactory } from "@botbye/node-core";
import { nodeHttpClient } from "@botbye/node-core/node-http-client";

const { dev } = moduleApiFactory({ httpClient: nodeHttpClient });

// Change log verbosity at runtime
dev.setLoggerLevel("debug"); // "error" | "warn" | "info" | "debug" | "log"
```

## 反钓鱼

Bot Bye的反钓鱼探测器 看起来像是复制你页面的站点 此集成为检测服务 **捕捉器** 因此,BotBye域名对客户端保持隐藏.

-   [反海盗保护概况](https://botbye.com/docs/anti-phishing/overview)
-   [为什么需要服务器端集成](https://botbye.com/docs/anti-phishing/overview#server-integration)

反钓鱼是由它自己识别出 `clientKey` (可在Dashboard上的您 Phishing 工程中找到),而不是用于 `evaluate`,因此它被配置和连接 单独,通过 `phishingModuleApiFactory`。 。 。 .

### 配置

```javascript
import { phishingModuleApiFactory } from "@botbye/node-core";
import { nodePhishingHttpClient } from "@botbye/node-core/phishing-node-http-client";

const phishing = phishingModuleApiFactory({
  httpClient: nodePhishingHttpClient,
});

phishing.init({
  // clientKey from your Phishing Project on the Admin Dashboard
  clientKey: "00000000-0000-0000-0000-000000000000",
});
```

打电话 `phishing.init` 在应用程序启动时,在满足任何捕捉者请求之前.

### `phishingModuleApiFactory` 选项

| 选项 | 类型 | 需求 | 说明 |
| --- | --- | --- | --- |
| `httpClient` | `TPhishingHttpClient` | 对 | HTTP客户端用于捕捉者呼叫. 见 [HTTP 客户端](https://npmcn.com/package/%40botbye/node-core/#readme-phishing-http-clients) 见下文. |
| `catcherRequestInfoExtractor` | `(request: R, global: TPhishingGlobalOptions) => TPhishingCatcherRequestInfo` | 没有 | 将自定义请求对象转换为 `{ headers }`,启用 `{ request: R }` 内 `fetchCatcher`相同的想法 `requestInfoExtractor` 以上——见 [建立定制一体化](https://npmcn.com/package/%40botbye/node-core/#readme-building-a-custom-integration)。 。 。 . |
| `url` | `string` | 没有 | 取代Bot Bye API的终点. 也可以通过 `phishing.init`。 。 。 . |

### Phishing HTTP 客户端

Phishing呼叫使用自己的HTTP客户端接口(`TPhishingHttpClient`页:1 `evaluate`是因为 `THttpClient` ——两者不可互换. 有两个内置客户端:

| 导入路径 | 何时使用 |
| --- | --- |
| `@botbye/node-core/phishing-node-http-client` | 标准节点.js环境(使用内置) `http`编号 :`https`(中文(简体) ) |
| `@botbye/node-core/phishing-fetch-http-client` | 带有获取 API (Deno, Bun, 边缘运行时间) 的运行时间 |

### `phishing.init` 选项

| 选项 | 类型 | 需求 | 说明 |
| --- | --- | --- | --- |
| `clientKey` | `string` | 对 | `clientKey` 从您管理板上的 Phishing 工程 |
| `url` | `string` | 没有 | 覆盖 Bot Bye API 端点( 默认 : `https://verify.botbye.com`(中文(简体) ) |
| `logger.level` | `"error" | "warn" | "info" | "debug" | "log"` | 没有 | 日志级别( 默认 ): `"info"`(中文(简体) ) |
| `logger.logger` | `TLogger` | 没有 | 自定义日志实例执行 `{ error, warn, info, debug, log }` |
| `timeouts.fetchCatcher` | `number` | 没有 | 每个超时( 毫秒) `fetchCatcher` 调用 |

### 使用量

反钓鱼需要 **两条路线的原产地**,每个代理通过 `fetchCatcher`数字 :

-   **SVG 路线** - 为SVG捕手服务。 这是您的 URL [客户端](https://botbye.com/docs/anti-phishing/integrations/client/js-tag#getcatcher-options) 通行证给 `getCatcher({ url })`。 。 。 .
-   **PNG 路线** ——服务于SVG参考的PNG(通过 `innerPngUrl`) (中文(简体) ).

无 `catcherRequestInfoExtractor`,通过 `headers` 明确而不是请求对象。 对于SVG, `innerPngUrl` 应该是 **绝对 URL** 您的 PNG 路由 —— 浏览器直接从您的源头装入 PNG .

```javascript
// Absolute URL of your PNG endpoint — the SVG catcher references it through innerPngUrl.
const PNG_CATCHER_URL = "https://your-site.example/botbye-catcher.png";

async function serveSvgCatcher(headers) {
  const catcher = await phishing.fetchCatcher({
    headers,
    format: "svg",
    innerPngUrl: PNG_CATCHER_URL, // absolute URL of the PNG endpoint below
  });

  return { status: catcher.status, headers: catcher.headers, body: catcher.body };
}

async function servePngCatcher(headers) {
  const catcher = await phishing.fetchCatcher({ headers, format: "png" });

  return { status: catcher.status, headers: catcher.headers, body: catcher.body };
}
```

`fetchCatcher` 总是返回 a `Promise<TUpstreamFetchCatcherResult>`数字 :

```typescript
type TUpstreamFetchCatcherResult = {
  status: number;
  headers: Record<string, string>;
  body: Uint8Array;
  error?: { message: string };
};
```

中继 `status`, (中文(简体) ), `headers`,以及 `body` 确切的电话取决于您的运行时间(`res.writeHead`编号 :`res.end`, (中文(简体) ), `new Response(...)`(见a/c.5/49/70,附件).

我们建议嵌入 **SVG 捕捉器**:它旨在继续跟踪,即使一个钓鱼网站将您的所有资产复制到自己的基础设施(PNG路线存在是因为SVG捕捉者依赖于它).

### 建立定制一体化

碞钩 `requestInfoExtractor` 页:1 `evaluate`, (中文(简体) ), `catcherRequestInfoExtractor` 让我们 `fetchCatcher` 直接接受框架的本地请求对象—— `{ request: R }` ——改为 `{ headers }`。 。 。 .

```typescript
import { phishingModuleApiFactory } from "@botbye/node-core";
import { nodePhishingHttpClient } from "@botbye/node-core/phishing-node-http-client";
import type { Request } from "express";

const phishing = phishingModuleApiFactory<Request>({
  httpClient: nodePhishingHttpClient,
  catcherRequestInfoExtractor: (request) => ({
    headers: request.headers as Record<string, string>,
  }),
});

phishing.init({
  clientKey: "00000000-0000-0000-0000-000000000000",
});

// Now fetchCatcher accepts an Express Request directly
app.get("/botbye-catcher.svg", async (req, res) => {
  const catcher = await phishing.fetchCatcher({
    request: req,
    format: "svg",
    innerPngUrl: PNG_CATCHER_URL,
  });

  res.status(catcher.status).set(catcher.headers).send(Buffer.from(catcher.body));
});
```

### 高级: 多个实例

使用 `phishingModuleApiFactory` 创建独立的 SDK 实例( 当保护多个项目不受一个服务的影响时有用) :

```javascript
import { phishingModuleApiFactory } from "@botbye/node-core";
import { nodePhishingHttpClient } from "@botbye/node-core/phishing-node-http-client";

const phishingA = phishingModuleApiFactory({ httpClient: nodePhishingHttpClient });
const phishingB = phishingModuleApiFactory({ httpClient: nodePhishingHttpClient });

phishingA.init({
  clientKey: "00000000-0000-0000-0000-000000000000",
});

phishingB.init({
  clientKey: "11111111-1111-1111-1111-111111111111",
});
```

## 文档

-   网络 : [https://botbye.com/docs/server-side/node-js/core 页面存档备份,存于互联网档案馆](https://botbye.com/docs/server-side/node-js/core)
-   标记下(用于人工智能工具和代理): [https://botbye.com/docs/server-side/node-js/core.md 页面存档备份,存于互联网档案馆](https://botbye.com/docs/server-side/node-js/core.md)

## 常见问题

### @botbye/node-core 是什么？

Bot Bye\! 节点核心模块 Js

### 如何安装 @botbye/node-core？

在项目目录运行 npm install @botbye/node-core，或使用 pnpm add / yarn add / bun add。

### @botbye/node-core 支持 TypeScript 吗？

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

### @botbye/node-core 支持 ESM 还是 CommonJS？

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

### @botbye/node-core 可以商用吗？

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

### @botbye/node-core 的下载量有多少？

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

### @botbye/node-core 还在维护吗？

最新版本 2\.2\.1 发布于 2026/10/14（25 天前）；至今共发布 6 个版本，其中过去 12 个月发布了 6 个；首次发布于 2026/05/20。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

