New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

aibot-node-sdk

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

aibot-node-sdk

企业微信智能机器人 Node.js SDK - WebSocket 长连接通道

latest
Source
npmnpm
Version
1.0.3
Version published
Weekly downloads
37
48%
Maintainers
1
Weekly downloads
 
Created
Source

@wecom/aibot-node-sdk

企业微信智能机器人 Node.js SDK —— 基于 WebSocket 长连接通道,提供消息收发、流式回复、模板卡片、事件回调、文件下载解密、媒体素材上传等核心能力。

✨ 特性

  • 🔗 WebSocket 长连接 — 基于 wss://openws.work.weixin.qq.com 内置默认地址,开箱即用
  • 🔐 自动认证 — 连接建立后自动发送认证帧(botId + secret)
  • 💓 心跳保活 — 自动维护心跳,连续未收到 ack 时自动判定连接异常
  • 🔄 断线重连 — 指数退避重连策略(1s → 2s → 4s → ... → 30s 上限),支持自定义最大重连次数
  • 📨 消息分发 — 自动解析消息类型并触发对应事件(text / image / mixed / voice / file)
  • 🌊 流式回复 — 内置流式回复方法,支持 Markdown 和图文混排
  • 🃏 模板卡片 — 支持回复模板卡片消息、流式+卡片组合回复、更新卡片
  • 📤 主动推送 — 支持向指定会话主动发送 Markdown、模板卡片或媒体消息,无需依赖回调帧
  • 📡 事件回调 — 支持进入会话、模板卡片按钮点击、用户反馈等事件
  • 串行回复队列 — 同一 req_id 的回复消息串行发送,自动等待回执
  • 🔒 文件下载解密 — 内置 AES-256-CBC 文件解密,每个图片/文件消息自带独立的 aeskey
  • 📎 媒体素材上传 — 支持分片上传临时素材(file/image/voice/video),自动管理并发与重试
  • 🪵 可插拔日志 — 支持自定义 Logger,内置带时间戳的 DefaultLogger
  • 📦 双模块格式 — 同时输出 CJS / ESM,附带完整 TypeScript 类型声明

📦 安装

npm install @wecom/aibot-node-sdk
# 或
yarn add @wecom/aibot-node-sdk

🚀 快速开始

import AiBot from '@wecom/aibot-node-sdk';
import type { WsFrame } from '@wecom/aibot-node-sdk';
import { generateReqId } from '@wecom/aibot-node-sdk';

// 1. 创建客户端实例
const wsClient = new AiBot.WSClient({
  botId: 'your-bot-id',       // 企业微信后台获取的机器人 ID
  secret: 'your-bot-secret',  // 企业微信后台获取的机器人 Secret
});

// 2. 建立连接(支持链式调用)
wsClient.connect();

// 3. 监听认证成功
wsClient.on('authenticated', () => {
  console.log('🔐 认证成功');
});

// 4. 监听文本消息并进行流式回复
wsClient.on('message.text', (frame: WsFrame) => {
  const content = frame.body.text?.content;
  console.log(`收到文本: ${content}`);

  const streamId = generateReqId('stream');

  // 发送流式中间内容
  wsClient.replyStream(frame, streamId, '正在思考中...', false);

  // 发送最终结果
  setTimeout(() => {
    wsClient.replyStream(frame, streamId, `你好!你说的是: "${content}"`, true);
  }, 1000);
});

// 5. 监听进入会话事件(发送欢迎语)
wsClient.on('event.enter_chat', (frame: WsFrame) => {
  wsClient.replyWelcome(frame, {
    msgtype: 'text',
    text: { content: '您好!我是智能助手,有什么可以帮您的吗?' },
  });
});

// 6. 优雅退出
process.on('SIGINT', () => {
  wsClient.disconnect();
  process.exit(0);
});

📖 API 文档

WSClient

核心客户端类,继承自 EventEmitter,提供连接管理、消息收发等功能。

构造函数

const wsClient = new WSClient(options: WSClientOptions);

方法一览

