@cekatai/event-sdk
用于Node.js和Bun的服务器SDK通过后端唯一访问符发送Cekat事件. 浏览器导出时刻意包含 没有令牌客户端, (中文(简体) ), Authorization 处理,或节点进口.
安装并初始化( Node.js and Bun)
npm install @cekatai/event-sdk # or: bun add @cekatai/event-sdk
要求节点js 22.12 或更新,或 Bun 1.2.5 或更新. 相同的软件包运行在两个上;参见 阿宝该软件包是无害环境管理的,也通过普通JS装入 require() (例如默认的NestJS项目). 节点客户端均导出 @cekatai/event-sdk 财务报告和审定财务报表 @cekatai/event-sdk/node。 。 。 .
| 框架适配器 | 获支助的主要课程 |
|---|---|
| 快递 | 4.17+, 5项 |
| 快捷化 | 第4、第5条 |
| 科亚 | 2.13+,3个 |
| NestJS( 压缩或快取平台) | 第10、11、12条 |
| Next.js (节点运行时间) | 第14、15、16条 |
获取样式处理器 : Bun.serve霍诺 爱莉西亚@cekatai/event-sdk/fetch(中文(简体) ) | 任意 |
import { Client } from '@cekatai/event-sdk';
// Keep the token in server-side configuration; never ship it to a browser.
const cekat = new Client(process.env.CEKAT_ACCESS_TOKEN!);
Client 只接受一个符号加可选 { baseURL, timeoutMs, retryCount, fetch } 选项. baseURL 必须是一个绝对的HTTP(S)源,没有证书、路径、查询或碎片。 默认是 https://t.cekat.ai;每个业务员额只到 /api/events/ingest 并认同自己 User-Agent: cekat-event-sdk-node/<version> <runtime>/<version>,运行时间在哪里 node 或者说 bun。默认超时为每次尝试3秒,默认重试计数为初始请求后2秒。 过 { signal } 用于不重试而取消任何事件的调用.
await cekat.userRegistration({ email: '[email protected]' });
await cekat.userLogin({ phoneNumber: '+15551234567', visitorId: 'browser-visitor' });
await cekat.orderCreated(125000, 'IDR', { email: '[email protected]', properties: { order_id: 'o-1' } });
await cekat.formSubmitted({ email: '[email protected]', properties: { form_id: 'contact' } });
await cekat.orderPaid(125000, 'IDR', { email: '[email protected]', properties: { order_id: 'o-1' } });
await cekat.customEvent('wishlist_updated', { email: '[email protected]', contactName: 'Ada' });
formSubmitted(event) 发送常见 form_submitted 活动(is_common: true) (中文(简体) ). orderCreated(amount, currency, event) 财务报告和审定财务报表 orderPaid(amount, currency, event) 需要限制 amount 和无空白 currency,作为 amount 财务报告和审定财务报表 currency 属性;不同时将这些密钥放入 event.properties。它们只在事件键上有所不同.
不可脱口而出 visitorId ; 空白的明确值回到上下文。 电子邮件和电话按提交内容保留,但至少必须有一个非空白。 事件属性仅为 JSON 值( 无限安全数字、 数组和平方对象); 转换等值 Date 以字符串为首.
每个事件都带有 event_id 还有一个 occurred_at 时间戳。 何时 eventId 空白的 SDK 生成一个随机的 UUID, 当 occurredAt 联合国 Date)被省略,它使用调用的时间. 两者在第一次尝试前均被固定并被每次再试再用,因此Cekat可以识别再试出货. 自己供应 eventId 当同一商务事件可能不止一次发送时(例如命令或webhook ID):
await cekat.orderPaid(order.total, order.currency, { email: order.email, eventId: `order-paid-${order.id}`, occurredAt: order.paidAt });
继续追踪请求的关键路径
事件方法总是返回一个承诺;无效的输入拒绝它而不是同步扔出. 为避免在用户提交请求中添加跟踪延迟, 您可以跳过 await - 不过.. 总是附加 .catch。未经处理的拒绝默认终止了节点.js进程,因此塞卡特断电绝不能达到:
cekat.userLogin({ email: user.email }).catch((error) => logger.warn({ error }, 'cekat user_login failed'));
电话同步读取了请求的访客范围,所以这个功能在适配器内.
一个成功的 Acknowledgement 表示摄入服务接受该事件 同步处理它不是一能、持久的持久性、身份解析、交付状态或特殊共同活动行为的保证.
节点请求访问者和适配器
X-Cekat-Visitor-ID 胜过 _cekat_visitor_id 饼干 数值被修剪; 空白值缺失 。 访问者ID是来自浏览器的不可信相关数据:从不使用它们进行认证或授权. 对于非框架守则,明确确立请求-局部范围:
import { runWithVisitorId } from '@cekatai/event-sdk/node';
await runWithVisitorId('visitor-123', () => cekat.customEvent('page_server_rendered', { email: '[email protected]' }));
在服务器边界使用一个适配器 。 背景是请求本地的,包括处理器内开始的同步工作.
// Express
import express from 'express';
import { visitorMiddleware } from '@cekatai/event-sdk/express';
express().use(visitorMiddleware());
// Fastify
import Fastify from 'fastify';
import { visitorPlugin } from '@cekatai/event-sdk/fastify';
await Fastify().register(visitorPlugin);
// Koa
import Koa from 'koa';
import { visitorMiddleware as koaVisitorMiddleware } from '@cekatai/event-sdk/koa';
new Koa().use(koaVisitorMiddleware());
// NestJS
import { CekatVisitorMiddleware } from '@cekatai/event-sdk/nestjs';
// consumer.apply(CekatVisitorMiddleware).forRoutes('*');
Next.j的支持是: 只有节点运行时间。在导入 Next 助手之前,在路径中宣布运行时间;边缘路由模块图形不能导入此子路径.
export const runtime = 'nodejs';
import { withCekatVisitor } from '@cekatai/event-sdk/nextjs';
export default withCekatVisitor(async (request, response) => { /* ... */ });
用于 App 路由器处理器 runWithCekatVisitor(request, () => handler()) 在相同的节点运行路线.
阿宝
在Bun 1.2.5或更新客户端时,访客范围,以及快车、快车、Koa和NestJS适配器运行不变;他们的测试套房以Bun为运行时间。 Next.js的帮助者测试也通过Bun, 但Next.js本身是否运行在Bun上是Next.js. 不需要单独的导入或构建。 Bun-native 服务器通过 Web Request 改为 fetch 处理器,所以使用 @cekatai/event-sdk/fetch数字 :
import { Client } from '@cekatai/event-sdk';
import { withCekatVisitor } from '@cekatai/event-sdk/fetch';
const cekat = new Client(Bun.env.CEKAT_ACCESS_TOKEN!);
Bun.serve({
// `this` and extra arguments such as `server` pass through unchanged.
fetch: withCekatVisitor(async (request, server) => {
const { email } = await request.json();
await cekat.userLogin({ email }); // sends the request's visitor_id
return new Response('ok');
}),
// Route handlers can be wrapped individually:
// routes: { '/login': { POST: withCekatVisitor(login) } },
});
何诺和爱丽西亚都暴露出一个标准 fetch,所以包起来,或者使用Hono中间软件:
import { Hono } from 'hono';
import { runWithCekatVisitor, withCekatVisitor } from '@cekatai/event-sdk/fetch';
const hono = new Hono();
hono.use((c, next) => runWithCekatVisitor(c.req.raw, next));
export default { fetch: hono.fetch };
// Elysia: serve its fetch handler with the wrapper instead of app.listen().
Bun.serve({ fetch: withCekatVisitor(elysiaApp.fetch) });
@cekatai/event-sdk/fetch 只需要网络 Request 财务报告和审定财务报表 AsyncLocalStorage,所以它也与Hono在Node.js上合作. 范围包括处理者及其等待或开始的一切。 处理器返回后生成的流式响应机构可能不会观察到: 已读 currentVisitorId() 在操作器中传递值.
在邦恩岛, AsyncLocalStorage 内部不恢复 AbortSignal.timeout() 听众或 MessagePort 消息处理器(它位于Node.js). 这些召回的电话不会让人来拜访,除非你先抓住并明确通过: const visitorId = currentVisitorId(); 接下来 cekat.userLogin({ email, visitorId })。测试套件覆盖的所有其他同步边界都表现在节点.js上.
1.4号前装箱
Bun 1.2.5至1.3.x有两种差异,两种差异均由Bun的HTTP客户端所造成并固定在Bun 1.4.0中:
- 无连接再利用 . 这些发布可以递出一个新的请求,即服务器关闭了中继响应,使请求被挂起,读取另一个响应的一部分,或者被发送两次. 因此,SDK为在1.4之前对Bun的每次尝试打开了新的连接(
keepalive: false) (中文(简体) ). 这为每个事件增加了一个TCP(和TLS)握手;持续地跟踪请求的关键路径,如上所示. - 被截断的响应看起来像是网络故障. 如果连接在Cekat的响应头后关闭,但在全身之前,Bun拒绝请求而不暴露状态. 改为
ResponseDecodeError(收到,没有重审) SDK看到TransportError,用同样的event_id,和报告deliveryOutcomeUnknown: true如果复试累累。 因此,重试可能再次传递同样的事件,如同任何网络故障一样. Bun 1.4.0+和Node.js上收到的回复是准确分类的.
超过1.2.5的包子没有经过测试。 见 文档/兼容性 为证据.
条纹元数据组成
使用商家的花纹客户端的助手;它不会创建花纹请求或发送Cekat事件.
import { mergeMetadata, metadataFromCurrentVisitor } from '@cekatai/event-sdk/stripe';
const metadata = mergeMetadata(merchantMetadata, metadataFromCurrentVisitor()['cekat_' + 'visitor_id']);
await stripe.paymentIntents.create({ amount: 1200, currency: 'usd', metadata });
await stripe.checkout.sessions.create({ mode: 'payment', metadata, payment_intent_data: { metadata } });
只修剪了 1–128 个字符 [A-Za-z0-9_-] 访问者成为了Frede访问者的元数据条目. 合并返回新对象,保留商钥,并保持无效或缺席的访客输入不变.
错误和交付结果
无效的本地输入拒绝方式 ValidationError 在网络一/O之前收到的答复已知道交付结果,并拒绝接受 AuthenticationError (401个), EventDefinitionNotFoundError (404个), ApiError (其他非200个)或 ResponseDecodeError (变形、截断或无法读取200). TransportError 指运输失败或SDK超时后的结果不明. 错误中保留的HTTP机构被限定为65,536字节.
运输故障,SDK超时,和HTTP 429,500,502,503,和504重试被封顶的指数式全焦(可达100ms,200ms,400ms,800ms,再取1s). 包括400人、401人和404人在内的其他身份没有再审。 一个有效的 Retry-After 头将延迟提升到服务器的值;如果服务器要求超过5秒,则呼叫会立即拒绝而不是屏蔽. 获得的200人从未被再审,即使其身体无法被读取,因为事件已被接受. 在未知结果后进行检索可产生重复事件;它们重复使用 event_id,但SDK并不能保证服务器侧分解.
浏览器访问者传播
浏览器助手读取精确 _cekat_visitor_id 饼干,它们很安全,没有访客 document 无法使用。 他们从不提出带有后端符号的请求.
使用显式浓缩作为默认逃生舱:
import { withVisitor, withVisitorRequest } from '@cekatai/event-sdk/browser';
await fetch('https://api.example.test/events', withVisitor({ method: 'POST' }));
await fetch(withVisitorRequest(new Request('https://api.example.test/events')));
现有 X-Cekat-Visitor-ID 头被保留了大小写不敏感。 如果目标来自不同方面,其中央遥感组织政策必须允许: X-Cekat-Visitor-ID 请求头.
Axios是可选的,只应附属于专门实例,而不是全过程/默认实例:
import axios from 'axios';
import { createAxiosVisitorInterceptor } from '@cekatai/event-sdk/browser/axios';
const api = axios.create({ baseURL: 'https://api.example.test' });
api.interceptors.request.use(createAxiosVisitorInterceptor());
默认禁用自动传播 。 仅使用已解析的 HTTP( S) 源/ 路径允许列表条目启用 。 匹配需要完全正常化 URL.origin 平等与平等 URL.pathname.startsWith(pathPrefix); 这不是原始的 URL 前缀匹配 。 允许进行一个活动安装 disable() 恢复原有的环球.
import { enableAutoPropagation } from '@cekatai/event-sdk/browser';
const disable = enableAutoPropagation({
allowedTargets: [{ origin: 'https://api.example.test', pathPrefix: '/v1/' }],
});
// Later, for example during application teardown:
disable();
自动截取器覆盖全球浏览器 fetch 财务报告和审定财务报表 XMLHttpRequest 只有这个 它不覆盖服务器获取,Axios,除非专用截取器注册,WebSocket/EventSource流量,导航,表单,服务-员工控制请求,或任意第三方HTTP客户端.
本地不打印软件包准备
./scripts/package --version 0.4.0 --output /absolute/empty-directory
Bun 支持被单独校验 npm run test:bun (Bun上的测试套房,包括仅Bun test/bun 服务器)和 CEKAT_NODE_RUNTIME=bun scripts/conformance (Bun上的共用合规装置)。 两者都使用Node.js和npm进行安装和类型检查.
该命令运行依赖性安装、官方兼容性核查、生产和全面依赖性审计、核准范围的依赖性门、测试、类型检查、建设、出口检查和浏览器测试;然后,它创建一个本地测试系统 .tgz 加一原子 SHA-256 manifest.json它从不出版、标志、标签或推。 从仓库运行到 npm release-node.yml 工作流程当 a node/vX.Y.Z 标签被按下;参见根释放清单.