微信公众号开发 + node.js服务器部署(二)

亢建白
2023-12-01

上篇写到自己自动回复信息。其他的类型可以看开发文档,自己封装两种方法。一个是用户发给公众号的信息,另一个是公众号返回给客户。但一遍大多数,就是扫面关注之后,自动欢迎语句,或者输入数字,或者简短文字;公众号返回文本。

七.自定义菜单

menu.js

/**
 * 自定义菜单
 */
module.exports = {
    "button":[
    {    
         "type":"click",
         "name":"点我啊~",
         "key":"V1001_CLICK_ME"   //eventkey
     },
     {
          "name":"菜单二",
          "sub_button":[
          {    
              "type":"view",
              "name":"搜索",
              "url":"http://www.baidu.com/"
           },
           {
            "type": "scancode_waitmsg", 
            "name": "扫码带提示", 
            "key": "扫码带提示", 
        }, 
        {
            "type": "scancode_push", 
            "name": "扫码推事件", 
            "key": "扫码带提示", 
        },
        // {
        //     "type": "media_id", 
        //     "name": "图片", 
        //     "media_id": "MEDIA_ID1"
        //  }, 
        //  {
        //     "type": "view_limited", 
        //     "name": "图文消息", 
        //     "media_id": "MEDIA_ID2"
        //  }
        ]
      },
      {
        "name": "发图", 
        "sub_button": [
            {
                "type": "pic_sysphoto", 
                "name": "系统拍照发图", 
                "key": "系统拍照发图", 
             }, 
            {
                "type": "pic_photo_or_album", 
                "name": "拍照或者相册发图", 
                "key": "拍照或者相册发图", 
            }, 
            {
                "type": "pic_weixin", 
                "name": "微信相册发图", 
                "key": "微信相册发图", 
            },
            {
                "name": "发送位置", 
                "type": "location_select", 
                "key": "rselfmenu_2_0"
            },
        ]
        }, 
    ]
}

js文件

 //创建菜单
    createMenu(menu){
        return new Promise(async(resolve,reject) => {
            try{
           // 获取access_token
           const data = await this.fetchAccessToken()
            const url = `https://api.weixin.qq.com/cgi-bin/menu/create?access_token=${data.access_token}`
            // 发送请求
            const result  =await rp({method:'POST',url,json:true,body:menu})
            resolve(result)
            }catch(e){
                reject('createMenu errer:'+e)
            }
        })
    }
    //清空菜单
    deleteMenu(){
        return new Promise(async(resolve,reject) => {
            try{
            const data = await this.fetchAccessToken()
            const url = `https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=${data.access_token}`
            const result = await rp({method:'GET',url,json:true})
            resolve(result)
            }catch(e){
                reject('deleteMenu errer:'+e)
            }
        })
    }

八.js-sdk

微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。
临时票据jsapi_ticket
方法跟之前获取access类似

// 页面路径公用提取出来了,测试可以把全路径放上去

const prefix ='https://api.weixin.qq.com/cgi-bin/';
module.exports = {
    accessToken : `${prefix}token?grant_type=client_credential`,
    ticket:`${prefix}ticket/getticket?type=jsapi`,
    menu:{
        create:`${prefix}menu/create?`,
        delete:`${prefix}menu/delete?`
    }
}


/

getTicket() {
        // 发送请求
        // 服务器端不能ajax 使用 request request-promise-native,返回的是promise对象
        return new Promise((resolve, reject) => {
            const data = this.fetchAccessToken();
            const url = `${api.ticket}&access_Token=${data.access_token}`;
            rp({
                    method: 'get',
                    url,
                    json: true
                })
                .then(res => {
                    resolve({
                        ticket: res.ticket,
                        expires_in: Date.now() + (res.expires_in - 300) * 1000
                    })
                    // { access_token:
                    //     '20_ZCrQnrFmz20x21BwfYy9b2fvJvqQPvQZ5NQMeiy5LZwRfKXgtgArpNFl-WnGDT0QvvTI94CjJ459Fy8IfFn4g00tskZ_Z76xgEDe8fXYnGXd9PwkZhQJ0_mN8FE_sVPVPz1x7OFy0RRPbyfMVXGaAJAIKT',
                    //    expires_in: 7200 }
                })
                .catch(err => {
                    console.log(err);
                    reject('getTicket errer')
                })
        })
    }
    saveTicket(ticket) {
        //将对象转化成json字符串
        ticket = JSON.stringify(ticket);

        return new Promise((resolve, reject) => {
            writeFile('./ticket.txt', ticket, err => {
                if (!err) {
                    console.log("file write success");
                    resolve();
                } else {
                    console.log(err);
                    reject('saveTicket 方法出错');
                }
            })
        })
    }
    // 读取ticket
    readTicket() {
        return new Promise((resolve, reject) => {
            readFile('./ticket.txt', (err, data) => {
                if (!err) {
                    console.log("file read success");
                    data = JSON.parse(data)
                    resolve(data);
                } else {
                    // console.log(err);
                    reject(err);
                }
            })
        })
    }
    // 是否有效
    isValidTicket(data) {
        if (!data && data.access_token && !data.expires_in) {
            return false;
        }
        return data.expires_in > data.now()
    }
    // 获取没有过期的ticket
    /**
     * @param
     */
    fetchTicket() {
        console.log(this.access_token)
        if (this.access_token && this.ticket_expires_in && this.isValidTicket(this)) {
            // 保存过Ticket
            return Promise.resolve({
                access_token: this.access_token,
                expires_in: this.expires_in,
            })
        }
        return this.readTicket()
            .then(async res => {
                // 本地有文件
                if (this.isValidTicket(res)) {
                    resolve(res)
                } else {
                    // 过期
                    const res = await this.getTicket();
                    await this.saveTicket(res);
                    return Promise.resolve(res)
                }
            })
            .catch(async err => {
                const res = await this.getTicket();
                await this.saveTicket(res);
                return Promise.resolve(res)
            })
            .then(res => {
                this.access_token = res.access_token;
                this.ticket_expires_in = res.expires_in;
                return Promise.resolve(res);
            })
    }
 类似资料: