# @crvouga/mockingbird-service-firstpromoter 中文文档

规范地址：https://npmcn.com/package/%40crvouga/mockingbird-service-firstpromoter/

版本：3\.11\.0
npm 元数据更新时间：2026-11-11T02:12:39.797Z
中文译文更新时间：2026-11-11T02:41:32.382Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40crvouga/mockingbird-service-firstpromoter
原文对照：https://npmcn.com/package/%40crvouga/mockingbird-service-firstpromoter/?lang=original
项目主页：https://github.com/crvouga/mockingbird/tree/main/packages/service/firstpromoter#readme
源码仓库：https://github.com/crvouga/mockingbird

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

- 包体积（解压后）：4.6 MB，18 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：2 个
- 首次发布：2026-09-22T23:53:50.404Z
- 最新版本发布：2026-11-11T02:12:39.396Z
- 近 30 天下载量：15277（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：42（近 12 个月 42 个）

## 中文简介

FirstPromoter v2 API的状态仿真器:促进器(由 cust id 创建前采用),由 tid / proposer id / ref sord 进行注册跟踪,iframe 登录,存档,以及 Basic-auth lead becomes referral webhoks.

## 安装

```sh
npm install @crvouga/mockingbird-service-firstpromoter
```

也可以使用：`pnpm add @crvouga/mockingbird-service-firstpromoter`、`yarn add @crvouga/mockingbird-service-firstpromoter`、`bun add @crvouga/mockingbird-service-firstpromoter`

## README

# @crvouga/mockingbird-service-first促进者

> 本地模拟器。 真正的API合同. 部分 [嘲笑鸟](https://github.com/crvouga/mockingbird)。 。 。 .

国家模拟器 **第一促进者 v2** 测试套房的附属 API: 促销者创建( 采用) 在创建前 `cust_id`),由 id / 查看 `cust_id` 编号 : `ref_token` / 电子邮件、 列表、 更新, 归档、 仪表板 iframe 登录、 登录跟踪 `tid`, (中文(简体) ), `promoter_id` 或证明, 和基本事实 `lead_becomes_referral` webhook我们的后端收到。 每个请求都是 在日记中记录,所以一个离职套件 可以断言 离职后的工作发送 生产失败的工作.

-   行动范围: [支助](https://github.com/crvouga/mockingbird/blob/main/packages/service/firstpromoter/SUPPORT.md)
-   第一促进者不公布机器可读规格:合同`openapi.yaml`)为 由我们消费者的要求 和zod计划 来验证反应.

## 安装

```bash
npm install -D @crvouga/mockingbird-service-firstpromoter
```

仅限无害环境管理。 节点 22或 Bun 1.2. 无土生属地. 给它服务 `npx mockingbird-firstpromoter serve`, (中文(简体) ), `createServer` 从 `./server` (节点),或 `createRuntime` 与任何获取服务器.

## 使用量

