唐抉的个人博客

企业微信之企业应用开发流程

字数统计: 2.9k阅读时长: 11 min
2022/11/18

创建应用

创建准备

  • 成功注册企业微信企业
  • 企业微信账号拥有当前企业的超级管理员或分级管理员的权限

创建应用

登录 企业微信管理后台,在【应用管理】界面-【应用】-【自建】点击【创建应用】,在弹出框填写应用的图标、标题、描述和可见范围基本信息。填写完成后,点击【创建应用】,将会跳转至应用详情页面。

配置信息

可见范围

在【应用管理】界面-【应用】-【自建】点击刚刚创建好的应用,进入应用信息页面,点击编辑。

点击可见范围旁边的添加,即可编辑可见范围。

应用主页

配置成员从工作台打开应用时打开的页面URL,假设应用打开的网页为:http://tangmenjue.top/

在应用信息页面点击编辑,点击应用主页旁边的设置,即可配置工作台打开的应用主页。

配置完成后,在可见范围内的成员,将在工作台看到该应用。

配置HOST

为了能在本地进行开发,需要将应用URL的访问指向本地。Window系统下打开C:\Windows\System32\drivers\etc目录,右键点击hosts,选择使用记事本打开,在文件末尾增加代码如下:

1
2
127.0.0.1	localhost
127.0.0.1 tangmenjue.top

获取应用接口凭证

获取企业ID corp_id

在登录管理后台后,在【管理后台】-【我的企业】-【企业信息】页面的最下面,便可找到【企业ID】

获取应用 Secret

在应用信息页面便可查看Secret

将Secret发送到企业微信中查看,点击【发送】,则在操作者的企业微信会话中,会收到企业微信推送过来的Secret信息

获取应用接口凭证 access_token

access_token由corpid和secret产生,所有接口在通信时都需要携带此信息用于验证接口的访问权限。

借助PostMan接口工具进行获取:https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=id&corpsecret=secret,链接里的id自行替换为实际的corp_id值,secret自行替换为实际的secret值。

打开PostMan,在左上角处点击Create collection

然后继续点击Add a request

在新弹出的窗口的Get输入框里输入,点击Send:

然后便可在Body处看到获取的access_token值:

发送应用信息

通过向企业微信信息推送接口POST对应的消息结构体即可实现应用消息的推送。对应的请求地址为:https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN

基本参数

  • 调用接口凭证 access_token 作为 URL Params 带在请求的 URL 中。
  • 应用的id agent_id 代表当前发送消息的应用 ID,可在应用的设置页面查看。
  • 消息接收范围 touser、toparty、totag 分别表示接收消息的 成员、部门、标签,这几个范围标记不能同时为空。
  • 消息类型 msgtype 用于指定消息的类型,当指定某一消息类型之后,接口服务只会读取该类型对应字段下的数据。
  • 消息内容 不同的消息类型,会对应不同的消息内容字段。

基本流程

发送基本类型消息

文本、图文消息、markdown类型的消息仅需要直接在业务后台服务器直接向企业微信消息推送接口发送对应的数据请求即可。

在示例代码的/server/messageController.js 文件中展示了向消息推送 Api 接口发送消息数据体的基本流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const axios = require('axios');
const AccessToken = require('./accesstoken');
const Config = require('../configs/main.config.js');

module.exports = function(router) {
// 发送推送消息
router.post('/message/send', async function (req, res, next) {
// 从前端请求中获取对应的参数
let {form:form_parames} = req.body || {};
// 将 agentid 拼入请求的结构体中
let request_data = {
...form_parames,
agentid:Config.agent_id,
};
request_data.safe = form_parames.safe ? '1' : '0';
// 获取 Access Token
const access_token = await AccessToken.getToken();
// 向消息推送的 Api 发送对应的数据结构体
const {data} = await axios.post('https://qyapi.weixin.qq.com/cgi-bin/message/send',
request_data,
{
params: {
access_token
}
});
// 返回请求的结果
res.send(data);
});
};

发送媒体类型消息

当要推送图片、语言、适配、文件等媒体类型的消息时,需要将对应的文件通过临时素材的接口上传至企业微信的临时素材库。

在示例代码的 /server/mediaController.js 文件中,展示了通过企业微信临时素材接口上传临时素材的基本流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const FormData = require('form-data');
const axios = require('axios');
const AccessToken = require('./accesstoken');

module.exports = function(router) {
router.post('/media/upload', async function (req, res, next) {

let {media:file} = req.files || {};
console.log(req.files);
let {type} = req.body || {} ;
const access_token = await AccessToken.getToken();

// 组件一个form,用来上传文件
const form = new FormData();
form.append('filename', file.name);
form.append('filelength', file.size);
form.append('media',file.data,file.name);

const {data} = await axios.post('https://qyapi.weixin.qq.com/cgi-bin/media/upload',
form,
{
params: {
access_token,
type
},
headers: {
"Content-Type": "multipart/form-data"
},
});
console.log(data);
res.send(data);
});
};

获取登录用户信息

企业微信提供了OAuth的授权登录方式,可以从企业微信终端打开的网页获取成员的身份信息,从而免去登录的环节。

配置可信域名

为了保证访问授权的安全性,需要配置授权链接URL所在域名为可信域名。在【应用详情】-【开发者接口】-【网页授权及 JS-SDK】,点击【设置可信域名】,在【设置可信域名】弹窗,填写网页授权功能的回调域名it.zsnet.net.cn,网页授权回调域名的配置须与实际访问链接的域名完全一致:

构造网页授权链接

以下由几个URL要注意区别:

  • 应用主页URL
    • 从工作台点击打开的页面URL,在创建应用时配置填写的,用来授权链接URL跳转。
  • 重定向URL
    • 当用户授权成功后,会带着成员授权code跳转的URL,用来接收code并获取成员身份
  • 授权链接URL
    • 企业微信名下的URL,包含了suite_id、重定向URL等信息,当企业微信服务参数验证成功后,会跳转到重定向URL

在示例代码的 /routes/index.js 文件中,展示了构造网页授权链接的基本流程:

1
2
3
4
router.get(Config.home_path, function (req, res, next) {
const login_url = getLoginURL('base');
res.redirect(login_url);
});

解析成员授权code

企业成员从工作台点击应用,打开应用主页URL,向授权链接URL跳转;企业微信对授权链接上的信息进行校验之后,会重定向URL跳转,并以query的形式带上当前访问成员的code信息。

