npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

wecom-sdk-ai

v0.1.0

Published

企业微信 Node.js SDK - 基于原生 fetch API,支持 CommonJS 和 ES Module 引用

Downloads

103

Readme

WeCom SDK AI 完整说明文档

企业微信 Node.js SDK - 基于原生 fetch API
包名: wecom-sdk-ai
版本: 0.1.0
更新日期: 2026-03-24


⚠️ 重要提示

本 SDK 尚未在实际项目中测试使用,当前版本 0.1.0 为预览版本。

  • 所有 API 调用已根据企业微信官方文档实现
  • TypeScript 类型定义完整
  • 单元测试覆盖核心模块
  • 实际调用企业微信 API 的效果需要验证

目录


项目概述

WeCom SDK 是一个基于企业微信官方 API 的 Node.js 开发工具包,采用原生 fetch API 实现,无需额外依赖(如 axios)。

技术栈

| 技术 | 版本 | 说明 | |------|------|------| | TypeScript | ^5.0.0 | 类型支持 | | Node.js | >=18.0.0 | 运行时要求 | | Jest | ^29.7.0 | 测试框架 | | ts-jest | ^29.1.0 | TypeScript 编译 |


功能特性

核心功能

| 功能 | 说明 | |------|------| | 单企业支持 | 简单的 corpid/corpsecret 配置 | | 多企业支持 | 复杂的多企业多应用架构 | | Token 管理 | 自动缓存和刷新机制 | | HTTP 客户端 | 基于原生 fetch 的请求封装 | | 错误处理 | 完整的中文错误码映射 | | 消息加解密 | 回调消息签名验证和解密 |

业务模块

  • 用户管理 - 成员的增删改查
  • 部门管理 - 组织架构管理
  • 标签管理 - 用户标签操作
  • 消息推送 - 文本、图片、Markdown 等消息类型
  • 媒体上传 - 图片、语音、视频、文件
  • 打卡管理 - 打卡数据获取
  • 会议管理 - 腾讯会议集成
  • 审批流程 - 审批单据操作
  • 外部联系人 - 客户管理
  • 应用管理 - 企业应用配置
  • 微盘 - 企业云盘操作
  • 日程管理 - 日程创建和查询
  • 教育模块 - 家校沟通、学生管理
  • 支付模块 - 企业支付功能
  • 智能表格 - 企微云文档
  • 导出任务 - 数据导出
  • 批量操作 - 批量任务提交
  • 设备管理 - 硬件设备管理
  • 客服模块 - 客服消息

安装引用

安装

npm install

编译

npm run build

引用方式

ES Module (import)

// 方式一: 命名导入
import { WeComClient } from 'wecom-sdk-ai';

// 方式二: 导入类
import WeComClient from 'wecom-sdk-ai';

// 导入其他模块
import { HttpClient, TokenManager, MemoryCache, WeComError } from 'wecom-sdk-ai';
import { verifySignature, decryptMessage, encryptMessage } from 'wecom-sdk-ai';

CommonJS (require)

// 方式一: 解构导入
const { WeComClient } = require('wecom-sdk-ai');

// 方式二: 直接导入
const WeComClient = require('wecom-sdk-ai').default;

// 导入其他模块
const { HttpClient, TokenManager, MemoryCache, WeComError } = require('wecom-sdk-ai');
const { verifySignature, decryptMessage, encryptMessage } = require('wecom-sdk-ai');

TypeScript 配置

确保 tsconfig.json 开启了相关选项:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "CommonJS",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true
  }
}

快速开始

配置

import { WeComClient } from 'wecom-sdk-ai';

// 单企业配置
const client = new WeComClient({
  corpid: 'your-corpid',
  corpsecret: 'your-corpsecret',
  appId: 1000001,        // 应用ID,可选
  enterpriseId: 'ent1'   // 企业标识,可选
});

发送消息

// 发送文本消息
const result = await client.message.sendText(1000001, 'Hello World', {
  touser: 'user1|user2'  // 多个用户用 | 分隔
});

// 发送 Markdown
const result = await client.message.sendMarkdown(1000001, '## 标题\n内容');

