首页 > 上网技巧 > 电脑小技巧 > 微信公众号签名接口 微信公众号消息管理接口

微信公众号签名接口 微信公众号消息管理接口

时间:2019-05-18 10:09 作者:QQ地带 我要评论

 a一、准备工作

 
1.在微信公众平台申请测试账号,并设置好好 JS 接口安全域名
 
2.验证服务器信息
 
1531734590_1_ 微信截图_20180716122946
 
router.use("/wx", (req, res) => {
  let { signature, timestamp, nonce, echostr } = url.parse(req.url, true).query;
  //将Token,timestamp,nonce按字典排序,排序后链接成一个字符串
  let str = [TOKEN, timestamp, nonce].sort().join("");
  //使用sha1模块进行sha1?#29992;?/div>
  let jsSHA = require('jssha');
  let shaObj = new jsSHA(str, 'TEXT');
  let sha1Str = shaObj.getHash('SHA-1', 'HEX');
  if (sha1Str === signature) {
    //将echostr返回给微信服务器
    res.send(echostr)
  }
  else {
    res.send("wrong")
  }
})
二、微信的签名算法
 
使用微信 sdk 必须自己实现微信的签名算法,大概需要4个步骤:
 
1.获取 access_token;
 
function getAccessToken() {
  return request(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}`)
    .then(function (body) {
      accessToken = JSON.parse(body).access_token;
    })
2.根据 access_token 获取 jsapi_ticket
 
function getAccessToken() {
  return request(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${APPSECRET}`)
    .then(function (body) {
      accessToken = JSON.parse(body).access_token;
      return request(`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${accessToken}&type=jsapi`);
    })
    .then(function (body) {
      jsapiTicket = JSON.parse(body).ticket;
    });
}
3.根据 appId(公众号唯一id)、noncestr(随机字符串)、timestamp(时间戳)、url(当前页面完整url,不包括#aaa=bbb) 通过sha1算法签名
 
let createNonceStr = function () {
    return Math.random().toString(36).substr(2, 15);
};
let createTimestamp = function () {
    return parseInt(new Date().getTime() / 1000) + '';
};
//对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1 = value1 & key2=value2…)拼接成字符串string
let raw = function (args) {
    let keys = Object.keys(args);
    keys = keys.sort()
    let string = '';
    keys.forEach(k => {
        string += '&' + k + '=' + args[k];
    })
    string = string.substr(1);
    return string;
};
//生成签名
const sign = function (jsapi_ticket, url) {
    let ret = {
        jsapi_ticket: jsapi_ticket,
        noncestr: createNonceStr(),
        timestamp: createTimestamp(),
        url: url
    };
    const string = raw(ret);
    const jsSHA = require('jssha');
    const shaObj = new jsSHA(string, 'TEXT');
    ret.signature = shaObj.getHash('SHA-1', 'HEX');
    return ret;
};
4.将信息返回给前端 , 设置wx.config。
 
由于获取access_token 和 jsapi_ticket的接口?#21152;?#35775;问限制,所以明确指出需要第三方做缓存处理。
 
//增加定时任务,刷新accessToken和jsapiTicket
setInterval(function () {
  getAccessToken();
}, 7200000);
三、消息管理     当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应。     消息推送也是微信公众号开发更为有趣的功能,涉及到文本消息、图片消息、语音消息、视频消息、音乐消息以及图文消息。      1.捕获消息信息     微信消息产生的请求方式为 POST,然后监听这个接口,得到的数据是xml的数据,解析XML,这里使用了 第三方的包 xml2js(npm install xml2js ):
 
let xml = '' //存储将要回复给公众号的文字
    //接收post内容
    req.on('data', chunk => {
      xml += chunk
    })
    //接收结束
    req.on('end', () => {
      //将接受到的xml数据转化为json
      if (xml) {
        xml2js.parseString(xml, { explicitArray: false }, function (err, json) {
          let backTime = parseInt(new Date().valueOf() / 1000) //创建发送时间,整数
          console.log(json)
        })
      }
    })
2.根据得到的消息类型(MsgType),可以进行不同的回复
 
//event表示事件,
  if (json.xml.MsgType == 'event') {
    // EventKey是在自定义菜单的时候定义的事件名称
    if (json.xml.EventKey == 'clickEvent') {
      res.send(msg.getTextXml(json, backTime, '你戳我干啥...'))
    }
    //text表示文字信息
  } else if (json.xml.MsgType == 'text') {
    //回复公众号的文字信息
    if (json.xml.Content == 1) {
      var contentArr = [{
        Title: "Node.js 微信自定义菜单",
        Description: "使用Node.js实现自定义微信菜单",
        PicUrl: "http://www.fpfh5.site/images/recording/record.png",
        Url: "http://www.baidu.com"
      }]
      res.send(msg.graphicMsg(json, backTime, contentArr))
    } else {
      res.send(msg.getTextXml(json, backTime, `你发"${json.xml.Content}"过来干啥?`))
    }
  } else if (json.xml.MsgType == 'image') {
    //回复公众号的图片信息
    res.send(msg.getImageXml(json, backTime))
  } else if (json.xml.MsgType == 'voice') {
    //回复公众号的语音信息
    res.send(msg.getVoiceXml(json, backTime))
  }
其中ToUserName是接受者的openid,FromUserName是发送者的openid,CreateTime就是一个整?#20599;?#26102;间戳。MsgType就是消息类型,一般有文本(text),图片(image),语音(voice),视频(video),小视频(shortvideo),地理位置(location)以及链接消息(link)。
 
3.消息模板,消息接口收到消息时,与回复消息时,ToUserName和FromUserName的位置互换。     
 
//回复图文消息
exports.graphicMsg = function (json, backTime, contentArr) {
    let content = contentArr.map(item => `<item>
        <Title><![CDATA[${item.Title}]]></Title>
        <Description><![CDATA[${item.Description}]]></Description>
        <PicUrl><![CDATA[${item.PicUrl}]]></PicUrl>
        <Url><![CDATA[${item.Url}]]></Url>
    </item>`)
    content = content.join('')
    let backXML = `<xml>
    <ToUserName><![CDATA[${json.xml.FromUserName}]]></ToUserName>
    <FromUserName><![CDATA[${json.xml.ToUserName}]]></FromUserName>
    <CreateTime>${backTime}</CreateTime>
    <MsgType><![CDATA[news]]></MsgType>
    <ArticleCount>${contentArr.length}</ArticleCount>
    <Articles>${content}</Articles>
  </xml>`
    return backXML;
}
//回复文本消息
exports.getTextXml = function(json, backTime, word) {
    let backXML = `<xml>
    <ToUserName><![CDATA[${json.xml.FromUserName}]]></ToUserName>
    <FromUserName><![CDATA[${json.xml.ToUserName}]]></FromUserName>
    <CreateTime>${backTime}</CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[${word}]]></Content>
  </xml>`
    return backXML;
};
//回复图片消息
exports.getImageXml = function(json, backTime) {
    let backXML = `<xml>
    <ToUserName><![CDATA[${json.xml.FromUserName}]]></ToUserName>
    <FromUserName><![CDATA[${json.xml.ToUserName}]]></FromUserName>
    <CreateTime>${backTime}</CreateTime>
    <MsgType><![CDATA[image]]></MsgType>
    <Image><MediaId><![CDATA[${json.xml.MediaId}]]></MediaId></Image>
  </xml>`
    return backXML;
};
// /回复语音消息
exports.getVoiceXml = function(json, backTime) {
    let backXML = `<xml>
    <ToUserName><![CDATA[${json.xml.FromUserName}]]></ToUserName>
    <FromUserName><![CDATA[${json.xml.ToUserName}]]></FromUserName>
    <CreateTime>${backTime}</CreateTime>
    <MsgType><![CDATA[voice]]></MsgType>
    <Voice><MediaId><![CDATA[${json.xml.MediaId}]]></MediaId></Voice>
  </xml>`
    return backXML;
};
4.客服回复消息
 
request({
    method: 'POST',
    uri: `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${accessToken}`,
    json: true,
    body:{
      "touser": json.xml.FromUserName,
      "msgtype": "text",
      "text": {
        "content": "Hello World"
      }
    }
})

标签: 微信公众号
顶一下
(0)
0%
踩一下
(0)
0%

Google提供的广告

天天炫斗2019更新公告
重启时时彩龙虎走势图 一起来捉妖最强宠物 白狮客服 中国彩票销售额 骰宝返水 2018以太坊价格走势 大航海时代登陆 莱加内斯VS莱万特 萨索洛3:5桑普多利亚 76人有多少个总冠军