方法说明返回值
connect()建立 WebSocket 连接,连接后自动认证this(支持链式调用)
disconnect()主动断开连接void
reply(frame, body, cmd?)通过 WebSocket 通道发送回复消息(通用方法)Promise<WsFrame>
replyStream(frame, streamId, content, finish?, msgItem?, feedback?)发送流式文本回复(支持 Markdown)Promise<WsFrame>
replyWelcome(frame, body)发送欢迎语回复(文本或模板卡片),需 5s 内调用Promise<WsFrame>
replyTemplateCard(frame, templateCard, feedback?)回复模板卡片消息Promise<WsFrame>
replyStreamWithCard(frame, streamId, content, finish?, options?)流式消息 + 模板卡片组合回复Promise<WsFrame>
updateTemplateCard(frame, templateCard, userids?)更新模板卡片(响应 template_card_event),需 5s 内调用Promise<WsFrame>
sendMessage(chatid, body)主动发送消息(Markdown / 模板卡片 / 媒体),无需回调帧Promise<WsFrame>
uploadMedia(fileBuffer, options)上传临时素材(三步分片上传),返回 media_idPromise<UploadMediaFinishResult>
replyMedia(frame, mediaType, mediaId, videoOptions?)被动回复媒体消息(file/image/voice/video)Promise<WsFrame>
sendMediaMessage(chatid, mediaType, mediaId, videoOptions?)主动发送媒体消息Promise<WsFrame>
downloadFile(url, aesKey)下载文件并 AES 解密,返回 Buffer 及文件名Promise<{ buffer: Buffer; filename?: string }>

属性

属性说明类型
isConnected当前 WebSocket 连接状态boolean
api内部 API 客户端实例(高级用途)WeComApiClient

replyStream 详细说明

发送流式文本回复(便捷方法,支持 Markdown)。

wsClient.replyStream(
  frame: WsFrameHeaders, // 收到的原始 WebSocket 帧(透传 req_id),也可直接传完整 WsFrame 对象
  streamId: string,      // 流式消息 ID(使用 generateReqId('stream') 生成)
  content: string,       // 回复内容(支持 Markdown),最长 20480 字节
  finish?: boolean,      // 是否结束流式消息,默认 false
  msgItem?: ReplyMsgItem[], // 图文混排项(仅 finish=true 时有效,最多 10 个)
  feedback?: ReplyFeedback, // 反馈信息(仅首次回复时设置)
);

使用示例:

const streamId = generateReqId('stream');

// 发送流式中间内容
await wsClient.replyStream(frame, streamId, '正在处理中...', false);

// 发送最终结果(finish=true 表示结束流)
await wsClient.replyStream(frame, streamId, '处理完成!结果是...', true);

replyWelcome 详细说明

发送欢迎语回复,需在收到 event.enter_chat 事件 5 秒内调用,超时将无法发送。

// 文本欢迎语
wsClient.replyWelcome(frame, {
  msgtype: 'text',
  text: { content: '欢迎!' },
});

// 模板卡片欢迎语
wsClient.replyWelcome(frame, {
  msgtype: 'template_card',
  template_card: { card_type: 'text_notice', main_title: { title: '欢迎' } },
});

replyTemplateCard 详细说明

回复模板卡片消息。收到消息回调或进入会话事件后使用。

wsClient.replyTemplateCard(
  frame: WsFrameHeaders,     // 收到的原始 WebSocket 帧
  templateCard: TemplateCard, // 模板卡片内容
  feedback?: ReplyFeedback,   // 反馈信息(可选)
);

replyStreamWithCard 详细说明

发送流式消息 + 模板卡片组合回复。首次回复时必须返回 stream 的 id;template_card 同一消息只能回复一次。

wsClient.replyStreamWithCard(
  frame: WsFrameHeaders,   // 收到的原始 WebSocket 帧
  streamId: string,         // 流式消息 ID
  content: string,          // 回复内容(支持 Markdown)
  finish?: boolean,         // 是否结束流式消息,默认 false
  options?: {
    msgItem?: ReplyMsgItem[];       // 图文混排项(仅 finish=true 时有效)
    streamFeedback?: ReplyFeedback; // 流式消息反馈信息(首次回复时设置)
    templateCard?: TemplateCard;    // 模板卡片内容(同一消息只能回复一次)
    cardFeedback?: ReplyFeedback;   // 模板卡片反馈信息
  },
);

使用示例:

const streamId = generateReqId('stream');

// 首次回复:带卡片
await wsClient.replyStreamWithCard(frame, streamId, '正在处理...', false, {
  templateCard: {
    card_type: 'button_interaction',
    main_title: { title: '操作面板' },
    button_list: [{ text: '确认', key: 'confirm' }],
    task_id: `task_${Date.now()}`,
  },
});

