在微信接口开发中,许多服务的使用都离不开Access Token,Access Token相当于打开这些服务的钥匙,正常情况下会在7200秒内失效,重复获取将导致上次获取的Token失效,本文将首先介绍如何获取Access Token,再介绍如何通过Access Token来在微信内添加自定义菜单(注意,开发者需要申请测试账号来测试自定义菜单,如何申请请参照前文)。

申请Access Token

获取Access Token接口的网址如下:

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=[APPID]&secret=[APPSECRET]

方括号内的参数可以在测试账号首页找到,被涂抹处即是:

真实请求的实例如下:

执行上述请求后,接口返回的内容如下:

这里我们就拿到了接下来需要使用的access_token:

ZiBTYeRMEMeCEM-Ol9ny_NE-XkgRbsP4snOqTRLh_nfp_UzFsYXVDtguf7jbZt70IQRkmEwU1n0cbxdWmJTdNg

,该Token将在7200秒,也就是2个小时内失效,之后需要重新请求前面的URL获取新的Token。

 

创建自定义菜单目前服务号和通过认证的订阅号均可申请自定义菜单,成功创建自定义菜单后,微信公众账号界面如下图所示:

目前自定义菜单最多包括三个一级菜单,每个一级菜单最多包含五个二级菜单。一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分会以“…”代替。请注意,创建自定义菜单后,由于微信客户端缓存,需要一定时间才在微信客户端展现出来,最快捷的方式是重新关注微信公众账号,这样马上就能看到自定义菜单。

目前自定义菜单接口可实现两种类型的按钮:

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

view:用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的url值(网页链接),达到打开网页的目的。建议与网页授权获取用户基本信息接口结合,获得用户的登入个人信息。

创建菜单的接口如下:

https://api.weixin.qq.com/cgi-bin/menu/create?access_token=[ACCESS_TOKEN]

其中中括号内的变量ACCESS_TOKEN即为我们前面获得的Token值。接下来我们开发一个简单的Apex网页,我们将通过这个网页来创建自定义菜单。

WeChatUtilityPage:网页,负责提交创建自定义菜单的申请,并显示创建成功与否的结果;

WechatUtilityController: 控制器类,负责网页背后的具体业务逻辑处理。

WeChatUtilityPage的源代码如下:

 <apex:page standardstylesheets="false" showHeader="false" sidebar="false" controller="WechatUtilityController">
<apex:form >
<font face="微软雅黑"><strong>菜单服务系列:</strong><br /><br />
<apex:commandButton value="注册微信菜单" action="{!register}" id="register" />
</apex:form>
{!msg}
<apex:pageMessages />
</apex:page>

画面非常简单,只有一段文字显示以及一个“注册微信菜单”按钮,点击按钮将处罚WechatUtilityController里的register方法,返回消息通过msg对象来显示,该对象的定义也在WechatUtilityController里,如果有系统异常,则将通过<apex: pageMessage/>来显示异常堆栈信息。下面我们看来看代码:

 public class WechatUtilityController {
public static String msg{get;set;} public String accessToken{get;set;}
public WechatUtilityController (){
accessToken = ‘ZiBTYeRMEMeCEM-Ol9ny_NE-XkgRbsP4snOqTRLh_nfp_UzFsYXVDtguf7jbZt70IQRkmEwU1n0cbxdWmJTdNg’;
} public void register(){
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setMethod('POST');
req.setHeader('Accept-Encoding','gzip,deflate');
req.setHeader('Content-Type','text/xml;charset=UTF-8');
req.setHeader('User-Agent','Jakarta Commons-HttpClient/3.1'); String xml = '{"button":[{"name":"关于我们","sub_button":[{"type":"click","name":"公司简介","key":"公司简介"},{"type":"click","name":"社会责任","key":"社会责任"},{"type":"click","name":"联系我们","key":"联系我们"}]},{"name":"产品服务","sub_button":[{"type":"click","name":"微信平台","key":"微信平台"},{"type":"click","name":"微博应用","key":"微博应用"},{"type":"click","name":"手机网站","key":"手机网站"}]},{"name":"技术支持","sub_button":[{"type":"click","name":"文档下载","key":"文档下载"},{"type":"click","name":"技术社区","key":"技术社区"},{"type":"click","name":"服务热线","key":"服务热线"}]}]}'; req.setBody(xml);
req.setEndpoint('https://api.weixin.qq.com/cgi-bin/menu/create?access_token=‘ + accessToken);
String bodyRes = ‘’; try{
HttpResponse res = h.send(req);
bodyRes = res.getBody();
}
catch(System.CalloutException e) {
System.debug('Callout error: '+ e);
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, e.getMessage()));
}
msg = bodyRes;
} }

