文章摘要 :本文主要介绍了企业微信API对接的详细过程,包括获取token、安装docker环境、打包启动应用、企业微信二维码验证以及调用企业微信的三个主要接口(获取所有用户、发送消息给单人、发送消息给多人)等步骤,旨在帮助企业通过程序发送消息给微信客户,实现消息提醒和客户管理的功能【所有功能,亲测有效!】。
想通过程序发送制定的消息给微信客户,客户需要接收到消息提醒并且可以直接打开微信查看(前提条件用户用加了门店企业微信好友),针对上面问题,提供两个接口:
1、一个是获取企业微信的用户的列表
2、一个是直接发送用户消息
获取第三方token,申请地址:Token 自助服务系统
目前已经获取到的token是(注意大家获取到token,试用期仅有7天,如想续期请自行续费):
puppet_workpro_867******41e7908d3ee3b44f5421
请先使用一个安装好docker 的服务器。请自行百度,在服务器如何安装docker。
方式一(推荐):阿里云安装docker,根据服务器类型选择安装,操作文档如下:
安装Docker并使用_云服务器 ECS(ECS)-阿里云帮助中心
方式二:执行下面的命令。
server.js 伪代码参考
// server.js
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = 9898;
app.use(bodyParser.json());
app.use(express.static('public'));
let verifyCode = ''; // 用于存储用户提交的验证码
app.post('/submit-verify-code', (req, res) => {
const { verifyCode: userVerifyCode } = req.body;
verifyCode = userVerifyCode;
res.json({ message: '验证码已接收', verifyCode: userVerifyCode });
});
app.listen(port, () => {
console.log(`服务器运行在 http://localhost:${port}`);
});
package.json伪代码参考
{
"name": "workpro-getting-started",
"version": "1.0.0",
"description": "basic example on workpro service",
"main": "index.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "ts-node index.ts"
},
"repository": {
"type": "git",
"url": "https://gitee.com/laibin113/enterprise-wechat-messaging.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://gitee.com/laibin113/enterprise-wechat-messaging.git"
},
"homepage": "https://gitee.com/laibin113/enterprise-wechat-messaging.git",
"dependencies": {
"@juzi/wechaty": "^1.0.66",
"@juzi/wechaty-puppet": "^1.0.66",
"qrcode-terminal": "^0.12.0",
"express": "^4.17.1",
"body-parser": "^1.20.0",
"@grpc/grpc-js": "1.8.12",
"node-fetch": "^2.6.1",
"node-cache": "^5.1.2"
},
"devDependencies": {
"@types/qrcode-terminal": "^0.12.0",
"@types/express": "^4.17.6"
}
}
(1)发送接口请求获取初始二维码,docker日志查看如果不会请自行百度;
(2)开启程序post方法请求:http:127.0.0.1:9898/goStart
(3)上面的接口127.0.0.1根据实际服务换成自己的IP,或者绑定对应的域名。
日志台会出现一个二维码!
验证成功后,日志台输出:(如图),表示登录成功
这个时候,日志台,会重新打印二维码,点击 确定是本人使用,然后扫描二维码,即可。
(1)post方法请求:http:127.0.0.1:9898/get-all-user
(2)body传参方式,参数说明:
pageSize:需要发送的企业微信消息内容
id:上面获取到用户信息的用户id
(3)备注:上面的接口127.0.0.1根据实际服务换成自己的IP,或者绑定对应的域名。
(4)9898对应服务器安全组需要放行该端口,如果启动防火墙也要放开该端口号。
datas为用户数据列表, hasNextPage为是否有下一页。
各个字段都十分容易理解,自行翻译吧,下面是参数:
_events 和 _eventsCount:事件相关的计数器。
id:标识符,通常用于唯一标识一个对象或记录。
payload:负载,指传输的数据内容。
address:地址,指用户的居住地址或联系地址。
alias:别名,用户使用的另一个名字或昵称。
avatar:头像,是指用户的照片或代表图像的链接。
city:城市,用户所在的城市。
corporation:公司,用户所在的公司或组织。
coworker:同事,可能表示用户是否是联系人的同事。
description:描述,可能是指对用户的一些描述性信息。
friend:朋友,可能表示用户是否是联系人的朋友。
gender:性别,1通常表示男性,0代表女性
handle:处理
name:名字,用户的姓名。
phone:电话,用户的联系电话。
province:省份,用户所在的省份。
signature:签名,用户的签名或个人格言。
star:星标,可能表示用户是否被标记为重要联系人。
title:标题,可能是指用户的职位或头衔。
type:类型,1可能表示用户类型或状态
weixin:微信,用户的微信账号或标识。
additionalInfo:额外信息,包含一些用于识别或分类用户的附加数据。
corpld 和 sCorpld:与公司或组织相关的某种标识符。
status:状态,5表示用户的状态码。
tags:标签,用于标记用户或分类的关键词列表,这里是一个数组。
realName:真实姓名,用户的正式姓名。
aka:也被称为,表示用户的其他已知名称或别名。
hasNextPage:有下一页,这通常用于分页显示,表示数据还有更多的部分。
发送消息接口:(如图下图所示)
(1)post方法请求:http:127.0.0.1:9898/send-message
(2)body传参方式,参数说明:
message:需要发送的企业微信消息内容
id:上面获取到用户信息的用户id
(3)备注:上面的接口127.0.0.1根据实际服务换成自己的IP,或者绑定对应的域名。
(1)post方法请求:http:127.0.0.1:9898/send-message-all
(2)body传参方式,参数说明:
message:需要发送的企业微信消息内容
id:上面获取到用户信息的用户id
(3)备注:上面的接口127.0.0.1根据实际服务换成自己的IP,或者绑定对应的域名。
(4)上面获取到的用户信息的tag(标签),可在下图那里管理。
效果如图:
# Dockerfile
FROM node:lts
# 复制应用程序代码到容器中
COPY . /appWxWork
WORKDIR /appWxWork
ENV WECHATY_PUPPET_SERVICE_AUTHORITY=token-service-discovery-test.juzibot.com
RUN npm config set registry https://registry.npmmirror.com/
# 在容器中安装 ts-node 和应用程序所需的依赖
RUN npm install ts-node typescript
# 暴露端口 8088
EXPOSE 9898
# 运行应用程序
CMD ["npm", "start"]
import {ScanStatus, WechatyBuilder} from '@juzi/wechaty'
import QrcodeTerminal from 'qrcode-terminal'
const NodeCache = require("node-cache");
const express = require('express');
const bodyParser = require('body-parser');
const myCache = new NodeCache({ stdTTL: 3660, checkperiod: 1200 });
const app = express();
const port = 9898;
app.use(bodyParser.json());
app.use(express.static('public'));
let verifyCode1 = ''; // 用于存储用户提交的验证码
const fetch = require('node-fetch');
let myUserName = '';
const token = 'puppet_workpro_******1241e7908d3ee3b44f5421';
const bot = WechatyBuilder.build({
puppet: '@juzi/wechaty-puppet-service',
//authority: 'token-service-discovery-test.juzibot.com',
puppetOptions: {
token,
tls: {
disable: true
// currently we are not using TLS since most puppet-service versions does not support it.
}
}
})
const store = {
qrcodeKey: '',
}
......
下面给出 3 段可直接粘贴到 server.js 中的最小可运行代码片段,对应文档中「获取用户列表」「单发消息」「群发消息」三个核心接口。每段都附带逐行中文解释,方便二次开发。
// POST /get-all-user
app.post('/get-all-user', async (req, res) => {
const { pageSize = 50 } = req.body; // 默认 50 条一页
if (!bot.isLoggedIn) { // 没扫码登录直接返回
return res.status(401).json({ msg: '未扫码登录' });
}
try {
// bot.Contact.findAll 会自动拉取全部联系人
const all = await bot.Contact.findAll();
const list = all
.filter(c => c.type() === bot.Contact.Type.Individual) // 只保留外部联系人
.slice(0, pageSize) // 前端分页
.map(c => ({
id: c.id, // 发送消息时要用
name: c.name(),
alias: c.alias(),
avatar: c.avatar(),
gender: c.gender(), // 1 男 0 女
tags: c.tags().map(t => t.name())
}));
res.json({ datas: list, hasNextPage: all.length > pageSize });
} catch (e) {
res.status(500).json({ msg: e.message });
}
});
解释
bot.Contact.findAll()
拿到完整联系人列表。
pageSize
切片返回,前端可继续传 pageSize+offset
做分页。
// POST /send-message
app.post('/send-message', async (req, res) => {
const { id, message } = req.body;
if (!id || !message) {
return res.status(400).json({ msg: '缺少 id 或 message' });
}
try {
const contact = await bot.Contact.find({ id });
if (!contact) return res.status(404).json({ msg: '用户不存在' });
await contact.say(message); // 真正发消息
res.json({ msg: '已发送', id, message });
} catch (e) {
res.status(500).json({ msg: e.message });
}
});
解释
id
反查联系人。
contact.say()
是 Wechaty 统一发消息的 API,文本/图片/链接都能发。
// POST /send-message-all
app.post('/send-message-all', async (req, res) => {
const { tag, message } = req.body; // tag 为空时给全部外部联系人发
if (!message) return res.status(400).json({ msg: 'message 不能为空' });
try {
const all = await bot.Contact.findAll();
const targets = all.filter(c => {
if (c.type() !== bot.Contact.Type.Individual) return false;
if (!tag) return true; // tag 为空 -> 全员
return c.tags().some(t => t.name() === tag);
});
const result = await Promise.allSettled(
targets.map(c => c.say(message))
);
const success = result.filter(r => r.status === 'fulfilled').length;
res.json({ total: targets.length, success, fail: result.length - success });
} catch (e) {
res.status(500).json({ msg: e.message });
}
});
解释
tag
,就按标签过滤;否则群发。
Promise.allSettled
保证即使某条发送失败也不会中断整体流程。
把以上三段代码追加到 server.js 后,重新 docker build -t wechat_data_con . && docker run -p 9898:9898 wechat_data_con
,即可通过三个 HTTP 接口完成「拉用户 → 发消息」的完整闭环。
(1)当想更换企业微信绑定者的时候,调用下面的接口进行结束,然后重新绑定。
(2)结束程序post方法请求:http:127.0.0.1:9898/goEnd
(3)备注:上面的接口127.0.0.1根据实际服务换成自己的IP,或者绑定对应的域名。
控制台日志 ,会重新打印二维码,请重新执行上面的步骤2~……
本文关键词解释 :
说明:原文档是我同事 陈伟俊 编写,本人觉得比较有意义文章,稍微整理输出分享给大家学习,希望这篇博客能够为你在工作中提供一些启发和指导。如果你有任何问题或需要进一步的建议,欢迎在评论区留言交流。让我们一起探索IT世界的无限可能!