// 流式结束
await wsClient.replyStreamWithCard(frame, streamId, '处理完成!', true);

updateTemplateCard 详细说明

更新模板卡片,需在收到 event.template_card_event 事件 5 秒内调用。

wsClient.updateTemplateCard(
  frame: WsFrameHeaders,     // 对应事件的 WebSocket 帧(需包含该事件的 req_id)
  templateCard: TemplateCard, // 模板卡片内容(task_id 需与回调收到的 task_id 一致)
  userids?: string[],         // 要替换模版卡片消息的 userid 列表,不填则替换所有用户
);

sendMessage 详细说明

主动向指定会话推送消息,无需依赖收到的回调帧。

wsClient.sendMessage(
  chatid: string,  // 会话 ID,单聊填用户的 userid,群聊填对应群聊的 chatid
  body: SendMarkdownMsgBody | SendTemplateCardMsgBody | SendMediaMsgBody,
);

使用示例:

// 发送 Markdown 消息
await wsClient.sendMessage('userid_or_chatid', {
  msgtype: 'markdown',
  markdown: { content: '这是一条**主动推送**的消息' },
});

// 发送模板卡片消息
await wsClient.sendMessage('userid_or_chatid', {
  msgtype: 'template_card',
  template_card: { card_type: 'text_notice', main_title: { title: '通知' } },
});

uploadMedia 详细说明

通过 WebSocket 长连接执行三步分片上传:init → chunk × N → finish

  • 单个分片不超过 512KB(Base64 编码前),最多 100 个分片(约 50MB 上限)
  • 自动根据分片数调整并发数(1~4 分片全并发;5~10 分片并发 3;>10 分片并发 2)
  • 单分片上传失败自动重试(最多 2 次)
wsClient.uploadMedia(
  fileBuffer: Buffer,          // 文件 Buffer
  options: UploadMediaOptions, // { type: WeComMediaType, filename: string }
): Promise<UploadMediaFinishResult>;  // { type, media_id, created_at }

使用示例:

import fs from 'fs';

// 上传图片
const imageBuffer = fs.readFileSync('/path/to/image.png');
const result = await wsClient.uploadMedia(imageBuffer, {
  type: 'image',
  filename: 'image.png',
});
console.log(`上传成功,media_id: ${result.media_id}`);

// 使用 media_id 回复图片消息
await wsClient.replyMedia(frame, 'image', result.media_id);

replyMedia 详细说明

被动回复媒体消息(通过 aibot_respond_msg 通道)。

wsClient.replyMedia(
  frame: WsFrameHeaders,    // 收到的原始 WebSocket 帧
  mediaType: WeComMediaType, // 媒体类型:'file' | 'image' | 'voice' | 'video'
  mediaId: string,           // 临时素材 media_id(通过 uploadMedia 获取)
  videoOptions?: {           // 视频消息可选参数(仅 mediaType='video' 时生效)
    title?: string;
    description?: string;
  },
);

sendMediaMessage 详细说明

主动发送媒体消息(通过 aibot_send_msg 通道推送)。

wsClient.sendMediaMessage(
  chatid: string,            // 会话 ID
  mediaType: WeComMediaType, // 媒体类型:'file' | 'image' | 'voice' | 'video'
  mediaId: string,           // 临时素材 media_id
  videoOptions?: {           // 视频消息可选参数(仅 mediaType='video' 时生效)
    title?: string;
    description?: string;
  },
);

downloadFile 使用示例

// aesKey 取自消息体中的 image.aeskey 或 file.aeskey
wsClient.on('message.image', async (frame: WsFrame) => {
  const body = frame.body;
  const { buffer, filename } = await wsClient.downloadFile(body.image?.url, body.image?.aeskey);
  console.log(`文件名: ${filename}, 大小: ${buffer.length} bytes`);
});

⚙️ 配置选项

WSClientOptions 完整配置:

参数类型必填默认值说明
botIdstring机器人 ID(企业微信后台获取)
secretstring机器人 Secret(企业微信后台获取)
reconnectIntervalnumber1000重连基础延迟(毫秒),实际延迟按指数退避递增(1s → 2s → 4s → ... → 30s 上限)
maxReconnectAttemptsnumber10最大重连次数(-1 表示无限重连)
heartbeatIntervalnumber30000心跳间隔(毫秒)
requestTimeoutnumber10000HTTP 请求超时时间(毫秒)
wsUrlstringwss://openws.work.weixin.qq.com自定义 WebSocket 连接地址
loggerLoggerDefaultLogger自定义日志实例

