TECH NOTES / 开发实践
企业微信自建应用开发笔记
原笔记 2021-09-26 · 整理于 2026-10-05
企业微信自建应用的术语、授权流程、消息推送与旧版 JS-SDK 接入记录。
版本说明:这是一份包含 2018 年接口与界面的学习记录。保留术语与交互过程供理解,授权范围、返回字段、素材有效期和 JS-SDK 配置请以当前企业微信文档为准。

术语
corpid:企业ID 每个企业都有唯一的corpid:我的企业--企业信息
userid:每个成员都有唯一的userid(账号):通讯录--成员详情页
部门id:每个部门都有唯一的id:通讯录-组织架构-部门右边的小圆点
-tagid:每个标签都有唯一的标签id:通讯录-标签agentid:每个应用唯一的id:应用与小程序-应用详情页
secret:企业应用中用于保障数据安全的钥匙【跟agentid配套】 ,目前的secret:
自建应用secret:应用与小程序--应用--自建--某应用
基础应用secret:【如审批,打卡等应用】企业与小程序--应用--基础--某应用--点开API小按钮
通讯录管理secret:通讯录同步【需开启api接口同步】
外部联系人管理secret:外部联系人--点开API小按钮
access_token:是企业后台去企业微信的后台获取信息时的重要 票据,由corpid和secret产生。所有接口在通信时都需要携带access_token用于验证接口的访问权限
每个企业号CorpID只有一个,但Secret却有几种,不同Secret获取到的令牌它的作用范围是不同的。
Secret分类如下:
- 应用Secret:点击“应用详情”就看到了
- 通讯录管理Secret:查看方式是“管理工具/通讯录同步”
- 管理组Secret:查看方式是“我的企业/权限管理/管理组”(你如果找不到也很正常,因为这是老用户才有的“待遇”,现已退出历史舞台,奸笑ing)。
应用
按提供方来分有三种:
- 基础应用:由微信提供;
- 第三方应用:开放体系下的第三方服务商提供;
- 自建应用:我们自己新建的,一般我们也都是需要自建应用进行开发。
按作用来分有两种:
- **主页型应用:**用户点击应用后直接打开一个链接;
- **消息型应用:**可以像公众号一样设置多个菜单,每个菜单可以配置不同的响应方式。
以下展示一个应用详情界面:

应用详情
从上图我们可以看出,一个应用主要包含以下几方面的信息:
- AgentId:应用ID,新建应用后由微信生成;
- Secret:应用的Secret,结合CorpID用来获取access_token;
- 可见范围:哪些人能看到这个应用(可按人、按部门或者按标签进行设定);
- **管理员:**可对该应用进行管理的人;
- 可信域名:应用网页相关地址需要满足对应接口的可信域名配置要求。原笔记中的示例为
www.example.com或test.example.com:3000,实际要求请按当前控制台与接口文档核对; - 工作台应用主页:配置用户点击应用后跳转的链接地址,配置后该应用即为主页型应用;
- **自定义菜单:**设置后表示应用为消息型工作台应用主页链接将失效,设置方式类似于公众号。
访问令牌
访问令牌(access_token)是我们开发的第一步,我们在调用微信接口前,往往需要先获取令牌,然后才能“为所欲为” :- )。
令牌只能通过企业ID(CorpID)+Secret来获取,CorpID的查看方式如下:

每个企业号CorpID只有一个,但Secret却有几种,不同Secret获取到的令牌它的作用范围是不同的。
Secret分类如下:
- 应用Secret:点击“应用详情”就看到了
- 通讯录管理Secret:查看方式是“管理工具/通讯录同步”
- 管理组Secret:查看方式是“我的企业/权限管理/管理组”(你如果找不到也很正常,因为这是老用户才有的“待遇”,现已退出历史舞台,奸笑ing)。

应用Secret

通讯录管理Secret

曾经的管理组Secret
获取令牌的接口是:
GET https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=CORPID&corpsecret=SECRECT
返回格式如下:
{
"errcode": 0,
"errmsg": "",
"access_token": "accesstoken000001",
"expires_in": 7200
}需要注意的是access_token具有时效性,超过7200(expires_in的值)秒后就会过期,又因为获取令牌的接口有访问频率的限制,所以你需要定时刷新access_token。
详细文档请参考:获取access_token - 企业微信。
场景一:网页授权登录
参考文档:网页授权登录 - 企业微信
这是我们使用频率最高的一个场景,简单的说就是:如何在用户进入应用的时候获取到他的userid(或者更详细的信息)?
授权登录使用OAuth2.0协议,先来看看微信官方提供的接入流程图:

总结下来就是三步:
- 用户访问时先跳微信服务器,同时你需要告诉微信服务器一个跳转地址
- 微信服务器先做验证,验证通过后回跳到你提供的地址,并同时带上一个跟用户信息相关的code
- 你根据这个code再调用另一个接口就能获取到用户数据了,一般在后端服务器做处理
第1,2步都是为了拿到code,第3步才是获取用户信息。
假如我有一个主页型应用,基本信息如下:
- 企业ID:wx10101
- 可信域名:test.example.com:3000
- 回调地址:https://test.example.com:3000/api/myredirect ,回调地址一般为后端服务器
那么生成的网页链接是这样的(该链接可设置为主页地址、菜单链接和推送消息的跳转链接):
这里有两点需要注意的地方:
- redirect_uri的值必须经过urlencode处理(可直接调用JS的全局函数encodeURIComponent)
- redirect_uri的host部分(即域名+端口)必须和可信域名配置一致
- 如果你将一些信息从用户点击传递到回调地址,那么可以设置state参数(只有这一种传递方式)
获取用户信息的接口是(注意code只能使用一次):
GET https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access\_token=ACCESS\_TOKEN&code=CODE
返回结果:
a) 当用户为企业成员时(无论是否在应用可见范围之内)返回示例如下:
{
"errcode": 0,
"errmsg": "ok",
"UserId":"USERID",
"DeviceId":"DEVICEID"
}
参数 | 说明 |
errcode | 返回码 |
errmsg | 对返回码的文本描述内容 |
UserId | 成员UserID。若需要获得用户详情信息,可调用通讯录接口:读取成员。如果是互联企业或者企业互联,则返回的UserId格式如:CorpId/userid |
DeviceId | 手机设备号(由企业微信在安装时随机生成,删除重装会改变,升级不受影响) |
b) 非企业成员时,返回示例如下:
{
"errcode": 0,
"errmsg": "ok",
"OpenId":"OPENID",
"DeviceId":"DEVICEID",
"external_userid":"EXTERNAL_USERID"
}
参数 | 说明 |
errcode | 返回码 |
errmsg | 对返回码的文本描述内容 |
OpenId | 非企业成员的标识,对当前企业唯一。不超过64字节 |
DeviceId | 手机设备号(由企业微信在安装时随机生成,删除重装会改变,升级不受影响) |
external_userid | 外部联系人id,当且仅当用户是企业的客户,且跟进人在应用的可见范围内时返回。如果是第三方应用调用,针对同一个客户,同一个服务商不同应用获取到的id相同 |
出错返回示例:
{
"errcode": 40029,
"errmsg": "invalid code"
}
场景二:扫码授权登录
参考文档:扫码授权登录 - 企业微信
我们这里只讨论Web网页扫码登录的场景,移动端扫码登录请参考官方文档。
在开发扫码登录前,你需要先开启应用的网页接入功能,开启方式是点击“应用详情/企业微信授权登录/Web网页”,直接将可信域名的值复制过来设置即可。
扫码登录与场景一类似,同样是OAuth2.0协议,也是先拿code再拿用户信息,交互流程图如下:

假如我有以下基本信息:
- 企业ID:wx10101
- 应用ID:1000000
- 可信域名:http://test.example.com:3000
- 回调地址:https://test.example.com:3000/api/myredirect
那么生成的扫码链接是这样的:
用户打开该链接后,就会出现一个二维码,用户使用企业微信扫码后,就会跳转到回调地址并带上授权code,通过code获取用户信息的接口为:
GET https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access\_token=ACCESS\_TOKEN&code=CODE
场景三:素材管理
参考文档:素材管理 - 企业微信
素材管理比较简单,直接调用微信接口即可,不过需要注意的是,目前企业微信只开放了临时素材的管理接口(今天是2018-05-04),所有通过接口上传的media_id仅三天内有效。
后台管理页面中的资源标识不代表公开 API 承诺长期可用。应用应按正式素材接口处理上传、有效期与重新获取,避免依赖后台页面的内部请求。
场景四:消息推送
参考文档:发送应用消息 - 企业微信
本质上就是调用一个接口而已。
需要注意的是,消息都是以应用为单位显示的(在发送消息的时候会指定agentid),所以你调用接口所使用的access_token必须是通过该应用的Secret获得的。
如果你希望对消息内容进行排版(用html的方式),且用户点击后,你希望跳转到一个网页地址去,我推荐你使用“文本卡片消息”。

我们之前还遇到过一个场景是,希望用户在点击消息后,跳转到其他应用去,但遗憾的是目前微信还不支持跨应用跳转。
场景五:JS-SDK
参考文档:JS-SDK - 企业微信
要用JS-SDK,客户端必须要进行SDK初始化;
要进行初始化,必须要有个签名;
要有个签名,必须要有个jsapi_ticket。
所以我们先说说jsapi_ticket。jsapi_ticket其实跟access_token类似,它也会过期,也有频率限制,所以我们也需要对jsapi_ticket进行定时刷新,获取jsapi_ticket的接口如下:
GET https://qyapi.weixin.qq.com/cgi-bin/get\_jsapi\_ticket?access\_token=ACCESS\_TOKEN
接下来是签名,分享一个node的签名算法供参考:
const qs = require('querystring');
/**
* 签名生成算法
* @param {*} query
*/
function sign(query) {
// 1.排序
const obj = qs.parse(query);
const message = Object.keys(obj).sort().map(key => `${key}=${obj[key]}`).join('&');
// 2.加密
const signature = crypto.createHash('sha1').update(message, 'utf8').digest('hex');
return signature;
}
// 测试
const query = 'noncestr=Wm3WZYTPz0wzccnW&jsapi_ticket=EXAMPLE_TICKET×tamp=1414587457&url=http://mp.weixin.qq.com?params=value';
console.log(sign(query));
// 示例票据仅用于演示,结果以实际参数为准。如果你不确定你的算法是否正确,可以去微信提供的在线签名工具进行验证。
有了签名以后,我们就可以进行SDK初始化了,初始化前需要引入js文件:
http://res.wx.qq.com/open/js/jweixin-1.2.0.js(支持https)
然后开始执行初始化:
beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,企业微信的corpID
timestamp: '', // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '', // 必填,签名,见附录1
jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
// 成功回调ready
wx.ready(function(){
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
// 失败回调error
wx.error(function(res){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});这里需要注意的是所有参数都是大小写敏感的,比如后端签名时参数是noncestr,但是前端初始化时是nonceStr。
初始化成功后,就可以尽情地浪了。使用企业微信打开以下链接即可体验官方提供的Demo页面:
http://work.weixin.qq.com/api/jsapidemo (二维码自动识别)
最后说两句
- 严格按照文档中要求的去做会少栽很多坑,不要看漏任何一个细节,例如大小写;
- 如果你已经按照文档要求去做了,还是未达到理想效果,那你可以安装一个开发者工具,尝试下从控制台输出信息去进行调试(微信的开发者工具是可以模拟整个微信环境的);
- 如果还是解决不了你的问题,那你就直接找客服吧(企业微信的客服反馈还是很及时的,在企业微信客户端的客服对话框中,输入“人工”即可)。
企业微信客服入口