在示例代码的 /routes/index.js 文件中,展示了从重定向URL里解析成员授权code的基本流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
router.get(Config.app_path, async function (req, res, next) {
let { code } = req.query;
if (code) {
let access_token = await AccessToken.getToken();
if (access_token) {
let { data: user_data } = await axios.get(`https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=${access_token}&code=${code}`);
console.log('获取 user_data 成功', user_data)
let user_id = user_data.UserId;
}
else {
res.render('error');
}
}

获取访问用户身份信息

在解析出成员授权code之后,使用access_token,调用获取访问用户身份的接口,即可得到访问用户的基本信息user_id,若想访问用户更详细的信息,则需要通过读取成员得到用户的姓名、头像等完整信息。

在示例代码的 /routes/index.js 文件中,展示了从重定向URL里解析成员授权code的基本流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
router.get(Config.app_path, async function (req, res, next) {
let { code } = req.query;
if (code) {
let access_token = await AccessToken.getToken();
if (access_token) {
let { data: user_detail_data } = await axios.get(`https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=${access_token}&userid=${user_id}`);
console.log('获取成员详细信息成功', user_detail_data);
req.session.user = user_detail_data;
}
else {
res.render('error');
}
}

实操过程

借助PostMan接口工具获取用户的userid(用手机号获取):https://qyapi.weixin.qq.com/cgi-bin/user/getuserid?access_token=ACCESS_TOKEN,链接里的ACCESS_TOKEN自行替换为实际的access_token值。

打开PostMan,在左上角New collection处右键选择Add collection:

点击新弹出的窗口的Get输入框选择POST,输入链接,选择下方的Body,选择row,填写对应的参数后,点击Send:

然后便可在下方的Body处看到userid的值:

向成员发送信息

调用企业内部的开放接口,都需要带上企业的接口凭证,且必须以 query 参数形式传递。而应用消息推送接口需要指定当前应用的 agent_id。

企业微信的应用消息推送支持不同的消息类型,比如文本、图片、语音、文件等,不同类型的消息类型需要指定对应的消息种类 msgtype。

在示例代码的 /routes/index.js 文件中,编写向成员发送信息的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

router.get(Config.app_path, async function (req, res, next) {
let { code } = req.query;
if (code) {
let access_token = await AccessToken.getToken();
if (access_token) {
let {data:message_data} = await axios.post(`https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${access_token}`,
{"touser" : user_detail_data.userid,
"agentid" : agent_id,
"msgtype" : "text",
"text" : {
"content" : `Hello World! ${user_detail_data.name}`},
})
}
else {
res.render('error');
}
}

实操过程

参数说明:

参数 是否必须 说明
touser 指定接收消息的成员,成员ID列表(多个接收者用‘|’分隔,最多支持1000个)。 特殊情况:指定为"@all",则向该企业应用的全部成员发送
toparty 指定接收消息的部门,部门ID列表,多个接收者用‘|’分隔,最多支持100个。 当touser为"@all"时忽略本参数
totag 指定接收消息的标签,标签ID列表,多个接收者用‘|’分隔,最多支持100个。 当touser为"@all"时忽略本参数
msgtype 消息类型,此时固定为:text
agentid 企业应用的id,整型。企业内部开发,可在应用的设置页面查看;第三方服务商,可通过接口 获取企业授权信息 获取该参数值
content 消息内容,最长不超过2048个字节,超过将截断(支持id转译)
safe 表示是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0
enable_id_trans 表示是否开启id转译,0表示否,1表示是,默认0。仅第三方应用需要用到,企业自建应用可以忽略。
enable_duplicate_check 表示是否开启重复消息检查,0表示否,1表示是,默认0
duplicate_check_interval 表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时

注意:touser、toparty、totag不能同时为空。

若操作过程中出现IP不合法的错误,在应用信息页面将IP添加进企业可信IP里便可正常访问。

借助PostMan接口工具进行发送信息:https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN,链接里的ACCESS_TOKEN自行替换为实际的access_token值。

打开PostMan,在左上角New collection处右键选择Add collection。点击新弹出的窗口的Get输入框选择POST,输入链接,选择下方的Body,选择row,填写对应的参数后,点击Send:

然后便可在下方的Body处看到已经信息发送成功。

CATALOG
  1. 1. 创建应用
    1. 1.1. 创建准备
    2. 1.2. 创建应用
    3. 1.3. 配置信息
      1. 1.3.1. 可见范围
      2. 1.3.2. 应用主页
      3. 1.3.3. 配置HOST
  2. 2. 获取应用接口凭证
    1. 2.1. 获取企业ID corp_id
    2. 2.2. 获取应用 Secret
    3. 2.3. 获取应用接口凭证 access_token
  3. 3. 发送应用信息
    1. 3.1. 基本参数
    2. 3.2. 基本流程
      1. 3.2.1. 发送基本类型消息
      2. 3.2.2. 发送媒体类型消息
  4. 4. 获取登录用户信息
    1. 4.1. 配置可信域名
    2. 4.2. 构造网页授权链接
    3. 4.3. 解析成员授权code
    4. 4.4. 获取访问用户身份信息
    5. 4.5. 实操过程
  5. 5. 向成员发送信息
    1. 5.1. 实操过程