📡 事件列表

所有事件均通过 wsClient.on(event, handler) 监听:

事件回调参数说明
connectedWebSocket 连接建立
authenticated认证成功
disconnectedreason: string连接断开
reconnectingattempt: number正在重连(第 N 次)
errorerror: Error发生错误
messageframe: WsFrame<BaseMessage>收到消息(所有类型)
message.textframe: WsFrame<TextMessage>收到文本消息
message.imageframe: WsFrame<ImageMessage>收到图片消息
message.mixedframe: WsFrame<MixedMessage>收到图文混排消息
message.voiceframe: WsFrame<VoiceMessage>收到语音消息
message.fileframe: WsFrame<FileMessage>收到文件消息
message.videoframe: WsFrame<VideoMessage>收到视频消息
eventframe: WsFrame<EventMessage>收到事件回调(所有事件类型)
event.enter_chatframe: WsFrame<EventMessage>收到进入会话事件(用户当天首次进入单聊会话)
event.template_card_eventframe: WsFrame<EventMessage>收到模板卡片事件(用户点击卡片按钮)
event.feedback_eventframe: WsFrame<EventMessage>收到用户反馈事件

📋 消息类型

SDK 支持以下消息类型(MessageType 枚举):

类型说明
Text'text'文本消息
Image'image'图片消息(URL 已加密,使用消息中的 image.aeskey 解密)
Mixed'mixed'图文混排消息(包含 text / image 子项)
Voice'voice'语音消息(已转文本)
File'file'文件消息(URL 已加密,使用消息中的 file.aeskey 解密)
Video'video'视频消息(URL 已加密,使用消息中的 video.aeskey 解密)

SDK 支持以下事件类型(EventType 枚举):

类型说明
EnterChat'enter_chat'进入会话事件:用户当天首次进入机器人单聊会话
TemplateCardEvent'template_card_event'模板卡片事件:用户点击模板卡片按钮
FeedbackEvent'feedback_event'用户反馈事件:用户对机器人回复进行反馈

SDK 支持以下媒体类型(WeComMediaType 类型):

类型说明
'file'文件
'image'图片
'voice'语音
'video'视频

🃏 模板卡片类型

SDK 支持以下模板卡片类型(TemplateCardType 枚举):

类型说明
TextNotice'text_notice'文本通知模版卡片
NewsNotice'news_notice'图文展示模版卡片
ButtonInteraction'button_interaction'按钮交互模版卡片
VoteInteraction'vote_interaction'投票选择模版卡片
MultipleInteraction'multiple_interaction'多项选择模版卡片

🔀 消息帧结构

WsFrame<T>

interface WsFrame<T = any> {
  cmd?: string;              // 命令类型
  headers: {
    req_id: string;          // 请求 ID(回复时需透传)
    [key: string]: any;
  };
  body?: T;                  // 消息体(泛型,默认 any)
  errcode?: number;          // 响应错误码
  errmsg?: string;           // 响应错误信息
}

BaseMessage(消息体基础结构)

interface BaseMessage {
  msgid: string;             // 消息唯一标识
  aibotid: string;           // 机器人 ID
  chatid?: string;           // 群聊 ID(群聊时返回)
  chattype: 'single' | 'group';  // 会话类型
  from: { userid: string };  // 发送者信息
  create_time?: number;      // 事件产生的时间戳
  response_url?: string;     // 支持主动回复消息的临时 url
  msgtype: string;           // 消息类型
  quote?: QuoteContent;      // 引用消息内容
}

EventMessage(事件消息结构)

interface EventMessage {
  msgid: string;             // 本次回调的唯一性标志
  create_time: number;       // 事件产生的时间戳
  aibotid: string;           // 智能机器人 ID
  chatid?: string;           // 会话 ID(仅群聊时返回)
  chattype?: 'single' | 'group';  // 会话类型
  from: EventFrom;           // 事件触发者信息(含 userid、corpid?)
  msgtype: 'event';          // 消息类型,固定为 event
  event: EventContent;       // 事件内容
}

🪵 自定义日志

实现 Logger 接口即可自定义日志输出:

