首先需要确认一点,一旦接入第三方服务器,微信就认为你已经具备了开发能力,像自动回复、关键词回复、自定义菜单这些功能,微信公众平台就不再提供了(需要开发者调用相关接口),停用服务器之后,这些功能也就恢复了,二者是互斥的。

说明一下,本文的例子是node+express搭建服务,消息加解密方式为明文模式,请酌情参考。

一、搭建本地调试环境

二、服务器配置及校验

  现在我们已经有了一个可供公网访问的本地服务,接下来说一下微信公众平台的相关配置:

  登录微信公众平台,找到基本配置

  

  可以看到服务器配置一项(我这里是已经启用过的),点击右侧的修改配置

  

  先说一下大致流程,信息编辑完毕之后点击提交,微信服务器会向你所填写的URL发送一条get请求,你的服务器必须要能接到这条请求,然后拿微信服务器带来的参数进行验证,验证完毕之后,返回验证结果给微信,微信拿到想要的结果之后(至于具体返回什么,后面会说),你的服务器就算是在微信服务器“备案”成功了,接下来点击启用就可以了,启用之后,微信服务器一旦收到消息,就会向你所填写的URL发送一条post请求(确保你的服务器在5秒内做出响应,不然会发生一些错误,具体错误可查看微信文档),请求携带的参数是xml格式的,注意配置一下,不要以json的形式去接收,解析xml,能拿到信息发送者、接收者、信息内容、事件类型等数据,然后就可以根据事件类型、信息等做出相应的处理。

  填写URL:支持https和http,格式为http://xxxxxx.com+接口路径,例如https://www.baidu.com/authorize,https://www.baidu.com是你的服务地址,authotize是你的接口路径。

  填写Token:这儿的token是验证服务器的令牌,是你自己定义的,符合格式要求就行,后面会用到(注意区别access_token,两者不是一回事)。

  填写EncodingAESKey:可以随机生成,也可以自己定义,符合格式要求就好,当设置消息加解密方式为加密模式时会用来解密消息(本文采用明文模式)。

  选择消息加解密方式:本文选择明文模式。

  服务器验证:

  

// 服务器验证
// /authorize为接口路径,router.get('/authorize', (req, res) => {//接收到微信服务器的请求后,取出参数signature,timestamp,echostr,noncelet signature = req.query.signature;let timestamp = req.query.timestamp;let echostr = req.query.echostr;let nonce = req.query.nonce;// 把token、timestamp、nonce进行字典排序,CONFIG.token换为你自己的token就好let arr = [CONFIG.token, timestamp, nonce].sort();// sha1加密let str = arr.join('');let hashCode = crypto.createHash('sha1');let result = hashCode.update(str).digest('hex');// 与signature对比后返回结果if (result === signature) {// 验证正确之后,把echostr原封不动返回给微信就行了res.send(echostr);} else {// 验证错误的话也要返回信息,告诉微信不要再尝试请求了,微信官方建议直接返回success字符串,当然返回空也是可以的res.send('success');}
});

一定要处理好服务器验证逻辑之后再点击提交按钮,否则是提交不成功的。

提交成功之后,就算是接入服务器了,但是点击启用按钮,服务器才能起作用。

接下来是消息处理逻辑:

微信服务器在接收到用户消息之后,就会向你的服务器发送请求,URL和验证服务器的URL一样,只不过请求方式为post