点 `FIRST_PROMOTER_API_URL` 在模拟器(我们的Joi计划需要 `https`,所以无论前面 设置任意 `FIRST_PROMOTER_API_KEY` 财务报告和审定财务报表 `FIRST_PROMOTER_ACCOUNT_ID`,并传出网球 Basic-auth 配对为 `--webhook-secret`。 。 。 .

```bash
npx mockingbird-firstpromoter serve --port 8812 \
  --webhook-url http://127.0.0.1:3000/users/webhooks/first-promoter \
  --webhook-secret "$FIRST_PROMOTER_WEBHOOK_AUTH_USERNAME:$FIRST_PROMOTER_WEBHOOK_AUTH_PASSWORD"
```

```ts
import { createServer } from "@crvouga/mockingbird-service-firstpromoter/server"

// Test setup: the emulator, an existing affiliate, and a click on their link.
const server = await createServer({
  webhooks: { url: "http://127.0.0.1:3000/users/webhooks/first-promoter", secret: "user:pass" },
})
const admin = (path: string, body: unknown) =>
  fetch(`${server.url}/__admin${path}`, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify(body),
  })
await admin("/promoters", { email: "nate@example.com", ref_token: "nate91" })
// The tid checkout stores as fp_tid.
const { tid } = (await (await admin("/clicks", { ref_token: "nate91" })).json()) as { tid: string }

// Application code: FIRST_PROMOTER_API_URL is server.url. The invoice handler tracks the signup.
const baseUrl = server.url
const tracked = await fetch(`${baseUrl}/v2/track/signup`, {
  method: "POST",
  headers: {
    authorization: "Bearer fp-api-key",
    "Account-ID": "acct_1",
    "content-type": "application/json",
  },
  body: JSON.stringify({ email: "customer@example.com", tid }),
})
// The emulator converts the referral and posts lead_becomes_referral to the backend with
// Authorization: Basic…
await server.close()
```

### 路线

| 路线 | 行为 |
| --- | --- |
| `POST /v2/company/promoters` | `{email, cust_id?, profile?: {first_name, last_name}, drip_emails?, initial_campaign_id?}` − 促进者(`FirstPromoterV2ResponseSchema`),在默认的竞选中注册,并有 `ref_token` (姓名+数字)和 `ref_link` `https://acme.example/referrals?fpr=<token>`使用同一电子邮件的现场宣传员或 `cust_id` 为 422 `{message, errors: {email: ["has already been taken"]}}`。 。 。 . |
| `GET /v2/company/promoters?page=&per_page=` | `{data: [promoter], meta: {pending_count}}`;存档的推广者被排除在外. |
| `GET /v2/company/promoters/{value}?find_by=id|cust_id|auth_token|ref_token|promo_code|email` | 一个推销员(也有存档的) `archived_at`页:1 `{message: "Promoter not found"}`。 。 。 . `promo_code` 通过种子解析代码 `POST /__admin/promo-codes` 给竞选注册的推动者. `auth_token` 是一个决定每个促进者标志 `POST` 编号 : `GET /__admin/promoters` 报告为 `auth_token` (供应商的推销员计划没有这样的领域,所以推销员机构不携带). 任何其他 `find_by` 四百块. |
| `PUT /v2/company/promoters/{id}` | `{cust_id?, email?, note?, profile?}` - 宣传者;404 / 422,如上. |
| `POST /v2/company/promoters/archive` | `{ids: [..]}` \* 已完成的批次 `{id, status, total, selected_total, processed_count, failed_count, action_label, progress, processing_errors, …}`。 。 。 . |
| `POST /v2/promoters/iframe_login?promoter_id=` | `{access_token, expires_in}`,或404个. |
| `POST /v2/track/signup` | `{email, tid? | promoter_id? | ref_id?, uid?, skip_email_notification?}` - 转介。 一个未知 `tid`,促销者或代号为404;没有400;已经追踪到的电子邮件为422. 与 `autoConvert` (违约)转介立即成为客户 `lead_becomes_referral` 发布. |
| `PUT /v2/company/commissions/{id}` | `{internal_note?, external_note?}` (供应商的 `CommissionUpdate`• 更新后的委员会,载于 `GET /v2/company/commissions`; 其他字段无法写出。 身份不明的号码是404 `{message: "Commission not found", code: "not_found"}`。 。 。 . |
| `GET /v2/company/referrals` | 大量储存的推荐和现场宣传员/运动元数据. `q` 搜索电子邮件/电子邮件; `ids[]`, (中文(简体) ), `filters[type]=lead|customer`, (中文(简体) ), `filters[state]`, (中文(简体) ), `filters[promoter_id]`和包容性 `filters[created_at|customer_since][from|to]` 呼叫前过滤器 . `page` 1起开始; `per_page` 默认为 20(最大为 100)。 已耗尽的页面和未匹配的搜索返回 `[]`。 。 。 . |
| `GET /v2/company/referrals/{id}` | 与列名相同的推荐预测。 数字标识或 `find_by=email|uid` 选择它; 缺少的记录是 404 . |

这个 [正式转诊参考](https://docs.firstpromoter.com/api-reference-v2/api-admin/referrals/get-referrals) 指定空阵列。 追踪参数和限制 [n8n 客户端](https://github.com/firstpromoter/n8n-app/blob/0842d761a3c024e7cf3030e5a108447375f03807/nodes/FirstPromoter/GeneralFunctions.ts) 财务报告和审定财务报表 [输入定义](https://github.com/firstpromoter/n8n-app/blob/0842d761a3c024e7cf3030e5a108447375f03807/nodes/FirstPromoter/FirstPromoter.node.ts)。 。 。 .

每个电话都需要 `Authorization: Bearer <key>` 还有一个 `Account-ID` 标题 (else 401).

### 网络呼号

`lead_becomes_referral` 身体和我们一样 `FirstPromoterNewCustomerWebhookSchema`数字 : `{event: {id, type, created_at}, data: {id, state, email, customer_since, promotion: {id, promoter_id, ref_id, leads_count, customers_count, current_referral_reward}, promoter: {id, cust_id, email, earnings_balance: {cash}}}}`,随同发送 `Authorization: Basic base64(<secret>)` 在其中的秘密 实值 `user:pass`非-2xx的答案被重审; `GET /__admin/webhooks`, (中文(简体) ), `…/events`, (中文(简体) ), `…/flush` 财务报告和审定财务报表 `PUT /__admin/webhook-endpoints` 工作如常.

### 管理员(超过标准合同)

| 路线 | 效果 |
| --- | --- |
| `POST /__admin/promoters` | 种子推广者 `{email, cust_id?, first_name?, last_name?, ref_token?, campaign_id?}`。 。 。 . |
| `GET /__admin/promoters` | 取名空间的推广者(存储形式). |
| `POST /__admin/clicks` | `{ref_token}` → `{tid, promoterId}`:点击促进者的链接. |
| `GET /__admin/referrals` | 追踪注册. |
| `POST /__admin/referrals/:id/convert` | `{saleAmount?}`:领头者已支付; 记为促销者(百分比奖励××金额)并贴出"网通". |
| `POST /__admin/commissions` | 种子一个针对现有 `{promoter_campaign_id, amount, unit?, status?, fulfilled?, is_paid?, referral_id?, sale_amount?, event_id?}`默认值:已核准、积分、未实现/未支付。 转介必须属于这个促进者和运动. |
| `POST /__admin/promo-codes` | 种子 `{promo_code, promoter_campaign_id}` 与现有的促销活动 销售归属测试. |
| `GET|PUT /__admin/settings` | `{website?, defaultCampaignId?, autoConvert?, promoCodeCreatesReferral?, campaigns?}` (营地携带) `referralRewards` 编号 : `promoterRewards` 与 `coupon`, (中文(简体) ), `amount`, (中文(简体) ), `unit`, (中文(简体) ), `per_of_sale`) (中文(简体) ). 默认竞选的推荐券是 `ACME50`。 。 。 . |

错误预设( E)`POST /__admin/faults {"preset": "<name>", "count"?: n}`· ; `GET /__admin/faults/presets`: `created_but_500` (储存,然后500: 重试必须被 `cust_id`, (中文(简体) ), `lookup_unavailable` (看503:既不创建也不收养), `no_campaign` (无) `promoter_campaigns`:无参考链接, `unauthorized`, (中文(简体) ), `rate_limited`, (中文(简体) ), `server_error`, (中文(简体) ), `connection_drop`, (中文(简体) ), `webhook_duplicate`, (中文(简体) ), `webhook_drop`。 。 。 .

FirstPromoter的调解程序 [公布的合同](https://github.com/firstpromoter/docs/blob/d4e9e6f16bf4801c524508d2809a425ea6419d7d/api-reference-v2/api-admin/commissions/openapi-v2-commissions.json)数字 : `GET /v2/company/commissions` 返回一个赤色阵列,首先是最新的阵列,带有 `q`,重复 `ids[]`, (中文(简体) ), `page` 编号 : `per_page` (默认为 1 / 20, 最多为 100) , 以及过滤器 `status`非货币 `fulfilled=yes|no`货币 `paid=yes|no`, (中文(简体) ), `promoter_id`, (中文(简体) ), `campaign_id`,金额/销售额 范围和创建日期范围. `POST …/commissions/mark_fulfilled` 非货币 佣金; `DELETE …/commissions/destroy` 删除选定的佣金。 两个都拿 `{ids}`。 。 。 . 最多5个身份证的批次返回200个/已完成;较大批次返回202个/待定。 在那个 模拟器在时钟前进后移动到进取点,然后以 1 000 ms 完成 认证API电话。 批次的藏品和有待完成的工作参与重设和快照. `GET …/batch_processes` 财务报告和审定财务报表 `…/batch_processes/progress` 默认列出未完成的工作 (单位:千美元)`filters[status]` 选择其他状态; `GET …/batch_processes/{id}` 返回计数和 处理错误. `batch_partial_failure` 处理时失败第一个选中的项目 别人。 时间、缺失ID/货币项目错误文本,而这个预设是合成控制; 它们不是关于供应商工人时间或确切错误信息的索赔。 完成为 与供应商分开储存 `is_paid` 货币领域.

`POST /v2/track/sale` 照着卖家的 [销售合同](https://github.com/firstpromoter/docs/blob/d4e9e6f16bf4801c524508d2809a425ea6419d7d/api-reference-v2/api-admin/tracking-api/openapi-v2-tracking.json)数字 : `{event_id, amount, email|uid, currency?, plan?, promo_code?, ref_id?, tid?, skip_email_notification?}` 在跟踪查询中记录了小单位的正整数。 第一个配置 运动奖励提供核定佣金; 奖励百分比四舍五入到最近的 小单位,平价奖励使用其配置的金额。 现金奖励也计入现有 促销者平衡;非货币性奖励没有. 答复包括转介、数额和 链接的佣金,在佣金收藏中可见。 重放事件ID返回 记录409,没有其他信用,佣金或网络hook。 未知的推荐文件,存档 宣传员和提供未匹配的归属标志归还文件404 `not_found` 形状. 代码必须通过管理员控制进行播种;符号必须属于推荐人的推广者 竞选。 所有验证都先于发售/委托/平衡写入;快照/重置包含事件 相去相减. 成功的发售保留了现有的转换webhook行为.

没有铅匹配时 `email` 编号 : `uid`卖家的 [跟踪合同](https://github.com/firstpromoter/docs/blob/d4e9e6f16bf4801c524508d2809a425ea6419d7d/api-reference-v2/api-admin/tracking-api/openapi-v2-tracking.json) 让我们 `tid` 或者说 `ref_id` "通过签注追踪": 创建了主角并指定了销售在 一个请求。 模拟器在 `tid` (点击 `POST /__admin/clicks`)或(或) `ref_id` 确定一个现场宣传员 请求中指定了领先者 `email`; 新线索数 向推销员推荐,成为顾客和帖子 `lead_becomes_referral`这是 docs-验证(上面的追踪OpenAPI),而不是甲骨文验证. `uid` 单靠自己不能给新线索起名, 还有一个 `email` 这已经是另一条线索了 `uid` 是422(如注册跟踪).

**`promo_code` 独活:最佳猜测,不是甲骨文验证.** 供应商没有提供进一步文件 `promo_code` ("用于促进码追踪"),所以只携带促进码的销售是否创造了 铅是不可观察的。 默认( E)`promoCodeCreatesReferral: false`:为未知的买方出售 仅限 `promo_code` 与任何未分配的销售相同 404, 并且没有存储。 打开 `PUT /__admin/settings {"promoCodeCreatesReferral": true}` 要有一个代码种子通过 `POST /__admin/promo-codes` 创建铅( 需要) `email`),将销售转让给拥有 竞选注册人数和职位 `lead_becomes_referral`完全一样 `tid` 编号 : `ref_id`。一个 未种子代码在两种模式中为404. 将取决于此设置的测试视为取决于 模拟者假设,直到现场反应被捕获.

### 命名空间

`x-mockingbird-namespace`页:1 `/__admin/ns/<name>` 前缀在 `FIRST_PROMOTER_API_URL`,或用 API 键: `PUT /__admin/credentials {"credentials": {"<FIRST_PROMOTER_API_KEY>": "<namespace>"}}`。 。 。 .

### 故意不模拟

-   错误机构和真实API的确切状态代码未经核实(没有沙盒证书): 错误使用 `{message}` 和审定 `{message, errors: {field: [...]}}`我们的消费者 分支 `ok` / 404,模拟器得到正确.
-   V1 API 我们的EMR后端仍然打电话来`/v1/promoters/*`, (中文(简体) ), `/v1/track/signup`, (中文(简体) ), `/v1/reports/campaigns`);目录将这个仿真器瞄准 v2.
-   退款、独立设立/编辑/核准佣金、现金支付和佣金过滤器 - 欺诈检查; 公共宣传码的提供; iframe sords后方的托管附属门户.
-   创建线索从 `promo_code` 默认单独关闭( e)`promoCodeCreatesReferral`:供应商仅为 `tid` 财务报告和审定财务报表 `ref_id`,所以选入行为是一个最好的猜测,而不是甲骨文验证.
-   货币记录不采用外汇兑换;具体计划的奖励、数量/ 计算,多级奖励,分出佣金和通知电子邮件没有模式化. 佣金四舍五入和立即批准是决定性的仿真政策,而不是现场核查 竞选政策。 与以往一样,缺席竞选奖金仍为10%.
-   转出编辑/删除,用户名/网站配置提供,取消日期过滤和分出归属.
-   促销码由每个命名空间4800001相继出.

## API 密码

| 导出 | 仁爱 | 说明 |
| --- | --- | --- |
| `FirstPromoterAPI` | 类 | 进程模拟器 : `fetch(request)`, (中文(简体) ), `reset()`, (中文(简体) ), `render(promoter)`, (中文(简体) ), `click(refToken)`, (中文(简体) ), `convert(referralId, saleAmount?)`, (中文(简体) ), `seedPromoter(input)`, (中文(简体) ), `state`选项: `sqlite`, (中文(简体) ), `now`, (中文(简体) ), `namespace`, (中文(简体) ), `settings`, (中文(简体) ), `onWebhook`。 。 。 . |
| `createRuntime` | 函数 | 全面服务合同的仿真器(健康、管理、命名空间、证书、预设、网络呼号)。 选项 : `webhooks: {url, secret, retryDelaysMs?, fetch?}`, (中文(简体) ), `settings`, (中文(简体) ), `clock`, (中文(简体) ), `seed`, (中文(简体) ), `adminKey`, (中文(简体) ), `onLog`, (中文(简体) ), `sqlite`。 。 。 . |
| `FIRSTPROMOTER_PRESETS` | 对象 | 每个命名的断层预设. |
| `FIRSTPROMOTER_NAMESPACE` | 字符串 | 服务名称, `"firstpromoter"`。 。 。 . |
| `WEBHOOK_PATH` | 字符串 | 接收器的路径, `/users/webhooks/first-promoter`。 。 。 . |
| `DEFAULT_CAMPAIGNS`, (中文(简体) ), `DEFAULT_SETTINGS` | 数值 | 种子运动和设置. |
| `document`, (中文(简体) ), `operationIds`, (中文(简体) ), `supportedOperationIds` | 数值 | 销售商为OpenAPI合同及其业务代号. |
| `createServer`, (中文(简体) ), `serveTarget`, (中文(简体) ), `DEFAULT_PORT` (单位:千美元)`./server`(中文(简体) ) | 节点 | 服务过来 `node:http`; 数据 `serve` CLI目标; 第8812口. |

部分 [嘲笑鸟](https://github.com/crvouga/mockingbird)。 。 。 .

## 常见问题

### @crvouga/mockingbird-service-firstpromoter 是什么？

FirstPromoter v2 API的状态仿真器:促进器\(由 cust id 创建前采用\),由 tid / proposer id / ref sord 进行注册跟踪,iframe 登录,存档,以及 Basic-auth lead becomes referral webhoks\.

### 如何安装 @crvouga/mockingbird-service-firstpromoter？

在项目目录运行 npm install @crvouga/mockingbird-service-firstpromoter，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 mockingbird-firstpromoter，可以用 npx mockingbird-firstpromoter 直接运行。

### @crvouga/mockingbird-service-firstpromoter 支持 TypeScript 吗？

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

### @crvouga/mockingbird-service-firstpromoter 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @crvouga/mockingbird-service-firstpromoter 可以商用吗？

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

### @crvouga/mockingbird-service-firstpromoter 的下载量有多少？

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

### @crvouga/mockingbird-service-firstpromoter 还在维护吗？

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