上面的代码构造了一段XML文,并将此XML问Post到req.setEnpoint方法里制定的URL。XML里即包含了对自定义菜单内容的具体定义,该XML的接口要求如下:

完成后保存代码即可看到前面微信截图所显示的效果。

创建菜单点击事件处理方法

前面的菜单中我们定义的都是click类型的菜单,但该类型菜单被点击的时候,微信将经由腾讯服务器向开发者指定的URL发送一段XML文,该XML的结构说明如下:

这和我们前面处理用户发送消息的方式其实是一致的,我们可以在前文准备的方法架构基础上添加处理代码,找到前文的如下代码段:

 if(msgType.equals('text')){
rtnMsg = handleText(inMsg);
}

在该代码段的基础上点击else处理分支:

 if(msgType.equals('text')){

         rtnMsg = handleText(inMsg);

 }
else if(msgType.equals('event')){
rtnMsg = handleEvent(inMsg);
}

上面的代码else分支判断如果用户发送来的消息类型是event类型则调用handleEvent方法来处理,此时用户可能是关注了微信账号,可能是取消了关注,也可能是点击了菜单…,在handleEvent方法里要进一步判断,留意方法里的eventKey是前面XML里用户自定义的:

 private static String handleEvent(IncomingMsg msg){
String event = msg.event;
String strTmp = '';
if(event.equals('subscribe')){
strTmp = '欢迎关注本账号!';
}
else if(event.equals('unsubscribe')){
strTmp = '';
}
else if(event.equals('CLICK')){
strTmp = '您点击了' + msg.eventKey;
}
String result = composeTextReply(msg, strTmp);
return result;
}

其中composeTextReply方法的定义如下:

  private static String composeTextReply(IncomingMsg msg, String content){
String strTmp = '<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>12345678</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[{2}]]></Content></xml>';
String[] arguments = new String[]{msg.fromUserName, msg.toUserName, content};
String strReply = String.format(strTmp, arguments);
return strReply;
}

方法运行效果如下,当用户点击了微信菜单后,系统会自动将eventKey里包含的信息发送给用户,这里是为了演示效果进行的简化,真实场景里可以根据需求进行具体功能订制:

 
 

