@cstar. help/js (英语)
正式类型SDK c 星报 客户支持平台.
- 原始获取 hTTP, Supabase 实时
- 类型脚本第一,包含完整类型定义
- 重点切入点 你和CStar一起建设
- 无害环境管理+CJS 出口
安装
npm install @cstar.help/js
我需要哪个SDK?
cStar有一个包,对不同的工作流程有单独的切入点. 从这里开始 :
| 导入 | 使用大小写 | 运行于 | 需要认证 | 密钥类型 |
|---|---|---|---|---|
@cstar.help/js | 管理仪表板/后端集成 | 只有服务器 | 对 | 保密( O)sk_*(中文(简体) ) |
@cstar.help/js/chat | 客户聊天部件 | 浏览器 | 对 | HMAC 或客户会议 |
@cstar.help/js/library | 公共知识库 | 浏览器或服务器 | 没有 | 无 |
@cstar.help/js/community | 公共社区论坛 | 浏览器或服务器 | 没有 | 无 |
@cstar.help/js/webhook | Webhook 签名验证 | 只有服务器 | 没有 | 签名秘密 |
@cstar.help/js/auth | 客户注册和登录 | 浏览器 | 没有 | 无(teamSlug(中文(简体) ) |
担保模式
服务器 API 和客户聊天认证方式不同 :
- 秘密 API 密钥 (单位:千美元)
sk_live_*, (中文(简体) ),sk_test_*在密钥权限内授权团队API操作. 放在服务器上. - 可公布的 API 密钥 (单位:千美元)
pk_live_*, (中文(简体) ),pk_test_*用于公共SDK(LibraryClient, (中文(简体) ),CommunityClient和GET /auth/whoami. Team API 端点以 403 拒绝:publishable_key_forbidden读取publishable_key_write在写,所以CStarClient需要一把密钥 他们不识别客户或授权客户聊天. - 聊天频率 使用一个
teamSlug,然后通过 HMAC 身份验证或客户会话认证客户。 它没有API键选项. 在您的服务器上保留 HMAC 签名机密 .
搭建辅助仪表板? 使用
CStarClient在你的后门。 在您的网站上添加对话吗 ? 使用ChatClient和以下客户认证选项之一.
服务器- Side: 管理 API 客户端
仅限服务器侧.
CStarClient需要密钥( e)sk_*),并且绝不能在浏览器代码中使用. SDK会警告您,如果它检测到浏览器环境.
管理入场券,客户,文章,团队成员,设置,游戏系统,以及其他一切.
import { CStarClient } from '@cstar.help/js';
const apiKey = process.env.CSTAR_SECRET_KEY; // sk_live_... or sk_test_...
const teamId = process.env.CSTAR_TEAM_ID;
if (!apiKey || !teamId) throw new Error('Set CSTAR_SECRET_KEY and CSTAR_TEAM_ID.');
const cstar = new CStarClient({ apiKey, teamId });
// List open tickets
const { data: tickets } = await cstar.tickets.list({ status: 'open' });
// Create a ticket
const ticket = await cstar.tickets.create({
title: 'Help with billing',
customerId: 'cus_abc123'
});
// Auto-paginate through all tickets
for await (const ticket of cstar.tickets.listAutoPaginating({ status: 'open' })) {
console.log(ticket.title);
}
创建、检索和更新的资源直接返回。 清单方法返回 { data, pagination, hasMore }搜索返回 { results, total, query }读取 cstar.lastMeta.requestId 当您需要申请身份证时,立即拨打电话.
私人笔记和信件历史
用密钥在服务器上运行信件管理 。 内部笔记留在支援队内部.
const note = await cstar.tickets.messages.create('tkt_123', {
content: 'The customer has already tried resetting their password.',
messageType: 'internal'
});
console.log(note.isInternal);
const page = await cstar.tickets.messages.list('tkt_123', { page: 2, pageSize: 25 });
console.log(page.data, page.pagination.hasMore);
这个 isInternal 布尔在创建注释时也被接受 。 如果你提供两种隐私选择 他们必须同意 信件历史被分解, 因此请求下一页同时 hasMore 这是真的.
完整资源参考
核心资源:入场券,顾客和知识库.
| 资源 | 方法 |
|---|---|
cstar.tickets | .list() .get(id) .create(params) .update(id, params) .del(id) .listAutoPaginating() |
cstar.tickets.messages | .list(ticketId, params?) .create(ticketId, params) |
cstar.customers | .list() .get(id) .create(params) .update(id, params) .del(id) .listAutoPaginating() |
cstar.articles | .list() .get(id) .create(params) .update(id, params) .del(id) .listAutoPaginating() |
cstar.categories | .list() .get(id) .create(params) .update(id, params) .del(id) |
团队配置( C):成员、设置和定制.
| 资源 | 方法 |
|---|---|
cstar.members | .list() .get(id) .update(id, params) .del(id) |
cstar.members.invites | .list() .create(params) .del(id) |
cstar.settings | .get() .update(params) .getBusinessHours() .updateBusinessHours(params) .getWidget() .updateWidget(params) |
cstar.settings.statuses | .list() .create(params) .update(key, params) .del(key) .reorder(keys) |
cstar.settings.quickReplies | .list() .create(params) .update(id, params) .del(id) .reorder(ids) |
cstar.customFields | .list() .create(params) .update(id, params) .del(id) .reorder(ids) |
cstar.notifications | .list({ userId }) .unreadCount(userId) .markRead(id, userId) .markAllRead(userId) |
业务:分析、批量行动和数据管理.
| 资源 | 方法 |
|---|---|
cstar.analytics | .overview(params?) .performance(params?) .library(params?) .csatStats(params?) |
cstar.sla | .list() .create(params) .update(id, params) .del(id) .reorder(ids) .metrics(params?) |
cstar.bulk | .update(params) .del(params) |
cstar.export | .create(params) |
cstar.import | .create(params) .logs(params?) .getLog(id) |
cstar.search | .query(params) |
cstar.tags | .list() .merge(params) .remove(tag) .del(tag) |
cstar.activity | .list(params?) |
cstar.auditLog | .list(params?) |
cstar.customerGroups | .list() .get(id) .create(params) .update(id, params) .del(id) |
游戏:完整的游戏系统.
| 资源 | 方法 |
|---|---|
cstar.game | .player(params?) .getPlayer(memberId) .leaderboard(params?) .myRank(params?) |
cstar.game.boss | .current() .isActive() .spawn(params?) .damage(params) .defeats(params?) .getDefeat(id) |
cstar.game.achievements | .list(params?) .unlocked(params) .get(id, params?) |
cstar.game.quests | .today(params?) .history(params?) |
cstar.game.puzzles | .today(params?) .complete(params) .streak(params) .leaderboard(params) |
cstar.game.oneUps | .list(params?) .send(params) .remaining(params) |
cstar.game.highFives | .list(params?) .send(params) .canSend(teamId, params) |
cstar.game.cosmetics | .list(params) .getPreferences(params) .updatePreferences(params) |
cstar.game.seasons | .list(params?) .current() .stats(seasonId, params) |
cstar.game.skills | .get(params) .allocate(params) .reset(params) |
游戏写作属于您的服务器, 带有密钥 API 。 使用cStar的用户和团队UUID. 1起和高5起默认发件人为关键创建人. 谜题记分牌需要一个 puzzleId; 使用螺纹板 { type: 'streaks' }。化妆品清单要求 userId。 。 。 .
化妆品和季节清单返回 { data, pagination, hasMore }. 退回一上五张名单 { object: 'list', data }。今天的追求回归 { quests, completedToday, totalQuests, allComplete, resetsAt } (每次探险都要自己付出代价) xpReward 财务报告和审定财务报表 goldReward;没有所有遗赠奖金)。 单一资源返回裸物.
高级:AI,自动化,取景,计费,网呼.
| 资源 | 方法 |
|---|---|
cstar.ai | .run(params) .autoTag(ticketId) .suggestReply(ticketId) .summarize(ticketId) .improve(text) |
cstar.automations | .list() .get(id) .create(params) .update(id, params) .del(id) .toggle(id) .reorder(ids) .test(id, params) .executions(id) .allExecutions() .evaluate(params) |
cstar.views | .list() .get(id) .create(params) .update(id, params) .del(id) .execute(id, params?) |
cstar.billing | .subscription() .portal(params?) |
cstar.webhooks | .list() .get(id) .create(params) .update(id, params) .del(id) .test(id) |
cstar.community.posts | .list() .get(id) .create(params) .update(id, params) .del(id) |
cstar.community.topics | .list() .get(id) |
cstar.attachments | .upload(file, params) .list(params?) .get(id) .del(id) |
用法实例
// Team analytics
const overview = await cstar.analytics.overview({ period: 'week' });
console.log(`${overview.tickets?.open ?? 0} open tickets this week`);
// SLA rules
const { data: rules } = await cstar.sla.list();
// Cheer on another team. The sender defaults to your API key's creator.
const highFive = await cstar.game.highFives.send({
recipientTeamId: '550e8400-e29b-41d4-a716-446655440003',
message: 'Amazing work!'
});
console.log(`A high five from ${highFive.senderTeam.name}`);
// AI-powered reply suggestion
const suggestion = await cstar.ai.suggestReply('tkt_abc123');
// Bulk close resolved tickets
await cstar.bulk.update({
resource: 'tickets',
ids: ['tkt_1', 'tkt_2', 'tkt_3'],
data: { status: 'closed' }
});
// Export closed tickets as JSON with raw rows and per-resource counts
const exported = await cstar.export.create({
resources: ['tickets'],
filters: { status: 'closed' },
format: 'json'
});
console.log(exported.summary.tickets);
// CSV is text and supports one resource at a time
const csv = await cstar.export.create({ resources: ['tickets'], format: 'csv' });
// Saved views
const view = await cstar.views.create({
name: 'Critical Unresolved',
entityType: 'tickets',
filters: { priority: 'critical', status: 'open' }
});
const { data: results } = await cstar.views.execute(view.id);
// Search across everything
const { results: searchResults } = await cstar.search.query({
query: 'billing issue',
types: ['tickets', 'customers']
});
客户端- Side: 聊天部件 SDK
在你的网站上建立一种在家中感觉的聊天体验. ChatClient 处理浏览器中没有团队 API 密钥的客户对话.
聊天客户端支持两种认证模式:
- HMAC: (韩语) 您认证的后端 标出客户的身份 与团队的签名秘密。 当您的网站已经知道是谁签的字时使用这个 .
- 会话 : 使用 cStar 客户证书签名,或者提供现有的 cStar 客户访问令牌. 用于独立的部件或客户端门户 .
选择您的团队部件配置支持的流程 . chat.getAuthMode() 返回时 'hmac', (中文(简体) ), 'session',或 null 在认证或断开后。 会话登录设置会话模式; SDK 也读取服务器的 X-Cstar-Auth-Mode 响应头.
常规
创建 /api/support/identity 在自己的后端。 它必须从经认证的用户中获取客户并返回 { customer, signature } 利用你的团队签名的秘密。 将精确的有效载荷发送到 cStar; 在浏览器中生成一个新的时间戳会改变签名的数据 。 这个 身份指南 显示签约合同.
import { ChatClient, type IdentifyParams } from '@cstar.help/js/chat';
const chat = new ChatClient({ teamSlug: 'acme' });
const response = await fetch('/api/support/identity', { credentials: 'same-origin' });
if (!response.ok) throw new Error('Could not verify your support identity');
const { customer, signature } = (await response.json()) as {
customer: IdentifyParams;
signature: string;
};
await chat.identify(customer, signature);
会话(电子邮件/密码)
import { ChatClient } from '@cstar.help/js/chat';
const chat = new ChatClient({ teamSlug: 'acme' });
// Use the values from your customer's sign-in form.
const { customer, teamId } = await chat.loginWithCredentials({
email: '[email protected]',
password: 'your-customer-password'
});
console.log(`Hello, ${customer.name ?? customer.email}!`, teamId);
客户端内部保存访问符. 公开结果包含 customer 财务报告和审定财务报表 teamId,不访问或刷新符号。 这在已有客户中显示; 它不创建账户 .
会话( 现有客户代号)
通过现有的 cStar 客户符作为对象 。 一个不相干的Supabase项目的令牌不设cStar客户会话. 在您的应用程序中包含 cStar 团队 UUID 。 否则客户端会在消息,社区和实时请求之前解决其配置的团队 sattle.
import { ChatClient, type LoginWithSessionParams } from '@cstar.help/js/chat';
async function connectCustomerSession(session: LoginWithSessionParams) {
const chat = new ChatClient({ teamSlug: 'acme' });
await chat.loginWithSession(session); // { accessToken, teamId?, customerName? }
return chat;
}
认证( 两种模式)
const { data: tickets, pagination } = await chat.tickets.list();
console.log(`${tickets.length} conversations`, pagination.hasMore);
// Use a ticket ID returned by the customer API.
const ticket = tickets[0];
let unsubscribe = () => {};
if (ticket) {
const history = await chat.messages.list(ticket.id);
console.log(history); // Message[]
await chat.messages.send(ticket.id, 'Thanks for the help!');
unsubscribe = chat.onMessage(ticket.id, (message) => {
console.log(`${message.sender_name}: ${message.content}`);
});
}
// Wire this to your UI's close/unmount handler and account-change cleanup.
function closeChat() {
unsubscribe();
chat.disconnect();
}
输入错误
HTTP 和网络故障使用 : ChatClientError。服务器响应可能提供 requestId 通过 X-Request-Id 页眉; 是 null 当无法使用时。 其他故障,如反应不正确JSON,仍然可以抛出普通错误.
客户端消息发送为每次有意回复生成一个新的重试密钥,并最多两次重试网络或服务器故障. 每次重试使用相同的密钥并返回原保存的回复. 一个终端 ChatClientError 将密钥保留在 error.idempotencyKey重用时 chat.messages.send(ticketId, content, { idempotencyKey }) 手动重试同一答复。 将草稿和密钥放在一起;当消息或票面有变化时使用新密钥. 收据持续24小时,并保留给客户、团队和直播/测试模式.
过 { signal } 以取消发送或重试延迟。 对于一个可以注销的UI,生成并保留自己的 idempotencyKey 发送前。 已取消的请求可能已被保存 。 对话历史包括: client_request_key 所以,你的UI可以调和一个待发泡 与它确认的答复。 带有相同文本的单独发函仍为单独发函. 这些信件重试不适用于票款创建或其他客户写作.
import {
ChatClientError,
ChatClientAuthError,
ChatClientRateLimitError,
ChatClientServerError,
ChatClientNetworkError
} from '@cstar.help/js/chat';
try {
await chat.identify(customer, signature);
} catch (err) {
if (err instanceof ChatClientAuthError) {
// Authentication failed or the active customer session changed.
} else if (err instanceof ChatClientRateLimitError) {
// 429: respect err.retryAfter when the server supplies it.
} else if (err instanceof ChatClientServerError) {
// Server failure: keep the draft and check the conversation.
} else if (err instanceof ChatClientNetworkError) {
// Network failure: err.originalError has the underlying cause.
} else if (err instanceof ChatClientError) {
console.log('Error', err.code, err.statusCode, 'requestId:', err.requestId);
} else {
throw err;
}
}
客户端:公共知识库
搜索和浏览您的公共帮助中心. 无需认证。 。 。 .
import { LibraryClient } from '@cstar.help/js/library';
const library = new LibraryClient({ teamSlug: 'acme' });
const categories = await library.categories();
const results = await library.search('reset password');
const article = await library.article('how-to-reset-password');
客户-系统:公共社区
浏览您的公共社区论坛 . 无需认证。 。 。 .
import { CommunityClient } from '@cstar.help/js/community';
const community = new CommunityClient({ teamSlug: 'acme' });
const topics = await community.topics();
const { posts } = await community.posts({ topicSlug: 'feature-requests', sort: 'votes' });
const { post, comments } = await community.post('dark-mode-support');
服务器系统: Webhook 校验
校验您服务器上收到的 Webhook 签名 .
import { constructEvent } from '@cstar.help/js/webhook/node';
// In your webhook handler (Node). It throws if the signature is invalid.
const event = constructEvent(rawBody, signature, 'whsec_your_secret');
switch (event.type) {
case 'ticket.created':
console.log('New ticket:', event.data.ticket.title);
break;
case 'customer.created':
console.log('New customer:', event.data.customer.email);
break;
}
对于边缘跑步时间(Cloudflare Workers, Deno),使用ASync变体:
import { constructEventAsync } from '@cstar.help/js/webhook';
const event = await constructEventAsync(rawBody, signature, secret);
配置
const cstar = new CStarClient({
apiKey: 'sk_live_...', // Required: must be a secret key (sk_*)
teamId: '8f14e45f-ea2b-4c8b-9f1e-2a6b3c4d5e6f', // Required: your team ID (a UUID; GET /api/v1/auth/whoami returns it)
baseUrl: 'https://...', // Optional: defaults to https://www.cstar.help
version: '2026-03-01', // Optional: API version header
maxRetries: 3, // Optional: retry attempts for retry-safe failures and 429
timeout: 30000, // Optional: request timeout in ms
fetch: myFetch, // Optional: send requests through this instead of the global fetch
realtime: { types: ['ticket.created', 'message.created'] } // Optional: realtime stream options (types, eventSource polyfill, autoReconnect, maxRetries)
});
自动读取网络错误和服务器错误。 邮政和邮政
只在您通过时请求重试这些失败 idempotencyKey 在现有的
请求选项。 丢失的响应可能跟随成功的写法,所以SDK
否则,不重复突变,就显示错误。 限制费率
请求仍在重试, 因为 API 在执行操作前拒绝它们 .
await cstar.tickets.create(
{ title: 'Cannot reset password', customerId: 'cus_...' },
{ idempotencyKey: 'support-issue-123' }
);
测试模式
测试模式从您的 API 密钥前缀自动检测 :
const cstar = new CStarClient({
apiKey: 'sk_test_abc123...',
teamId: process.env.CSTAR_TEAM_ID! // a UUID
});
console.log(cstar.isTestMode); // true
// All operations use test data, so no real customers are affected
处理错误
所有 API 错误抛出已键入的例外 :
import {
CStarError,
CStarAuthenticationError,
CStarConflictError,
CStarRateLimitError,
CStarNotFoundError,
CStarValidationError
} from '@cstar.help/js';
try {
await cstar.tickets.get('tkt_nonexistent');
} catch (err) {
if (err instanceof CStarNotFoundError) {
console.log('Ticket not found:', err.message);
} else if (err instanceof CStarValidationError) {
console.log('Invalid param:', err.param);
} else if (err instanceof CStarRateLimitError) {
console.log('Rate limited, retry after:', err.retryAfter, 'seconds');
} else if (err instanceof CStarConflictError) {
// A unique-key conflict, an Idempotency-Key still in use, or the team's
// webhook limit (code 'webhook_limit_reached': delete unused webhooks first).
console.log('Conflict:', err.code);
} else if (err instanceof CStarAuthenticationError) {
console.log('Bad API key');
} else if (err instanceof CStarError) {
console.log('API error:', err.code, err.statusCode);
}
}
目 录
安全重试创建/更新操作 :
const ticket = await cstar.tickets.create(
{ title: 'Billing issue', customerId: 'cus_abc' },
{ idempotencyKey: 'create-billing-issue-usr123' }
);
24小时内,同一键相同的请求返回第一个成功
反应。 同一个钥匙和不同的身体扔 CStarValidationError
(单位:千美元)idempotency_key_reused,第422页)。 虽然第一个请求仍在运行
API 答案 409 idempotency_key_in_use 与 Retry-After。从0.18.1起,客户端在内部等待和重复 maxRetries; 0.1.8.0 抛出
CStarConflictError。 。 。 .
API 忽略打开的密钥 webhooks.create, (中文(简体) ), webhooks.listen 财务报告和审定财务报表
export.create,所以一个键不能让他们的复试安全。 从0.18.2起
客户端不会在这些呼叫中发送密钥, 也不会重试网络错误
或 5xx; 0. 18.1 及更早时仍然重试它们, 因此将键留出( 没有
一个客户端不重试它们)或使用客户端 maxRetries: 0检查
webhooks.list() 在重试之前 webhooks.create重复 export.create
只读取您的数据( 无保存) 。 重复 webhooks.listen 是一个
第二 CLI 监听器: 用 webhooks.unlisten(id),或者在之后被覆盖
五分钟没有心跳.
所需资源
- 节点.js 22+(匹配支持的Supabase依赖)
- 类型脚本 5.0+(用于类型定义)
许可证
麻省理工学院