管理用户

// 创建用户
await client.user.create({
  userid: 'zhangsan',
  name: '张三',
  mobile: '13800138000',
  department: [1, 2]
});

// 获取用户详情
const user = await client.user.get('zhangsan');

// 批量获取部门用户
const users = await client.user.simpleList(1, 1); // 递归获取子部门

管理部门

// 创建部门
const result = await client.department.create({
  name: '技术部',
  parentid: 1,
  order: 1
});

// 获取部门列表
const depts = await client.department.list();

API 参考

WeComClient

主入口类,提供所有业务模块的访问。

const client = new WeComClient(options);

选项参数:

| 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | corpid | string | 是 | 企业ID | | corpsecret | string | 是 | 应用密钥 | | appId | number | 否 | 应用ID,默认 1000001 | | enterpriseId | string | 否 | 企业标识,默认 "default" | | cache | CacheProvider | 否 | 自定义缓存实现 |

属性:

| 属性 | 类型 | 说明 | |------|------|------| | user | UserModule | 用户管理模块 | | department | DepartmentModule | 部门管理模块 | | tag | TagModule | 标签管理模块 | | message | MessageModule | 消息推送模块 | | media | MediaModule | 媒体上传模块 | | ... | ... | 其他业务模块 |

消息类型

// 文本消息
{ msgtype: 'text', text: { content: string } }

// 图片消息
{ msgtype: 'image', image: { media_id: string } }

// 语音消息
{ msgtype: 'voice', voice: { media_id: string } }

// 视频消息
{ msgtype: 'video', video: { media_id: string, title?: string, description?: string } }

// 文件消息
{ msgtype: 'file', file: { media_id: string } }

// Markdown 消息
{ msgtype: 'markdown', markdown: { content: string } }

// 文本卡片
{ msgtype: 'textcard', textcard: { title: string, description: string, url: string, btntxt?: string } }

// 图文消息
{ msgtype: 'news', news: { articles: Array<{ title: string, description?: string, url: string, picurl?: string }> } }

业务模块

UserModule - 用户管理

| 方法 | 说明 | |------|------| | create(data) | 创建用户 | | get(userid) | 获取用户详情 | | update(data) | 更新用户信息 | | delete(userid) | 删除用户 | | batchDelete(userids) | 批量删除用户 | | simpleList(departmentId, fetchChild?) | 获取部门成员简单列表 | | list(departmentId, fetchChild?) | 获取部门成员详情列表 | | convertToOpenid(userid) | userid 转 openid | | convertToUserid(openid) | openid 转 userid | | getUseridByMobile(mobile) | 通过手机号获取 userid | | getUseridByEmail(email, emailType?) | 通过邮箱获取 userid |

DepartmentModule - 部门管理

| 方法 | 说明 | |------|------| | create(data) | 创建部门 | | update(data) | 更新部门信息 | | delete(id) | 删除部门 | | list(id?) | 获取部门列表 | | simpleList(id?) | 获取部门简单列表 | | get(id) | 获取部门详情 |

TagModule - 标签管理

| 方法 | 说明 | |------|------| | create(tagname, tagid?) | 创建标签 | | update(tagid, tagname) | 更新标签 | | delete(tagid) | 删除标签 | | get(tagid) | 获取标签成员 | | addUsers(tagid, userlist, partylist?) | 增加标签成员 | | deleteUsers(tagid, userlist, partylist?) | 删除标签成员 |

MessageModule - 消息推送

| 方法 | 说明 | |------|------| | send(data) | 发送消息 | | sendText(agentid, content, options?) | 发送文本消息 | | sendImage(agentid, mediaId, options?) | 发送图片消息 | | sendMarkdown(agentid, content, options?) | 发送 Markdown 消息 | | recall(msgid) | 撤回消息 |

MediaModule - 媒体管理

| 方法 | 说明 | |------|------| | upload(type, filename, content) | 上传临时素材 | | get(mediaId) | 获取临时素材 | | uploadImg(file) | 上传图片 | | uploadVoice(voice) | 上传语音 | | uploadVideo(video) | 上传视频 | | uploadFile(file) | 上传普通文件 |