Force.com微信开发系列(四)申请Access Token及自定义菜单之创建菜单的更多相关文章

  1. Force.com微信开发系列(五)自定义菜单进阶及语音识别

    在上文里我们介绍了如何通过Force.com平台里为微信账号添加自定义菜单,本文里我们将进一步介绍如何查询菜单以及删除菜单的相关知识,最后会介绍微信平台如何进行语音识别的相关技术. 查询菜单 与创建菜 ...

  2. Force.com微信开发系列(八)生成带参数的二维码

    为了满足用户渠道推广分析的需要,公众平台提供了生成带二维码的接口.使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送.目前有两种类型的二维码,分别是临时二维码和永久二维码 ...

  3. Force.com微信开发系列(六)客服接口

    当用户主动发消息给微信公众账号的时候(包括发送信息.点击自定义菜单click事件.订阅事件.扫描二维码事件.支付成功事件.用户维权),微信将会把消息数据推送给开发者,开发者在一段时间内(目前为48小时 ...

  4. Force.com微信开发系列(三)申请测试账号及回复图文消息

    Force.com除了简单的文本消息回复外,还能回复图文并茂的消息.能回复音乐或者视频.能对用户发来的语音进行识别.能够搜集用户的地理位置信息并提供相应的内容或服务等,本文将对这些技能一一展开说明,在 ...

  5. Force.com微信开发系列(一) 后台配置

    为寻找国内免费云资源作为微信后台,花了一天时间试用SinaAppEngine(SAE),调试太不方便用户体验差.新浪作为媒体公司技术功底经不起考验,亚马逊能推出AWS,新浪还不行!更好选项是百度Bai ...

  6. Force.com微信开发系列(七)OAuth2.0网页授权

    OAuth是一个开放协议,允许用户让第三方应用以安全且标准的方式获取该用户在某一网站上存储的私密资源(如用户个人信息.照片.视频.联系人列表),而无须将用户名和密码提供给第三方应用.本文将详细介绍OA ...

  7. Force.com微信开发系列(二)用户消息处理

    Force.com是国际知名的云平台公司,成功配置好Force.com作为微信公开号的服务端后,接下来需要的任务是处理用户发送的消息.当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML ...

  8. 《C#微信开发系列(1)-启用开发者模式》

    1.0启用开发者模式 ①填写服务器配置 启用开发模式需要先成为开发者,而且编辑模式和开发模式只能选择一个(进入微信公众平台=>开发=>基本配置)就可以看到以下的界面: 点击修改配置,会出现 ...

  9. 《C#微信开发系列(Top)-微信开发完整学习路线》

    年前就答应要将微信开发的学习路线整理给到大家,但是因为年后回来这段时间学校还有公司那边有很多事情需要兼顾,所以没能及时更新文章.今天特地花时间整理了下,话不多说,上图,希望对大家的学习有所帮助哈. 如 ...

随机推荐

  1. MFC的消息管理

    一般而言,与视图状态和用户输入有关的命令由视图类来处理,与文件操作有关的命令由文档类来处理,与窗口布局有关的命令由主框架类来处理,与程序的运行状态有关的命令由APP类来处理.

  2. (adhoc) process launch failed: timed out waiting for app to launch

    I had a similar issue when trying to debug an App with Ad-Hoc provisioning... Check which provisioni ...

  3. 15套漂亮的 PSD 格式的图标,不一样的视觉效果

    在 Web 设计领域,图标发挥非常重要的作用,因为美丽的和创造性的图标集可以很容易地使网页设计更有吸引力.网页设计设计师专注于每一个领域的设计,包括颜色选择.图标.创造力.混色等.正确的选择图标可以使 ...

  4. Xcode-Xcode 7.3 解决不能自动联想问题

    一.问题: 升级Xcode 7.3 之后发现导入头文件之后,没法自动联想. 二. 解决办法: 打开Xcode --> Target --> BuildSettings --> App ...

  5. SQL Server 2014里的IO资源调控器

    在本文中,我们将来看看SQL Server 2014在资源调控器方面增加了哪些新的功能.资源调控器(Resource Governor)是从SQL Server 2008开始出现的一项功能.它是用于管 ...

  6. Jquery几个比较实用,但又让很多人忽略的几个函数

    工作中接触的人中,这些函数的使用频率比较少,我用的又比较好用的几个函数 来给大家分享一下. 你有你喜欢的,也可以分享一下 1.filter 使用了我要什么就有什么 这个函数不但可以很方便的筛选自定义H ...

  7. .Net魔法堂:史上最全的ActiveX开发教程——部署篇

    一.前言 接<.Net魔法堂:史上最全的ActiveX开发教程——发布篇>,后我们继续来部署吧! 二. 挽起衣袖来部署   ActiveX的部署其实就是客户端安装ActiveX组件,对未签 ...

  8. Dell_r720服务器部署

    没错,就是它-->                             前言:本来是写在word文档上作为笔记的,想想觉得不能浪费我在机房被狂虐两天总结出来的这点小经验, 还是分享一下吧,说 ...

  9. [团队项目]SCRUM项目4.0

    1.准备看板. 形式参考图4. 2.任务认领,并把认领人标注在看板上的任务标签上. 先由个人主动领任务,PM根据具体情况进行任务的平衡. 然后每个人都着手实现自己的任务. 3.为了团队合作愉快进展顺利 ...

  10. Winform开发框架的重要特性总结

    从事Winform开发框架的研究和推广,也做了有几个年头了,从最初的项目雏形到目前各种重要特性的加入完善,是经过了很多项目的总结归纳和升华,有些则是根据客户需要或者应用前景的需要进行的完善,整个Win ...