@chamvi/chat-whatsapp (英语)
查姆维特工的WhatsApp Web.
贝利斯的Chat SDK适配器,
插入到一个 @chamvi/chat 频道.
目录
安装
npm install @chamvi/chat-whatsapp @chamvi/chat @chamvi/core @chamvi/http chat [email protected] --save
仅限无害环境管理,节点.js >=26.0.0。 。 。 . @chamvi/chat, (中文(简体) ), @chamvi/core, (中文(简体) ), chat (Chat SDK,4.44或后在 4.x行)和 baileys 是同伴的依赖关系; baileys 被钉入到一个版本的chamvi的适配器上7.0.0-rc14) (中文(简体) ). smob 是唯一的运行时间依赖。 软件包只使用 @chamvi/chat公共API:它的频道是 chatChannel() 和WhatsApp的钩子一样 platform (单位:千美元)IChatPlatform) (中文(简体) ).
使用量
createWhatsAppChat() 构建 Chat SDK Chat,“WhatsApp”及其“适配器” chatChannel()。在引擎上注册频道,订阅代理 channel.on() 并用工具回复 ctx.channels.findOneOrFail('chat').emit()数字 :
import type { LanguageModel } from 'ai';
import { z } from 'zod';
import {
Engine,
createMemoryStore,
defineModelAgent,
defineTool,
} from '@chamvi/core';
import type { IEngine } from '@chamvi/core';
import { createWhatsAppChat } from '@chamvi/chat-whatsapp';
import type { WhatsAppChatOptions } from '@chamvi/chat-whatsapp';
export function createWhatsAppEngine(
model: LanguageModel,
// auth: your secure session store; state: a Chat SDK state adapter
options: Pick<WhatsAppChatOptions, 'auth' | 'state' | 'onPairing' | 'socketFactory' | 'clock'>,
): IEngine {
const { WHATSAPP_SENDERS, APP_URL } = process.env;
if (!WHATSAPP_SENDERS || !APP_URL) {
throw new Error('Set WHATSAPP_SENDERS (phone number jids, comma separated) and APP_URL.');
}
const whatsapp = createWhatsAppChat({
// a non-secret alias of the account, not its phone number
account: 'assistant',
// only these senders start runs; everybody else is ignored
policy: { senders: WHATSAPP_SENDERS.split(',') },
resolveInvoker: (identity) => ({
id: identity.sender,
kind: 'whatsapp',
permissions: [],
}),
// a link to the approval in the chamvi UI: ids only, answered there
approvalUrl: ({ runId, approvalId }) => `${APP_URL}/ui/approvals?run=${encodeURIComponent(runId)}&approval=${encodeURIComponent(approvalId)}`,
...options,
});
const reply = defineTool({
description: 'Reply in the chat the message came from.',
inputSchema: z.object({ text: z.string() }),
execute: async ({ text }, { context }) => {
// the source chat: no address needed
await context.channels.findOneOrFail('chat').emit({ body: text });
return 'sent';
},
});
const assistant = defineModelAgent({
name: 'assistant',
model,
instructions: 'You are the owner\'s assistant on WhatsApp. Answer with the reply tool.',
// one memory per direct chat and one per group
conversation: true,
// direct messages and mentions in an allowed group
channels: [whatsapp.channel.on()],
tools: { reply },
});
return new Engine({
// memory store: conversations included; use @chamvi/store-db in production
store: createMemoryStore({ clock: options.clock }),
agents: [assistant],
channels: [whatsapp.channel],
clock: options.clock,
conversations: { authorize: ({ agent }) => agent === 'assistant' },
});
}
当设置建成时, 没有任何连接: 频道的 start (引擎的)初始化Chat,获得认证租赁,再构建套接字. 虽然账户没有对齐, onPairing 接收用于为电话渲染的 QR 引用( 它旋转); 它从未达到日志或 onError。 。 。 . setup.status() (和 onStatus报告 stopped, (中文(简体) ), connecting, (中文(简体) ), pairing, (中文(简体) ), connected, (中文(简体) ), disconnected, (中文(简体) ), logged-out, (中文(简体) ), held-elsewhere (另一个进程举行会话;开始重试而不是失败)或 failed (会话存储失败) ; setup.reset() 清除会话并再次对对而不重新启动(在 held-elsewhere) (中文(简体) ).
auth 是一个 IWhatsAppAuthProvider数字 : createStoreWhatsAppAuth({ vault, connection }) 将会话封入 chamvi 商店( 连接库 @chamvi/core)或自给(参见 业务) (中文(简体) ). 与 @chamvi/app, (中文(简体) ), whatsappModule() 给店主打电话. state 是一个聊天SDK StateAdapter; chamvi的摄取量并不取决于其分化.
谁可能开始运行是 policy数字 :
| 政策 | 允许 |
|---|---|
{ senders: [...] } | 所列电话号码 jids 的直接信息(<digits>@s.whatsapp.net,没有设备后缀) |
groups: [...] | 列表组 jids 中的信件 (<id>@g.us)来自被允许的发送者,默认只有在它们提到bot时(bot)requireGroupMention: false 放下那个 |
{ open: true } | 任何已解决的发送者; resolveInvoker 决定( 未定义否认) |
消息只有在其身份被验证、政策允许且 resolveInvoker 指定一个引用者。 机器人自己的消息,未知的发件人和一个其LID无法通过贝利斯认证的映射解决到一个电话号码的发件人被默默地拒绝:没有运行,没有回复,没有下载.
订阅、答复、核准、内存和信任 @chamvi/chat:一个消息的对话是: { account, chat jid, direct:<sender> | group:<group jid> },所以一个团体在其成员之间共享一个记忆.
限制
- 文本仅限,没有媒体下载,没有历史,没有信息分割(
CHAT_TEXT_MAX_CHARS),与每个聊天频道一样. - 交付至少是一次:每次发送都携带从消息密钥中衍生出来的WhatsApp消息id,所以重试再使用;WhatsApp是否将这样的重复投放未验证.
- 不失所取或下行摄取. 在连接器下架时到达的消息,或进程在被存储之前丢失的消息,不会被后取.
业务
通过贝利斯的WhatsApp Web是 非正式协议:WhatsApp可能更改或限制账户. 使用一个你能承受的账户 丢失并读取 何等App 向导 在现场直播之前 简而言之:
- 会话存储.
createStoreWhatsAppAuth()(和whatsappModule()(a) 存储证书和信号密钥AES-256-GCMCHAMVI_ENCRYPTION_KEYS,每批原子和栅栏 通过租赁connection:<name>(TTL 60 s, 每20 s更新一次): 杀后 - 9 下一个开始显示held-elsewhere并在租约到期后连接。 失去密钥意味着再次重设并配对(重设后在新数据密钥下再创建连接). 自己的供养者(acquire(signal, { reset? })- > (中文){ auth, saveCreds, flush, release, lost? })必须坚持以解剖和序列方式进行验证和信号密钥,只取位置(第二个持有人拒绝使用)ConnectionHeldError和, 打开reset中,当会话占据位置时,会话会空出。 chamvi用租赁的一代守护每一次授权呼叫,在释放前冲出并释放每近的租赁:一个失败的冲出被报告,并写道过活WHATSAPP_SHUTDOWN_TIMEOUT_MS报告(30 s)一旦和解,即予以释放。 结束套接字有相同的长度,所以一个死链永远不能离开租约. - 一个连接器. 每个账户进行一次部署,
Recreate停下来,不要复制两本. - 配对 仅由 QR (
onPairing的连接页面whatsappModule();没有电话号码码. - 重新连接: 意外的近距离连接与后退( )
WHATSAPP_RECONNECT:2 s增长到30 s,12个尝试. 登录( 401) 或替换会话( 440) 不: 重置( )setup.reset(),或者在仪表板上重设会话)并再次对接. - 停下来 结束套接字, 拒绝稍后的认证写入并冲出 。 Baileys可能重新测试一个密钥输入拒绝的站口的解密器(约30 s,无结果);chamvi不能保证这种消息在重启后得到处理.
- 日志: Baileys自己的日志机是无声的(它会携带配对材料),这也隐藏了它的解密和LID警告.
使用@ chamvi/ app
import { createApp } from '@chamvi/app';
import { whatsappModule } from '@chamvi/chat-whatsapp/module';
const whatsapp = whatsappModule({
// the session's connection: sealed in the app store, shown at /ui/connections/whatsapp
connection: 'whatsapp',
account: 'assistant',
state,
policy: { senders: ['[email protected]'] },
resolveInvoker: (identity) => ({ id: identity.sender, kind: 'whatsapp', permissions: [] }),
});
export default createApp({
// agents subscribe with whatsapp.on()
agents: [assistant],
modules: [whatsapp],
conversations: { authorize: ({ agent }) => agent === 'assistant' },
});
whatsappModule() (单位:千美元)@chamvi/app 是一个可选对等点) takes createWhatsAppChat()选项 auth, (中文(简体) ), onPairing 财务报告和审定财务报表 onStatus附加时 connection, (中文(简体) ), leaseTtlMs 和可选 approvalUrl (默认:下面的仪表板) CHAMVI_PUBLIC_URL) (中文(简体) ). 在设置中它需要 CHAMVI_ENCRYPTION_KEYS (单位:千美元)<id>:<base64 of 32 bytes>,逗号分隔,第一个活动;在未设置或变形时设置失败命名),将频道贡献给 AppToken.CHANNELS 连接控件到 AppToken.CONNECTIONS: 仪表板的连接页显示状态,并 connection:<name>:write 中,只包含 QR 和 重置 会话。 租的只有引擎启动时才有 所以 chamvi start --check 财务报告和审定财务报表 chamvi run-job 获取和写什么.
有了你自己的供养者, chatModule({ channel: setup.channel }) 联 合 国 @chamvi/chat/module 捐款a createWhatsAppChat() 改为频道.
API 密码
| 导出 | 持有 |
|---|---|
createWhatsAppChat(options) | { chat, ingress, channel, status(), reset(), conversation() } |
createStoreWhatsAppAuth({ vault, connection, owner?, leaseTtlMs? }) | 存储支持 IWhatsAppAuthProvider· ; WHATSAPP_CONNECTION_TYPE 'whatsapp' |
whatsappModule(options) (单位:千美元)/module(中文(简体) ) | WhatsAppModule { channel, handle, on(), to(), conversation(), status(), reset() }, (中文(简体) ), WhatsAppModuleOptions |
类型 WhatsAppChatOptions, (中文(简体) ), WhatsAppChatSetup, (中文(简体) ), StoreWhatsAppAuthOptions, (中文(简体) ), WhatsAppPolicy, (中文(简体) ), WhatsAppIdentity, (中文(简体) ), IWhatsAppAuthProvider, (中文(简体) ), WhatsAppAuthLease, (中文(简体) ), WhatsAppPairing, (中文(简体) ), WhatsAppConnectionStatus, (中文(简体) ), WhatsAppSocket, (中文(简体) ), WhatsAppSocketFactory | |
WHATSAPP_ADAPTER_NAME 'whatsapp', (中文(简体) ), WHATSAPP_RECONNECT, (中文(简体) ), WHATSAPP_SHUTDOWN_TIMEOUT_MS 30 000人 | |
错误代码 whatsapp_auth, (中文(简体) ), whatsapp_connection, (中文(简体) ), whatsapp_logged_out (单位:千美元)WHATSAPP_*_ERROR_CODE(中文(简体) ) |
整个选项参考是 何等App 向导。 。 。 .
许可证
由 所制
原载 Apache 许可证 2.0。 。 。 .