其他模块

| 模块 | 说明 | |------|------| | BatchModule | 批量任务 | | ExportModule | 数据导出 | | ExternalModule | 外部联系人 | | OaModule | 审批流程 | | CheckinModule | 打卡数据 | | MeetingModule | 会议管理 | | WedriveModule | 企业微盘 | | PaymentModule | 企业支付 | | ServiceModule | 客服消息 | | SchoolModule | 教育模块 | | DeviceModule | 设备管理 | | AgentModule | 应用管理 | | SmartsheetModule | 智能表格 | | CallbackModule | 回调处理 |


核心模块

TokenManager - Token 管理

import { TokenManager } from 'wecom-sdk-ai';

// 单企业模式
const tokenManager = new TokenManager({
  corpid: 'corp-id',
  corpsecret: 'corp-secret',
  appId: 1000001
});

// 多企业模式
const tokenManager = new TokenManager({
  enterprise1: {
    corpid: 'corp-1',
    apps: [{ corpsecret: 'secret-1', appId: 1000001 }]
  },
  enterprise2: {
    corpid: 'corp-2',
    apps: [{ corpsecret: 'secret-2', appId: 1000002 }]
  }
});

// 获取 Token
const token = await tokenManager.getAccessToken('enterprise1', 1000001);

// 刷新 Token
const newToken = await tokenManager.refreshToken('enterprise1', 1000001);

HttpClient - HTTP 客户端

import { HttpClient } from 'wecom-sdk-ai';

const client = new HttpClient();

// GET 请求
const result = await client.get('/user/get', { userid: 'zhangsan' }, 'access-token');

// POST 请求
const result = await client.post('/user/create', { userid: 'zhangsan', name: '张三' }, {}, 'access-token');

CacheProvider - 缓存接口

import { CacheProvider, MemoryCache } from 'wecom-sdk-ai';

// 使用内置内存缓存(默认)
const cache = new MemoryCache();

// 自定义缓存实现
class RedisCache implements CacheProvider {
  async get(key: string): Promise<string | null> {
    return await redis.get(key);
  }
  async set(key: string, value: string, ttlSeconds: number): Promise<void> {
    await redis.setex(key, ttlSeconds, value);
  }
  async delete(key: string): Promise<void> {
    await redis.del(key);
  }
}

工具函数

import { verifySignature, decryptMessage, encryptMessage, parseXml, buildXml } from 'wecom-sdk-ai';

// 验证回调签名
const isValid = verifySignature(config, signature, timestamp, nonce, echoStr);

// 解密消息
const message = decryptMessage(config, encryptedMsg);

// 加密消息
const { encrypted, signature, timestamp, nonce } = encryptMessage(config, message);

// XML 解析和构建
const data = parseXml(xmlString);
const xml = buildXml(data);

WeComError - 错误处理

import { WeComError, ErrorCodeMap } from 'wecom-sdk-ai';

try {
  await client.user.get('invalid-user');
} catch (error) {
  if (error instanceof WeComError) {
    console.log(`错误码: ${error.code}`);
    console.log(`错误信息: ${error.message}`);
    console.log(`中文描述: ${error.chineseMessage}`);
  }
}

测试结果

⚠️ 测试说明

注意: 以下测试为单元测试,仅验证代码逻辑正确性,不包含实际调用企业微信 API 的集成测试

实际使用时,请务必在企业微信管理后台配置好相关应用权限,并验证 API 调用效果。

测试执行时间

2026-03-24

测试结果概览

Test Suites: 5 passed, 5 total
Tests:       44 passed, 44 total
Time:        4.035 s

详细测试结果

1. error.test.ts ✅

| 测试用例 | 状态 | 耗时 | |----------|------|------| | 应正确设置错误码和消息 | ✅ 通过 | 5 ms | | 应包含中文错误信息 | ✅ 通过 | 1 ms | | 未知错误码应提供默认中文信息 | ✅ 通过 | - | | 应包含常见错误码映射 | ✅ 通过 | 1 ms | | 应返回格式化的错误信息 | ✅ 通过 | 1 ms |