interface Logger {
  debug(message: string, ...args: any[]): void;
  info(message: string, ...args: any[]): void;
  warn(message: string, ...args: any[]): void;
  error(message: string, ...args: any[]): void;
}

使用示例:

const wsClient = new AiBot.WSClient({
  botId: 'your-bot-id',
  secret: 'your-bot-secret',
  logger: {
    debug: () => {},  // 静默 debug 日志
    info: console.log,
    warn: console.warn,
    error: console.error,
  },
});

🔧 WebSocket 命令协议

以下为 SDK 内部使用的 WebSocket 命令常量(WsCmd),了解底层协议有助于高级调试:

方向常量说明
开发者 → 企微SUBSCRIBEaibot_subscribe认证订阅
开发者 → 企微HEARTBEATping心跳
开发者 → 企微RESPONSEaibot_respond_msg回复消息
开发者 → 企微RESPONSE_WELCOMEaibot_respond_welcome_msg回复欢迎语
开发者 → 企微RESPONSE_UPDATEaibot_respond_update_msg更新模板卡片
开发者 → 企微SEND_MSGaibot_send_msg主动发送消息
开发者 → 企微UPLOAD_MEDIA_INITaibot_upload_media_init上传素材 - 初始化
开发者 → 企微UPLOAD_MEDIA_CHUNKaibot_upload_media_chunk上传素材 - 分片
开发者 → 企微UPLOAD_MEDIA_FINISHaibot_upload_media_finish上传素材 - 完成
企微 → 开发者CALLBACKaibot_msg_callback消息推送回调
企微 → 开发者EVENT_CALLBACKaibot_event_callback事件推送回调

📂 项目结构

aibot-node-sdk/
├── src/
│   ├── index.ts             # 入口文件,统一导出
│   ├── client.ts            # WSClient 核心客户端
│   ├── ws.ts                # WebSocket 长连接管理器
│   ├── message-handler.ts   # 消息解析与事件分发
│   ├── api.ts               # HTTP API 客户端(文件下载)
│   ├── crypto.ts            # AES-256-CBC 文件解密
│   ├── logger.ts            # 默认日志实现
│   ├── utils.ts             # 工具方法(generateReqId 等)
│   └── types/
│       ├── index.ts          # 类型统一导出
│       ├── config.ts         # 配置选项类型
│       ├── event.ts          # 事件映射类型
│       ├── message.ts        # 消息相关类型
│       ├── api.ts            # API/WebSocket 帧/模板卡片类型
│       └── common.ts         # 通用类型(Logger)
├── examples/
│   └── basic.ts             # 基础使用示例
├── package.json
├── tsconfig.json
├── rollup.config.mjs        # Rollup 构建配置
└── yarn.lock

🧩 完整使用示例

流式回复 + 图文混排

import AiBot from '@wecom/aibot-node-sdk';
import type { WsFrame, ReplyMsgItem } from '@wecom/aibot-node-sdk';
import { generateReqId } from '@wecom/aibot-node-sdk';
import { createHash } from 'crypto';
import fs from 'fs';

const wsClient = new AiBot.WSClient({
  botId: 'your-bot-id',
  secret: 'your-bot-secret',
});

wsClient.connect();

wsClient.on('message.text', async (frame: WsFrame) => {
  const streamId = generateReqId('stream');

  // 流式中间内容
  await wsClient.replyStream(frame, streamId, '正在生成图文内容...', false);

  // 准备图文混排项(仅 finish=true 时有效)
  const imageData = fs.readFileSync('/path/to/image.jpg');
  const base64 = imageData.toString('base64');
  const md5 = createHash('md5').update(imageData).digest('hex');

  const msgItem: ReplyMsgItem[] = [
    { msgtype: 'image', image: { base64, md5 } },
  ];

  // 流式结束,附带图片
  await wsClient.replyStream(frame, streamId, '这是最终结果', true, msgItem);
});

上传素材 + 回复媒体消息

import AiBot from '@wecom/aibot-node-sdk';
import type { WsFrame } from '@wecom/aibot-node-sdk';
import fs from 'fs';

const wsClient = new AiBot.WSClient({
  botId: 'your-bot-id',
  secret: 'your-bot-secret',
});

wsClient.connect();

