![微信公众平台企业号开发揭秘](https://wfqqreader-1252317822.image.myqcloud.com/cover/489/26793489/b_26793489.jpg)
3.1 主动调用
何谓主动调用?主动调用是微信企业号基本的连接模式,为什么说它是基本的呢?因为当我们的应用需要调用企业号API的时候,建立HTTPS协议连接,数据包不需要解密,每次调用企业号API的时候,只需要调用AccessToken参数。稍后会细讲什么是AccessToken、AccessToken怎么获取及其使用期限。
3.1.1 主动调用概述
主动调用即企业号应用直接访问企业号API,根据用户的需要获取后台数据资源或发送消息给成员。主动调用不需要执行解密操作,直接连接微信企业号提供的API请求地址即可,剩下的就是获取数据并进行相应的操作处理。
3.1.2 获取AccessToken
AccessToken是请求微信API的访问票据,可以把AccessToken比喻成一张身份证,把需要做的一件事(如获取某个成员的身份信息)比喻成一个人,把微信API比喻成一个旅馆。当这个人去住旅馆时,就必须要出示身份证,以便旅馆工作人员登记这个人的入住信息,这样可以避免不法分子入住,有身份证的人才可以入住旅馆,才可以享受旅馆的服务,如此理解印象更深刻。
AccessToken需要用CorpID和Secret来获取,AccessToken使用期限为7200秒,在这个AccessToken还处于有效期内时,重复获取AccessToken将返回同一个AccessToken,直到这个AccessToken过期,再去获取AccessToken时,AccessToken才会是一个新的值。
怎么获取CorpID和Secret呢?接下来为大家详细介绍。
申请和注册企业号之后,找到需要的第一个参数CorpID,登录企业号,进入管理后台,单击“我的企业”,如图3-1所示。
进入“我的企业”页面,找到“企业信息”栏并将内容拖动到底部,如图3-2所示,界面框内的属性就是CorpID,这个属性很重要。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P53_1755.jpg?sign=1739284694-IOUcR0GgEyZlYuyXdK76IkzrHAQfc2Xp-0-fdaa26e0292d3473ccde40f82bcf5cbc)
图3-1 单击“我的企业”
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P53_1756.jpg?sign=1739284694-lSjCQ0izCapLwIkx4aUKeLCHf2DI0C6i-0-0bfa303e05c87bbee2d6ad4ad33816b8)
图3-2 获取CorpID
获取CorpID后,接下来获取Secret。
登录企业号,进入管理后台,单击“企业应用”选项,进入“企业应用”页面,单击其中的一个应用,如果没有应用,可以新建一个,如图3-3所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P53_1789.jpg?sign=1739284694-Q5ufrPhm3uVMihAqHzykVhcMDVekaKS6-0-3c8682fac03ca16f40289653fd831a88)
图3-3 创建新的应用
单击“创建应用”选项后,弹出如图3-4所示的界面。
填写新应用信息,单击“创建应用”按钮,如图3-5所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P53_1773.jpg?sign=1739284694-qJLKkfA4KQPJ0NAN86Wocbm45oWQzLv9-0-b709588bd97762ef8ef35b18116dd22f)
图3-4 填写新应用信息
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P53_1774.jpg?sign=1739284694-eVCnQSrulEnSpuXwE3hRoJ4E9vauG9L1-0-7655986894e880b74295f22c10164806)
图3-5 创建新的应用
稍后单击“企业应用”选项,进入“企业应用”页面,生成新应用“Android趣味堂”,如图3-6所示。
单击该应用,可以查看该应用的详情,方框内的就是Secret参数,如图3-7所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1801.jpg?sign=1739284694-ZEYoT6pGExKZW2hSbCrklerPEB6EGE14-0-bac54ffbc1e93e79be5522f9aef7a66d)
图3-6 新应用创建完成
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1802.jpg?sign=1739284694-Oa7ah2gJQsuVcQsg9GeEHZJa1T8ze9FD-0-845e8baf206e5f927e0dd153ac8d0cc5)
图3-7 获取Secret参数
在应用详情页还可以查看该应用的可见范围,就是对某些成员可见对某些成员不可见,由开发者设置。“Android趣味堂”应用的可见范围如图3-8所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1847.jpg?sign=1739284694-lzX0lkLuEnpXis0dJSCuqEMYwYzHMqZS-0-70ba889d15890f38af82b74b721b1a88)
图3-8 应用可见范围
在应用详情页还可以设置该应用的一些功能,如发送消息、网页授权及JS-SDK、设置应用主页、接收消息、自动回复、自定义菜单、企业微信授权登录,如图3-9所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1818.jpg?sign=1739284694-uybMEm44dqf4NHQcJHRDMbNQMwSICPWK-0-33b5254dedfdf78018d84313630f8305)
图3-9 应用功能设置
在应用详情页底部有“删除应用”选项。单击后可删除该应用,如图3-10所示。
在应用详情页右侧有一个停用、启用的Switch按钮,如图3-11所示,单击该按钮可以选择是否启用应用。若停用,则会弹出一个确认停用的窗口,提示“应用停用后,该应用在客户端中的消息将被删除”,单击窗口中的“停用”按钮可停用该应用。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1830.jpg?sign=1739284694-JlsUVbl7qF0iiOmJNtC1Jvps3AQRISAA-0-3e0c8c17809f051c96271d22d495123c)
图3-10 删除应用
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1831.jpg?sign=1739284694-fBkX2Rw0t1J4pRMg9sNPwI1EBbDYaPLE-0-7fbb2e4efb762ef86ef3c4e7bae16415)
图3-11 启用应用
至此,应用详情页的介绍就结束了,也获取了CorpID、Secret参数,接下来利用这两个参数来获取AccessToken。
在编程之前需要仔细阅读API,避免出现地址错误或参数错误,一定要看明白之后再开始写代码,否则很可能出现一些不必要的问题。
请求说明如下。
HTTPS请求方式:Get
请求地址:https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=id&corpsecret=secrect
参数说明见表3-1。
表3-1 参数说明
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-T55_65017.jpg?sign=1739284694-7u2Egl6xWfdD5Odo8pGA9byLxj8nknVg-0-3410f23cb447218e2105973703a9d343)
正确返回结果:
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P55_65020.jpg?sign=1739284694-3m61JUeRKGtuw8zncbuQLdteNQ2IoEXt-0-29d4153f2c2daef273c3b9f979caa245)
参数说明见表3-2。
表3-2 参数说明
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-T55_65021.jpg?sign=1739284694-RRAq9URy1UlhzFI1wmXwqivMgLmInuHg-0-44f044ab090b5e3702e5d089f72ee2ec)
错误返回结果:
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P55_65023.jpg?sign=1739284694-KEUR1RvOUQ71uvCnutToBmWZm10GkLvg-0-3a137890fa852755f8e8ebb69f711fd8)
编写一个获取AccessToken的程序来调用接口,为了方便读者看懂,笔者会把函数代码以及调用方法逐个贴出来,一定要仔细跟着输入代码并理解其意思,还可以根据注释来加深某个语句、某个函数的意义。注意,一定要先看完本章再开始写代码,因为部分章节是有联系的。
getAccessToken()代码如下。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P55_65024.jpg?sign=1739284694-ZiA5MbZJjfjl5sg3onOMKZlD7My3wwOE-0-177b30c676623f11a84b24cf5c081f70)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P56_65025.jpg?sign=1739284694-1vNoZn4QpoyNdVrYzMjkcMba6N9Tqhr4-0-975bf8887a4296def8151f21c40a0252)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P57_65026.jpg?sign=1739284694-aPUjTRHfvi2Rm5cehRscg0x9mW8eCTVj-0-ded1a05db5ec7dbb8c1c324ca36ec102)
代码有很详细的注释,大家要仔细阅读函数开始部分的带@parma、@author字样的文字,这是注释文档,可写可不写,但是笔者建议大家都写,并养成习惯。因为很多大项目被分成很多模块,每个模块在管理的时候必须要有非常详细的注释,方便交接、管理、后期维护。
HttpRequest()代码如下。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P57_65027.jpg?sign=1739284694-YlgNlvK9PlaP3lsGeNEhNB8qWcQyPYe5-0-8d1f4d4059dad9c6cb80eaa9f3dd63a2)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P58_65028.jpg?sign=1739284694-WInLyq2KgWPfQlgmifaIbD4G3rtilFbO-0-c03525fb8eb48d79da783bb714e6fd99)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P59_65029.jpg?sign=1739284694-uiAQFC6bqRJh5VtPsbyYWig6DOS9EfvF-0-a224d20cb1198103befbf26097f10b1b)
AccessToken类代码如下。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P59_65030.jpg?sign=1739284694-rg88o5lKRjtPXu3IgQhWa27DJy37SL4a-0-f16f2ad9c4314a0cd6b55238a3005a37)
下面示范getAccessToken函数的调用。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P59_65031.jpg?sign=1739284694-T4ocTTqAcK7IhSVG5oQb99TNheLRVIXJ-0-ec61a980e467af52840e124321a47b16)
范例获取到的结果值为7200,单位为秒。
获取到的AccessToken:ud5kEI0N52juvNsxJJZL1HCV3gxanUHeD72Z5aCBnYcfJUrR-wpmFMHQgX2jLl9OzGqq2Bx1APlo5UsOol5G6g。
有效时间:7200秒。
读者要注重理解,前期可以跟着敲代码,后面要慢慢建立起自己的代码体系、代码风格。
3.1.3 主动调用的频率限制
当获取到AccessToken时,应用就可以成功地调用企业号后台所提供的各种接口,以管理、访问企业号后台的资源或给企业号成员发消息。
为了防止因企业应用的程序错误而引发企业号服务器负载异常,默认情况下,每个企业号调用接口都有一定的频率限制,当超过此限制时,调用对应接口会收到相应错误码。
以下是当前默认的频率限制,企业号后台可能会根据运营情况调整此阈值。
- 基础频率
每个企业调用单个cgi/api不可超过1 000次/分,30 000次/小时。
每个IP调用单个cgi/api不可超过2 000次/分,60 000次/小时。
第三方应用提供商由于需要同时服务于多个企业,IP频率限制为:每个IP调用单个cgi/api不可超过20 000次/分,600 000次/小时。
- 发消息频率
每个企业不可超过账号上限数×30人次/天。
- 创建账号频率
每个企业创建账号数不可超过账号上限数×3/月。
- 创建应用频率
每个企业最大应用数限制为30个,创建应用次数不可超过30×3/月。
关于访问次数和AccessToken的时效性,可以合理安排访问的次数,AccessToken失效之后,程序没有再次去获取AccessToken会导致接口访问权限失效的错误。下面针对此问题写一个程序来解决。
3.1.4 防止AccessToken过期的处理
首先介绍具体思想,因为AccessToken的时效性是7200s,所以我们只需要给定两个写死的获取凭证的参数,判断这两个参数是否取到,没有值就需要自行配置。再启动一个线程,传参给新起的线程,写一个死循环,执行一次获取,对获取到的对象实例进行一次判断,如果值为null,就调用线程休眠,具体休眠时间看情况并结合API计算。
因为是死循环,所以当第二次取到值的时候,又进行了判断,当然这次不可能为null,除非参数有问题,这时就不需要继续执行下去,需要休眠线程,因为值已经取到了。根据API 7200s的时效性,每天2000次调用频率,其实2000次足够我们调用了,7200/3600=2h, 24/2h=12,每天12次就可以了,更何况是2000次呢?让线程休眠7000+s,之后的时间(7200-7000)剩下200+s,在200+s里可以重新唤醒线程开始对值判断,又可以合理管理调用时间间隔,具体以自己的需求情况为准。这样就可以避免AccessToken的失效了。
接下来介绍参数配置的问题,在web.xml里需要配置如下几个参数,作为线程启动及获取凭证的映射。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P61_65032.jpg?sign=1739284694-0aX4Fkndhl2KWeuWElrSMf1jmXE5JuOs-0-7b11a11d11679b919d6edc967dd291da)
servlet-name、servlet-class分别是类名和包名点类名,在init-param属性下配置好appid、appsecret。load-on-startup为0,就是当这个服务启动时,InitAccessTokenServlet自动启动并同时启动线程服务。
(1)通过配置<init-param>向Servlet中传入参数。
(2)通过配置<load-on-startup>使得Web服务器启动时就加载该Servlet。
(3)没有配置<servlet-mapping>,因为InitServlet并不对外提供访问。
接下来开始编写访问次数的程序,然后编写一个自定义的Servlet,继承自HttpServlet,代码如下。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P61_65033.jpg?sign=1739284694-7STF4gpAEYZJ3sAvu50eDG1KHoxbajGg-0-c8553555d4d6f7024845402bdc1466d6)
编写自定义线程,代码如下。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P62_65035.jpg?sign=1739284694-2ujDNcNIuGneVomj5cpRrdygGSswSoH6-0-4cb0cc069268e6cdb56d81c9e9862252)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P63_65036.jpg?sign=1739284694-adPu81o5csAzfht8WVdae0reQRGXZOlg-0-abae4938f3b2497ef52c9972e6bb412c)
线程打印测试如图3-12所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P63_4405.jpg?sign=1739284694-5sWQVGGe8eJhxU33Lwrz2ATOKYPOD9e3-0-02aabb4ce4126b398f13dd5cf40d0b7f)
图3-12 线程测试
服务开启之后,服务器日志打印,如图3-13所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P64_4417.jpg?sign=1739284694-uzFwCuUHbLTYIebaBnBpaPzr9beqYDxU-0-027ef1517f0e1eec2ffdb386a880fb48)
图3-13 服务器日志