微信公众号开发
需求:在web端用户实时操作的内容,在微信公众号获取到
实现:项目与微信公众号的连接,在微信公众号上回复,发送对应的文本,图片,视频内容
一、微信公众号的接入(三个部分)
1.node 服务器;
2.将本地的 node 服务暴露到外网;
3.微信公众号信息验证
进入微信公众号的开发文档,选择开始开发,接口测试号申请。
当我们点提交的时候,微信服务器会给我们填写的 URL 地址发送一个 get 请求,并传回一些特定的字段。就是下图这些参数,我们需要把这些参数跟微信服务去验证。
设置完之后,可以诊断一下是否成功。
app.get('/wx/token', (req, res, next) => {
wechat.auth(req, res, next);
})
app.post('/wx/token', (req, res, next) => {
wechat.autoMsg(req, res, next);
})
这里引入了一个新的模块 sha1,主要是对结果进行加密的。我们再到微信测试号配置设置就可以成功保存了,验证成功可以开始正式的开发了。
function WeChat(config) {
// 传入配置文件
this.config = config;
this.token = config.token;
this.appID = config.appID;
this.appsecret = config.appsecret;
this.prefix = config.prefix;
this.diyApi = config.diyApi;
this.weather = config.weather;
}
// 微信授权验证方法
WeChat.prototype.auth = function (req, res, next) {
//更新access_token
let that = this;
this.getAccessToken().then(function (data) {
let url = util.format(that.diyApi.createMenu, that.prefix, data);
console.log(url);
that.requestPost(url, JSON.stringify(menu)).then(function (data) {
console.log(data);
});
});
let signature = req.query.signature;
let echostr = req.query.echostr;
let timestamp = req.query.timestamp;
let nonce = req.query.nonce;
let reqArray = [nonce, timestamp, this.token];
reqArray.sort(); //对数组进行字典排序
let sortStr = reqArray.join('');
let sha1Str = sha1(sortStr.toString().replace(/,/g, ""));
if (signature === sha1Str) {
res.end(echostr);
console.log("授权成功!");
} else {
res.end("false");
console.log("授权失败!");
}
}
微信授权验证方法
二、临时素材、照片上传
对于与微信公众号,我们可能不仅仅只是发文本,我们还需要发语音,视频之类的各种素材。
从微信文档上可以看出,是 post 请求,然后传递文档流给微信服务器。
(1)先配置好 config 文件。
(2)然后给 WeChat 添加一个素材上传的方法。
// 新增临时素材上传
WeChat.prototype.uploaadVideo = function (urlPath, type) {
let that = this;
return new Promise(function (resolve, reject) {
that.getAccessToken().then(function (data) {
let form = { //构造表单
media: fs.createReadStream(urlPath)
}
let url = util.format(that.diyApi.uploadFile, that.prefix, data, type);
that.requestPost(url, form).then(function (result) {
console.log(result)
resolve(JSON.parse(result).media_id);
})
})
})
}
(3)然后给 WeChat 添加一个照片上传的方法。
// 照片上传
WeChat.prototype.uploadFile = function (urlPath, type) {
let that = this;
return new Promise(function (resolve, reject) {
that.getAccessToken().then(function (data) {
let form = { //构造表单
media: fs.createReadStream(urlPath)
}
let url = util.format(that.diyApi.uploadFile, that.prefix, data, type);
that.requestPost(url, form).then(function (result) {
console.log(result)
resolve(JSON.parse(result).media_id);
})
})
})
}
(4)被动回复信息。
// 回复文本消息
exports.textMsg = function(toUser,fromUser,content){
var xmlContent = "<xml><ToUserName><![CDATA["+ toUser +"]]></ToUserName>";
xmlContent += "<FromUserName><![CDATA["+ fromUser +"]]></FromUserName>";
xmlContent += "<CreateTime>"+ new Date().getTime() +"</CreateTime>";
xmlContent += "<MsgType><![CDATA[text]]></MsgType>";
xmlContent += "<Content><![CDATA["+ content +"]]></Content></xml>";
return xmlContent;
}
// 回复图文消息
exports.graphicMsg = function(toUser,fromUser,contentArr){
var xmlContent = "<xml><ToUserName><![CDATA["+ toUser +"]]></ToUserName>";
xmlContent += "<FromUserName><![CDATA["+ fromUser +"]]></FromUserName>";
xmlContent += "<CreateTime>"+ new Date().getTime() +"</CreateTime>";
xmlContent += "<MsgType><![CDATA[news]]></MsgType>";
xmlContent += "<ArticleCount>"+contentArr.length+"</ArticleCount>";
xmlContent += "<Articles>";
contentArr.map(function(item,index){
xmlContent += "<item>";
xmlContent += "<Title><![CDATA["+ item.Title +"]]></Title>";
xmlContent += "<Description><![CDATA["+ item.Description +"]]></Description>";
xmlContent += "<PicUrl><![CDATA["+ item.PicUrl +"]]></PicUrl>";
xmlContent += "<Url><![CDATA["+ item.Url +"]]></Url>";
xmlContent += "</item>";
});
xmlContent += "</Articles></xml>";
return xmlContent;
}
// 回复图片
exports.imgMsg = function(toUser, fromUser, media_id) {
var xmlContent = "<xml><ToUserName><![CDATA["+ toUser +"]]></ToUserName>";
xmlContent += "<FromUserName><![CDATA["+ fromUser +"]]></FromUserName>";
xmlContent += "<CreateTime>"+ new Date().getTime() +"</CreateTime>";
xmlContent += "<MsgType><![CDATA[image]]></MsgType>";
xmlContent += "<Image><MediaId><![CDATA["+ media_id +"]]></MediaId></Image></xml>";
return xmlContent;
}
// 回复音频
exports.videoMsg = function(toUser, fromUser, media_id, title, description) {
var xmlContent = "<xml><ToUserName><![CDATA["+ toUser +"]]></ToUserName>";
xmlContent += "<FromUserName><![CDATA["+ fromUser +"]]></FromUserName>";
xmlContent += "<CreateTime>"+ new Date().getTime() +"</CreateTime>";
xmlContent += "<MsgType><![CDATA[video]]></MsgType>";
xmlContent += "<Video><MediaId><![CDATA["+ media_id +"]]></MediaId>";
xmlContent += "<Title><![CDATA["+ title +"]]></Title>";
xmlContent += "<Description><![CDATA["+ description +"]]></Description></Video></xml>";
return xmlContent;
}
注:获取 access_token
至此上传素材完成。素材上传的过程中主要有一点需要注意一下,post 请求的时候,需要给微信服务发送一个流文件,发送成功之后,服务器会返回一个 media_id。
这个 mdedia_id 就是该素材的 id,后面如果我们需要对素材进行其他操作,都是这个 id。