wsClient.on('message.text', async (frame: WsFrame) => {
  // 上传文件
  const fileBuffer = fs.readFileSync('/path/to/document.pdf');
  const result = await wsClient.uploadMedia(fileBuffer, {
    type: 'file',
    filename: 'document.pdf',
  });

  // 使用 media_id 被动回复文件消息
  await wsClient.replyMedia(frame, 'file', result.media_id);
});

主动推送消息

// 在认证成功后,可以随时主动推送消息
wsClient.on('authenticated', async () => {
  // 向指定用户推送 Markdown 消息
  await wsClient.sendMessage('target_userid', {
    msgtype: 'markdown',
    markdown: { content: '# 通知\n\n这是一条**主动推送**的消息。' },
  });

  // 主动推送媒体消息
  const imageBuffer = fs.readFileSync('/path/to/photo.jpg');
  const result = await wsClient.uploadMedia(imageBuffer, {
    type: 'image',
    filename: 'photo.jpg',
  });
  await wsClient.sendMediaMessage('target_userid', 'image', result.media_id);
});

模板卡片交互

// 回复带按钮的模板卡片
wsClient.on('message.text', async (frame: WsFrame) => {
  await wsClient.replyTemplateCard(frame, {
    card_type: 'button_interaction',
    main_title: { title: '请选择操作', desc: '点击下方按钮进行操作' },
    button_list: [
      { text: '确认', key: 'btn_confirm', style: 1 },
      { text: '取消', key: 'btn_cancel', style: 2 },
    ],
    task_id: `task_${Date.now()}`,
  });
});

// 监听卡片按钮点击事件并更新卡片
wsClient.on('event.template_card_event', async (frame: WsFrame) => {
  const eventKey = frame.body.event?.event_key;
  const taskId = frame.body.event?.task_id;

  await wsClient.updateTemplateCard(frame, {
    card_type: 'text_notice',
    main_title: { title: eventKey === 'btn_confirm' ? '已确认 ✅' : '已取消 ❌' },
    task_id: taskId,
  });
});

文件下载解密

import fs from 'fs';
import path from 'path';

// 处理图片消息
wsClient.on('message.image', async (frame: WsFrame) => {
  const body = frame.body;
  const imageUrl = body.image?.url;
  if (!imageUrl) return;

  // 使用消息中独立的 aeskey 下载并解密
  const { buffer, filename } = await wsClient.downloadFile(imageUrl, body.image?.aeskey);
  const savePath = path.join(__dirname, filename || `image_${Date.now()}.jpg`);
  fs.writeFileSync(savePath, buffer);
  console.log(`图片已保存: ${savePath} (${buffer.length} bytes)`);
});

// 处理文件消息
wsClient.on('message.file', async (frame: WsFrame) => {
  const body = frame.body;
  const fileUrl = body.file?.url;
  if (!fileUrl) return;

  const { buffer, filename } = await wsClient.downloadFile(fileUrl, body.file?.aeskey);
  const savePath = path.join(__dirname, filename || `file_${Date.now()}`);
  fs.writeFileSync(savePath, buffer);
  console.log(`文件已保存: ${savePath} (${buffer.length} bytes)`);
});

🔧 开发

# 安装依赖
yarn install

# 开发模式(监听文件变化)
yarn dev

# 构建
yarn build

# 运行示例
yarn example

🔗 导出说明

SDK 同时支持默认导出和具名导出:

// 默认导出
import AiBot from '@wecom/aibot-node-sdk';
const wsClient = new AiBot.WSClient({ ... });

// 具名导出
import { WSClient, generateReqId } from '@wecom/aibot-node-sdk';
const wsClient = new WSClient({ ... });

// 类型导入
import type { WsFrame, BaseMessage, TextMessage, TemplateCard } from '@wecom/aibot-node-sdk';

完整导出列表:

类别导出项
WSClientWeComApiClientWsConnectionManagerMessageHandlerDefaultLogger
函数generateReqIdgenerateRandomStringdecryptFile
枚举MessageTypeEventTypeTemplateCardTypeWsCmd
类型WSClientOptionsWSClientEventMapWsFrameWsFrameHeadersBaseMessageTextMessageImageMessageMixedMessageVoiceMessageFileMessageVideoMessageEventMessageTemplateCardStreamReplyBodyReplyMsgItemReplyFeedbackLogger

📄 License

MIT

Keywords

wecom

FAQs

Package last updated on 19 Mar 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts