上篇写到自己自动回复信息。其他的类型可以看开发文档,自己封装两种方法。一个是用户发给公众号的信息,另一个是公众号返回给客户。但一遍大多数,就是扫面关注之后,自动欢迎语句,或者输入数字,或者简短文字;公众号返回文本。
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是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。
临时票据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);
})
}