模块覆盖率: 100%

2. client.test.ts ✅

| 测试用例 | 状态 | 耗时 | |----------|------|------| | 应正确发送 GET 请求 | ✅ 通过 | 8 ms | | 应正确附加 access_token | ✅ 通过 | 2 ms | | 应正确附加查询参数 | ✅ 通过 | 1 ms | | 应正确发送 POST 请求 | ✅ 通过 | 1 ms | | 应正确设置请求头 | ✅ 通过 | - | | 应正确处理 URL 查询参数 | ✅ 通过 | - | | HTTP 错误应抛出异常 | ✅ 通过 | 12 ms | | WeCom API 错误应抛出 WeComError | ✅ 通过 | - | | 应提供中文错误信息 | ✅ 通过 | - | | 应正确处理空参数 | ✅ 通过 | 1 ms | | 应正确处理数组参数 | ✅ 通过 | - |

模块覆盖率: 100%

3. modules/user.test.ts ✅

| 测试用例 | 状态 | 耗时 | |----------|------|------| | 应正确创建用户 | ✅ 通过 | 9 ms | | 应正确获取用户信息 | ✅ 通过 | - | | 应正确更新用户信息 | ✅ 通过 | 1 ms | | 应正确删除单个用户 | ✅ 通过 | - | | 应正确批量删除用户 | ✅ 通过 | 1 ms | | 应正确获取部门成员列表 | ✅ 通过 | 1 ms | | 应支持递归获取子部门成员 | ✅ 通过 | 1 ms | | 应正确获取部门成员详情 | ✅ 通过 | - | | 应通过手机号获取 userid | ✅ 通过 | 1 ms | | 应支持指定 enterpriseId 和 appId | ✅ 通过 | - |

模块覆盖率: 68.75%

4. utils.test.ts ✅

| 测试用例 | 状态 | 耗时 | |----------|------|------| | 应正确验证签名 | ✅ 通过 | 6 ms | | 错误签名应返回 false | ✅ 通过 | - | | 应正确解析 XML | ✅ 通过 | 1 ms | | 应正确构建 XML | ✅ 通过 | 1 ms | | 应生成指定长度的随机字符串 | ✅ 通过 | - | | 默认应生成 32 位随机字符串 | ✅ 通过 | - | | 应生成当前时间戳字符串 | ✅ 通过 | - | | 应正确解密加密的消息 | ✅ 通过 | 2 ms | | 应正确解密包含中文的消息 | ✅ 通过 | 1 ms |

模块覆盖率: 98.41%

5. token.test.ts ✅

| 测试用例 | 状态 | 耗时 | |----------|------|------| | 应使用 corpid 和 corpsecret 初始化 | ✅ 通过 | 5 ms | | 应生成正确的缓存 key | ✅ 通过 | 1 ms | | 应使用多企业配置初始化 | ✅ 通过 | 1 ms | | 应获取指定企业和应用的 token | ✅ 通过 | 1 ms | | 当企业不存在时应抛出错误 | ✅ 通过 | 8 ms | | 当应用不存在时应抛出错误 | ✅ 通过 | 1 ms | | 应从缓存获取 token | ✅ 通过 | - | | 缓存为空时应重新获取 token | ✅ 通过 | - | | 应强制刷新 token | ✅ 通过 | 1 ms |

模块覆盖率: 79.24%

代码覆盖率汇总

| 文件 | 语句覆盖 | 分支覆盖 | 函数覆盖 | 行覆盖 | |------|----------|----------|----------|---------| | 总体 | 83.5% | 69.64% | 76.19% | 83.93% | | src/cache.ts | 16.66% | 0% | 25% | 18.18% | | src/client.ts | 100% | 70.58% | 100% | 100% | | src/error.ts | 100% | 100% | 100% | 100% | | src/token.ts | 79.24% | 70.37% | 77.77% | 79.24% | | src/utils.ts | 98.41% | 71.42% | 100% | 98.41% | | src/modules/user.ts | 68.75% | 100% | 64.28% | 68.75% |


项目结构

