美文网首页程序猿阵线联盟-汇总各类技术干货
Node开发微信公众号(3)——微信菜单

Node开发微信公众号(3)——微信菜单

作者: Mr绍君 | 来源:发表于2018-05-05 11:35 被阅读42次

    开始之前照例说一下实现思路。

    要实现微信菜单,我们需要向微信服务器发送一个post请求,并把我们的菜单配置发送给微信服务器。


    从上图的请求地址我们可以看到,我们可以分为两步来实现,第一步获得access_token这个参数,第二步发送post请求创建菜单。


    1.获取access_token

    access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。所以说这个access_token是很重要的,而且这个票据只能保存2个小时,2个小时后就失效了,需要重新获取。

    我们先将请求地址配置到config上,因为微信上的请求接口他们的前缀都是一样的,所以我们可以把前缀提取出来。

    {
        "appID": "wxd27649727105b6d2",
        "appsecret": "a3f2eb9f5819b0bf4b2a92a81f99baf4",
        "token": "wechat",
        "prefix": "https://api.weixin.qq.com/",
        "diyApi": {
            "getAccessToken": "%scgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
            "createMenu": "%scgi-bin/menu/create?access_token=%s"
        }
    }
    

    代码中的%s是一个占位符,用于后面字符替换。然后我们给WeChat加个get请求方法和post请求方法,因为后面会经常用到。

    // 获取全局票据
    WeChat.prototype.getAccessToken =function() {
        var that = this;
        return new Promise(function(resolve,reject){
            var currentTime = new Date().getTime();
            //格式化请求地址,把刚才的%s按顺序替换
            var url = util.format(that.diyApi.getAccessToken, that.prefix, that.appID, that.appScrect);      
            //判断本地存储的 access_token 是否有效
            if(accessTokenJson.access_token === "" || accessTokenJson.expires_time < currentTime){
                that.requestGet(url).then(function(data){
                    var result = JSON.parse(data); 
                    if(data.indexOf("errcode") < 0){
                        accessTokenJson.access_token = result.access_token;
                        accessTokenJson.expires_time = new Date().getTime() + (parseInt(result.expires_in) - 200) * 1000;
                        //更新本地存储的
                        fs.writeFile('./wechat/access_token.json',JSON.stringify(accessTokenJson));
                        resolve(accessTokenJson.access_token);
                    }else{
                        resolve(result);
                    } 
                });
            }else{
                //将本地存储的 access_token 返回
                resolve(accessTokenJson.access_token);  
            }
        }); 
    }
    
    // 封装一个get请求方法
    WeChat.prototype.requestGet = function(url) {
        return new Promise (function(resolve, reject) {
            request(url, (error, response, body)=> {
                resolve(body);
            })
        })
    }
    

    node原生的请求需要些一些请求头之类的东西,所以这里用了一个新的模块,叫做request。用法也很比较简单,直接上npm上看下一就行。这里的票据是存在本地的access_token.json文件中,当然也可以存数据库,这个看个人需求。

    还有一个需要说明的是ES6的Promise用法,简单的说明一下:js的程序执行是单线程的,所以遇到O/I操作会发生阻塞,所以node使用了大量的回调函数。但是回调函数不是特别直观,所以es6提供了Promise用法,也是一种异步调用。

    想要深入了解,可以看一下阮一峰的ECMAScript 6 入门,这是一本免费的电子书http://es6.ruanyifeng.com/#docs/intro

    2.创建菜单

    微信开发文档提供了几种类型,我们照着写就行。


    {
        "button":[
           {    
             "type":"view",
             "name":"个人博客",
              "url":"http://xiaoxiagroup.top"
           },
           {    
             "type":"click",
             "name":"听歌",
             "key":"music"
           },
           {    
             "name":"小工具",
             "sub_button":[{
                  "type": "scancode_waitmsg", 
                  "name": "扫一扫",
                  "key": "scancode"
             },{
                  "type": "pic_sysphoto", 
                  "name": "系统拍照发图",
                   "key": "take_photo"
             },{
               "type": "location_select", 
               "name": "发送位置",
               "key": "send_location"
           }]
           }
        ]
    }
    

    封装一个post请求方法。

    // 封装一个post请求方法
    WeChat.prototype.requestPost = function(url, data) {
        return new Promise (function(resolve, reject) {
            request.post({url: url, form:data}, function(err,httpResponse,body){
                resolve(body);
            })
        })
    }
    

    至此,微信菜单也完成了。


    源码地址:https://github.com/yeshaojun/wechatBase
    如果喜欢就给我点个小星星吧!

    相关文章

      网友评论

        本文标题:Node开发微信公众号(3)——微信菜单

        本文链接:https://www.haomeiwen.com/subject/hzttrftx.html