// 消息处理
// 用xml2js模块来处理xml
let parseString = require('xml2js').parseString;
router.post('/authorize', (req, res) => {try {let buffer = [];// 监听data事件,用于接收数据,用req.body是拿不到数据的req.on('data', (data) => {buffer.push(data);});// 监听end事件,用于处理接收完成的数据req.on('end', () => {parseString(Buffer.concat(buffer).toString('utf-8'), {explicitArray: false}, (err, result) => {// 处理错误if (err) {console.log('解析微信服务器发来的消息出错了:');console.log(err);res.send('success');return false;}if (!result || !result.xml) {// 未接收到有效消息,告诉微信服务器不要再尝试连接res.send('success');return console.log('未接收到任何消息也未发生任何事件');}result = result.xml;// 接收方微信(注意接收方和发送方的转换)let toUser = result.FromUserName;// 发送方微信let fromUser = result.ToUserName;let userMessage = result.Content;console.log('-----------------------开始处理消息-----------------------');if (result.Event == 'subscribe') {// 如果是用户关注console.log('--------------------有用户关注了---------------------------');handleAutoReply(res, toUser, fromUser, 'subscribe');} else {// 其他消息if (result.MsgType != 'text') {res.send('success');console.log('------------------不是文本类型的消息暂不处理----------------------');return false;}// 文本消息// 这里可以处理一些特殊回复,比如发送编码查询等// 处理关键词自动回复console.log('-----------------------现在处理关键词回复------------------------');handleAutoReply(res, toUser, fromUser, userMessage);}});});} catch(err) {console.log(err);res.send('success');}
});
/*** [handleAutoReply description]* @param  {Object} res         [response对象]* @param  {String} toUser      [接收方]* @param  {String} fromUser    [发送方]* @param  {String} keyword     [关键词]* @return {String} xmlContent  [消息模板]*/
function handleAutoReply(res, toUser, fromUser, keyword) {// messageMap是含有关键词回复key-value的json,根据不同的关键词,向用户发送不同消息let messageMap = JSON.parse(JSON.stringify(messageJson));let content = messageMap[keyword];if (!content) {res.send('success');return false;}let xml = returnText(toUser, fromUser, content);res.send(xml);
}
/*** [returnText description]* @param  {String} toUser      [接收方]* @param  {String} fromUser    [发送方]* @param  {String} content     [消息内容]* @return {String} xmlContent  [消息模板]*/
function returnText(toUser, fromUser, content) {let xmlContent = `<xml><ToUserName><![CDATA[${toUser}]]></ToUserName><FromUserName><![CDATA[${fromUser}]]></FromUserName><CreateTime>${new Date().getTime()}</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[${content}]]></Content></xml>`;return xmlContent;
}

一定要注意错误处理,微信收不到正确响应时,会尝试重新请求,所以一旦程序发生未知错误,要及时处理,并且通知微信不要再尝试发送请求了(发送success字符串即可),否则微信会提示用户接入的服务器异常。

至此,消息回复的逻辑已经处理完了。但是接入自己的服务器之后,之前在微信公众平台设置的自定义菜单也没了,需要我们调用接口去配置;

配置自定义菜单:

打开微信接口调试页面:https://mp.weixin.qq.com/debug

输入你的appid和secret,由于配置自定义菜单之后,菜单就会一直存在,不需要代码去维持,所以我选择了在这儿获取access_token,当然你也可以在你的程序中去获取,然后再写个配置菜单的页面,那就更方便了。

然后选择接口类型为自定义菜单:

access_token填你刚才获取的就好,注意这个是有时效的,一般为7200秒,过期的话再重新获取就好了。

body是你配置菜单的json,简单讲一下:

{"button":[{    "type":"click","name":"今日歌曲","key":"V1001_TODAY_MUSIC"},{"name":"菜单","sub_button":[{    "type":"view","name":"搜索","url":"http://www.soso.com/"},{"type":"miniprogram","name":"wxa","url":"http://mp.weixin.qq.com","appid":"wx286b93c14bbf93aa","pagepath":"pages/lunar/index"},{"type":"click","name":"赞一下我们","key":"V1001_GOOD"}]}]}

button是一级菜单数组,每个元素代表一个一级菜单,注意一级菜单最多三个,每个菜单最多4个字,超出显示...,每个一级菜单下的二级菜单最多5个,每个二级菜单最多7个字,超出显示...。

type是按钮类型,根据需要选择就好:

1

2

3

4

5

6

7

8

9

10

1、click:点击推事件用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;

2、view:跳转URL用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取用户基本信息接口结合,获得用户基本信息。

3、scancode_push:扫码推事件用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后显示扫描结果(如果是URL,将进入URL),且会将扫码的结果传给开发者,开发者可以下发消息。

4、scancode_waitmsg:扫码推事件且弹出“消息接收中”提示框用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后,将扫码的结果传给开发者,同时收起扫一扫工具,然后弹出“消息接收中”提示框,随后可能会收到开发者下发的消息。

5、pic_sysphoto:弹出系统拍照发图用户点击按钮后,微信客户端将调起系统相机,完成拍照操作后,会将拍摄的相片发送给开发者,并推送事件给开发者,同时收起系统相机,随后可能会收到开发者下发的消息。

6、pic_photo_or_album:弹出拍照或者相册发图用户点击按钮后,微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。用户选择后即走其他两种流程。

7、pic_weixin:弹出微信相册发图器用户点击按钮后,微信客户端将调起微信相册,完成选择操作后,将选择的相片发送给开发者的服务器,并推送事件给开发者,同时收起相册,随后可能会收到开发者下发的消息。

8、location_select:弹出地理位置选择器用户点击按钮后,微信客户端将调起地理位置选择工具,完成选择操作后,将选择的地理位置发送给开发者的服务器,同时收起位置选择工具,随后可能会收到开发者下发的消息。

9、media_id:下发消息(除文本消息)用户点击media_id类型按钮后,微信服务器会将开发者填写的永久素材id对应的素材下发给用户,永久素材类型可以是图片、音频、视频、图文消息。请注意:永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id。

10、view_limited:跳转图文消息URL用户点击view_limited类型按钮后,微信客户端将打开开发者在按钮中填写的永久素材id对应的图文消息URL,永久素材类型只支持图文消息。请注意:永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id。

根据需要,组织好你的json,填入body输入框就行了,点击检查问题,如果检查通过,菜单就创建成功了,检查失败的话,再具体看一下报错信息。首次设置会立即生效,修改的话需要5分钟才刷新,可以选择先取消关注公众号,然后再关注,就能立即看到效果了。

这里讲的都是通过微信接口调试页面做的,流程都是一样的,当然也可以写在你的程序里,按步骤调用相关接口就行了。

微信公众号接入第三方服务器,设置自动回复、关键回复、自定义菜单,配置及开发流程相关推荐

  1. 微信公众号接入第三方服务器,设置自动回复、关键回复、自定义菜单,配置及开发流程...

    首先需要确认一点,一旦接入第三方服务器,微信就认为你已经具备了开发能力,像自动回复.关键词回复.自定义菜单这些功能,微信公众平台就不再提供了(需要开发者调用相关接口),停用服务器之后,这些功能也就恢复 ...

  2. 微信公众号接入图灵机器人实现自动回复消息

    2019独角兽企业重金招聘Python工程师标准>>> 1.创建图灵机器人 进入图灵机器人网址:http://www.tuling123.com/ 登录/注册,进入机器人管理,然后点 ...

  3. jsp中设置自动换行_微信公众号文章中如何设置自动回复?

    小客服 大家一定都清楚微信公众号的输入关键字就自动回复功能,像这样,我进入一个指定的微信公众号,在聊天界面发送关键字,比如:英语四六级,立马就会弹出相应的资料或链接给我.但是这种便捷的方式没法在文章中 ...

  4. 微信公众号接入第三方管理平台和创建微官网

    一.接入第三方管理平台 1.为什么要接入? 接入第三方管理平台是为了获取扩展功能,而自身又没有相应的开发能力,所以只能依靠第三方管理平台来实现功能.比如:抽奖.问卷.天气查询,数据分析等. 2.有哪些 ...

  5. 微信公众号接入第三方平台

    第一步 授权事件接收URL http://www.falago.cn/weiweb/wei/wei_inceptmsg 在第三方的授权事件填写自己服务器的url,微信服务器会向其"授权事件接 ...

  6. 微信公众号接入web服务器,asp.net Web API 接入微信公众平台验证服务器,接收微信发送的POST请求...

    验证签名,接入微信公众平台:不能直接返回String,直接返回String微信服务器不接受. // GET: api/checkSignature/5 public HttpResponseMessa ...

  7. PHP 支付PC端扫码支付、APP接口调起支付宝支付、微信公众号接入支付宝支付

    第一:第三方支付原理 第二:支付接口申请流程 地址:https://docs.open.alipay.com/270/105899/ : 参考地址:https://blog.csdn.net/nove ...

  8. 微信公众号接入图灵机器人

    微信公众号接入图灵机器人 1. 申请一个微信公众号 这个步骤和申请一个小程序了类似,首先进入微信公众平台进行注册,关键是注册的时候是选择订阅号,还是服务号,我觉的如果你是自己做着玩的,就搞个订阅号,订 ...

  9. 2014-07-23 .NET实现微信公众号接入

    今天是在吾索实习的第11天.今天我跟我的实习小组的组员们,解决了关于使用ASP.NET进行微信公众号接入的问题.因为我们小组成员也是刚接触微信公众号的二次开发,所以在解决该问题的工程中也走了不少弯路. ...

最新文章

  1. Lucene6.0 创建索引及查询text简单实例
  2. 作者:程学旗,男,中国科学院计算技术研究所研究员、博士生导师,中国科学院“网络数据科学与技术”重点实验室主任。...
  3. json字符串使用注意问题
  4. 获取客户端IP和MAC
  5. python无法使用物理网卡_Python 实现监控所有物理网卡状态
  6. utf-8下编辑的时候字体不能直接识别,但是可以识别 unicode 编码表
  7. 梯度下降法中的参数学习速率如何选择
  8. 智慧农业技术解决方案
  9. aliez歌词_aLIEz FULL歌词【假名 罗马音】
  10. 三个常用的apk分析网站对比:VirusTotal、哈勃、摸瓜
  11. 不等缓和曲线计算公式及坐标?
  12. Windows异常学习笔记(三)—— VEHSEH
  13. Hbuilder如何替换选中代码快捷键
  14. 北京信息科技大学计算机学院官网,北京信息科技大学教务处官网入口地址
  15. pa服务器系统,常见问题
  16. 你旁边的电闸有辐射或者其它危害吗?
  17. 小陈java学习笔记0805
  18. PC威信 3.7.5 测试HOOK接口
  19. 2019给自己立个小目标
  20. ofdm系统matlab仿真,基于Simulink 的OFDM 系统仿真分析

热门文章

  1. Java API操作ZK node
  2. Spring 构造器注入
  3. mysql int mediumint,MySQL数据类型:TINYINT, SMALLINT, MEDIUMINT, INT, INTEGER等字段类型区别...
  4. Android动态屏蔽IP地址
  5. 邀请新用户奖励现金活动的一些反思
  6. 《神经网络与深度学习》 邱希鹏 学习笔记(一)
  7. 情人节快乐 | 请收下这份礼物
  8. 雅克比矩阵的简单理解(手稿)
  9. 全新PHP程序开发在线工单管理系统源码,售后工单系统
  10. 掌握好linkedin的这些技巧,你就已经超越了80%的跨境人