wecom-sdk-ai/
├── src/
│   ├── index.ts              # 主入口,导出所有模块
│   ├── client.ts             # HTTP 客户端封装
│   ├── token.ts              # Token 管理器
│   ├── cache.ts              # 缓存接口和实现
│   ├── error.ts              # 错误类和错误码映射
│   ├── utils.ts              # 工具函数
│   ├── types/
│   │   └── index.ts          # 共享类型定义
│   └── modules/
│       ├── user.ts           # 用户管理
│       ├── department.ts     # 部门管理
│       ├── tag.ts            # 标签管理
│       ├── message.ts        # 消息推送
│       ├── media.ts          # 媒体上传
│       ├── batch.ts          # 批量操作
│       ├── export.ts         # 数据导出
│       ├── external.ts       # 外部联系人
│       ├── oa.ts            # 审批
│       ├── checkin.ts        # 打卡
│       ├── meeting.ts        # 会议
│       ├── wedrive.ts        # 微盘
│       ├── payment.ts        # 支付
│       ├── service.ts        # 客服
│       ├── school.ts         # 教育
│       ├── device.ts         # 设备
│       ├── agent.ts          # 应用
│       ├── smartsheet.ts     # 智能表格
│       └── callback.ts       # 回调处理
├── __tests__/
│   ├── client.test.ts
│   ├── token.test.ts
│   ├── error.test.ts
│   ├── utils.test.ts
│   └── modules/
│       └── user.test.ts
├── dist/                     # 编译输出
├── package.json
├── tsconfig.json
├── jest.config.js
└── README.md                # 说明文档

使用示例

完整示例:发送图文消息

import { WeComClient } from 'wecom-sdk-ai';

const client = new WeComClient({
  corpid: 'ww1234567890abcdef',
  corpsecret: 'your-secret-here',
  appId: 1000001
});

async function main() {
  try {
    // 发送图文消息
    const result = await client.message.send({
      msgtype: 'news',
      agentid: 1000001,
      touser: 'zhangsan|lisi',
      news: {
        articles: [
          {
            title: '公告',
            description: '这是一条重要公告',
            url: 'https://example.com/announcement',
            picurl: 'https://example.com/image.jpg'
          }
        ]
      }
    });

    console.log('发送成功:', result.msgid);
  } catch (error) {
    if (error instanceof Error) {
      console.error('发送失败:', error.message);
    }
  }
}

main();

完整示例:管理企业部门

import { WeComClient } from 'wecom-sdk-ai';

const client = new WeComClient({
  corpid: 'ww1234567890abcdef',
  corpsecret: 'your-secret-here'
});

async function manageDepartments() {
  // 创建顶级部门
  const itDept = await client.department.create({
    name: '技术部',
    parentid: 1,
    order: 1
  });
  console.log('创建技术部 ID:', itDept.id);

  // 在技术部下创建子部门
  const backendDept = await client.department.create({
    name: '后端组',
    parentid: itDept.id,
    order: 1
  });
  console.log('创建后端组 ID:', backendDept.id);

  // 获取所有部门
  const allDepts = await client.department.list();
  console.log('所有部门:', allDepts.department);

  // 更新部门信息
  await client.department.update({
    id: backendDept.id,
    name: '后端开发组'
  });

  // 获取部门成员
  const members = await client.user.simpleList(itDept.id, 1); // 递归获取
  console.log('技术部成员数:', members.userlist.length);
}

manageDepartments();

更新日志

v0.1.0 (2026-03-24)

  • 初始版本发布
  • 完成所有测试用例 (44/44 通过)
  • 支持 CommonJS 和 ES Module 引用
  • 修复加密解密中文支持问题
  • 完善错误处理和中文错误信息
  • 优化 Token 缓存机制
  • 增加多企业多应用支持

许可证

MIT License


联系方式

如有问题,请提交 Issue。


⚠️ 免责声明

  1. 本 SDK 尚未在实际企业微信项目中验证使用
  2. API 参数和返回值可能与企业微信官方文档存在差异
  3. 使用前请务必阅读企业微信官方 API 文档
  4. 生产环境使用前建议进行充分测试