前提条件你得有一台自己的服务器,然后要域名备案完成并且做好域名映射
如果中间有看不懂的可以配合这个大佬的文章一起看,我这里的实际代码是他的代码的简化
我用的是axios,express,和大佬用的库有所区别,看个人技术栈
先来讲解一下前端要写什么
然后是这样子的效果,只用在意获取vr链接那部分的代码
session-from="{{vr_url}}"是我们发给服务器的消息,按自己需求来定
没错前端就是那么少事情,主要的后端
首先去微信小程序后台,把自己的appid,密钥,公钥拿下来后面用,然后配置好自己的服务器域名
之后找到消息推送,点击配置,url选择你的get服务的地址,比如说我的是app.get('/wxCallbackAction')那就写https://域名/wxCallbackAction
先别急着发送,回到我们的服务器后台
这段代码的token改成你自己的,然后就可以点击发送认证了
app.get('/wxCallbackAction', (req:any, res:any) => {
const { signature, timestamp, nonce, echostr } = req.query;
// 1. 将token、timestamp、nonce三个参数进行字典序排序
const token = "djdc"; // 替换为你的Token
let array = [token, timestamp, nonce];
array.sort();
// 2. 将三个参数字符串拼接成一个字符串进行sha1加密
const tempStr = array.join('');
const hashCode = crypto.createHash('sha1');
const resultCode = hashCode.update(tempStr, 'utf8').digest('hex');
// 3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
if (resultCode === signature) {
console.log('验证成功,消息是从微信服务器转发过来');
res.send(echostr);
} else {
console.log('验证失败!!!');
res.status(400).json({
status: -1,
message: "验证失败"
});
}
});
验证成功之后会是这样的
然后我们就可以收到微信小程序发来的消息了
以下代码没有定义的变量改成你自己的也就是密钥,appid那些
app.post('/wxCallbackAction', async (req:any, res:any) => {
const { Encrypt } = req.body;
if (!Encrypt) {
return res.json({ status: 'success' });
}
//收到消息后要解码,解码的代码放到后面了
const decryptData = WXDecryptContact(Encrypt);
//这里没问题后自己打印出来看一下
console.log(decryptData)
//获取access_token
let url='https://api.weixin.qq.com/cgi-bin/token?'+'grant_type=client_credential&appid='+appid+'&secret='+appsecret
const response=await axios.get(url)
let access_token=response.data.access_token
//下面这一部分是存放临时资源,这里主要讲一下FormData下载这个包下来用const FormData = require('form-data');
//也就是npm install form-data
let resurl='https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='+access_token
const logoPath = path.join(__dirname, 'image', 'logo.jpg');
const mediaurl='https://api.weixin.qq.com/cgi-bin/media/upload?access_token='+access_token+'&type=image'
const file=fs.createReadStream(logoPath);
let formdata=new FormData();
formdata.append('media',file,{filename:'logo.jpg'})
const mediares=await axios.post(mediaurl,formdata)
let mediaid=mediares.data.media_id
//发送消息回去给微信小程序,做成自动客服
if(decryptData.MsgType=='event'||decryptData.MsgType=='text')
{
let return_content=JSON.parse(decryptData.SessionFrom).vr_url
let res2=axios.post(resurl,
{
access_token: access_token,
touser: decryptData.FromUserName,
msgtype:'link',
//这是发送文本的内容回去
// text: {content: return_content},
//这是发送链接回去
link:{title:'如视vr接口',url:return_content,description:'点击看vr',thumb_url:'https://api.weixin.qq.com/cgi-bin/media/get?access_token='+access_token+'&media_id='+mediaid}
});
}
return res.json({ status: 'success' });
});
解码的代码
const crypto = require('crypto'); // 加密模块
const decodePKCS7 = function (buff:any) {
let pad = buff[buff.length - 1];
if (pad < 1 || pad > 32) {
pad = 0;
}
return buff.slice(0, buff.length - pad);
};
// 微信转发客服消息解密
const decryptContact = (key:any, iv:any, crypted:any) => {
const aesCipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
aesCipher.setAutoPadding(false);
let decipheredBuff = Buffer.concat([aesCipher.update(crypted, 'base64'), aesCipher.final()]);
decipheredBuff = decodePKCS7(decipheredBuff);
const lenNetOrderCorpid = decipheredBuff.slice(16);
const msgLen = lenNetOrderCorpid.slice(0, 4).readUInt32BE(0);
const result = lenNetOrderCorpid.slice(4, msgLen + 4).toString();
return result;
};
// 解密微信返回给配置的消息服务器的信息
const decryptWXContact = (wechatData:any) => {
if(!wechatData){
wechatData = '';
}
//EncodingAESKey 为后台配置时随机生成的,改成你在消息推送里面的EncodingAESKey
const key = Buffer.from(EncodingAESKey + '=', 'base64');
const iv = key.slice(0, 16);
const result = decryptContact(key, iv, wechatData);
const decryptedResult = JSON.parse(result);
console.log(decryptedResult);
return decryptedResult;
};
module.exports = decryptWXContact;
评论已关闭