老师你好,我感觉我每部都做对了,但是图片在微信客户端就是接受不到。 现在我图文,一般的消息都能成功回复出去,就是5的图不行。输出结果如下图
upload url:https://api.weixin.qq.com/cgi-bin/media/upload?access_token=BOYIN9M57YLPbIgQEwM8M1tvnYfAvlxAVtHlJS-SAvrRoZ0q9TI35GBBA423G_rljKOgWf_64o7mAKSQQDOK_CTcXwzdd4UYZnweDcpC9S8eX0Yc8SQlnk11Zj9inRcCTFWcACAXJA&type=image upload success:{"statusCode":200,"body":{"type":"image","media_id":"KMCavjDjR2piKM8Hk7QSXkKPLUttNdy1Vk5Dt5rk6u7gk2sWuy61rpHT_bB8mzRH","created_at":1476290700},"headers":{"connection":"close","content-type":"text/plain","date":"Wed, 12 Oct 2016 16:45:00 GMT","content-length":"118"},"request":{"uri":{"protocol":"https:","slashes":true,"auth":null,"host":"api.weixin.qq.com","port":443,"hostname":"api.weixin.qq.com","hash":null,"search":"?access_token=BOYIN9M57YLPbIgQEwM8M1tvnYfAvlxAVtHlJS-SAvrRoZ0q9TI35GBBA423G_rljKOgWf_64o7mAKSQQDOK_CTcXwzdd4UYZnweDcpC9S8eX0Yc8SQlnk11Zj9inRcCTFWcACAXJA&type=image","query":"access_token=BOYIN9M57YLPbIgQEwM8M1tvnYfAvlxAVtHlJS-SAvrRoZ0q9TI35GBBA423G_rljKOgWf_64o7mAKSQQDOK_CTcXwzdd4UYZnweDcpC9S8eX0Yc8SQlnk11Zj9inRcCTFWcACAXJA&type=image","pathname":"/cgi-bin/media/upload","path":"/cgi-bin/media/upload?access_token=BOYIN9M57YLPbIgQEwM8M1tvnYfAvlxAVtHlJS-SAvrRoZ0q9TI35GBBA423G_rljKOgWf_64o7mAKSQQDOK_CTcXwzdd4UYZnweDcpC9S8eX0Yc8SQlnk11Zj9inRcCTFWcACAXJA&type=image","href":"https://api.weixin.qq.com/cgi-bin/media/upload?access_token=BOYIN9M57YLPbIgQEwM8M1tvnYfAvlxAVtHlJS-SAvrRoZ0q9TI35GBBA423G_rljKOgWf_64o7mAKSQQDOK_CTcXwzdd4UYZnweDcpC9S8eX0Yc8SQlnk11Zj9inRcCTFWcACAXJA&type=image"},"method":"Post","headers":{"accept":"application/json","content-type":"multipart/form-data; boundary=--------------------------178037158051642397238963","content-length":443239}}} here? reply content:<xml> <ToUserName><![CDATA[oxk0wvwjhJ-UhGr2CGND-VYrgIt0]]></ToUserName> <FromUserName><![CDATA[gh_0628f885df72]]></FromUserName> <CreateTime>1476290700742</CreateTime> <MsgType><![CDATA[image]]></MsgType> <Image> <MediaId><![CDATA[KMCavjDjR2piKM8Hk7QSXkKPLUttNdy1Vk5Dt5rk6u7gk2sWuy61rpHT_bB8mzRH]]></MediaId> </Image> </xml>
基于以上您可以看到,我上传是图片是成功的,返回的body中也包含了和上传一样的mediaid,并且返回的数据也和微信接口要求的一样。
这边还请您给予指导
下面是wechat.js
'use strict' var Promise = require('bluebird'); var request = Promise.promisify(require('request')); var util = require('../lib/util'); var fs = require('fs'); var prefix = 'https://api.weixin.qq.com/cgi-bin/'; var grant_type = 'client_credential'; //grant_type=client_credential&appid=APPID&secret=APPSECRET function Wechat(opts){ var that = this; this.appID = opts.appID; this.appsecret = opts.appsecret; this.getAccessToken = opts.getAccessToken; this.saveAccessToken = opts.saveAccessToken; //初始化的过程中就去把token拿到 this.fetchAccessToken() } //取得Access token Wechat.prototype.fetchAccessToken = function (data){ var that = this; //console.log('fetch this:'+that) //先检查有没有合法的token,如果有的话直接返回 if (this.access_token && this.expires_in){ if (this.validateAccessToken(this)){ return Promise.resolve(this.access_token) } } // if(this.validateAccessToken(that)){ // console.log('valid') // return Promise.resolve(that.access_token); // } //console.log('should valid') //get 方法是去读写在本地的token,如果本地的不好使了,那么调用update方法去微信服务器交换 return that.getAccessToken() .then(function(data){ try{ data = JSON.parse(data); } catch(e){ return that.updateAccessToken(); } if(that.validateAccessToken(data)){ console.log('data:2'+some) return Promise.resolve(data); } else{ //var some = JSON.stringify(data); //console.log('data:2'+some) return that.updateAccessToken(); } }).then( function(data){ that.access_token = data.access_token; that.expires_in = data.expires_in; that.saveAccessToken(data); //返回token return Promise.resolve(data.access_token); }) } Wechat.prototype.validateAccessToken = function (data){ var some = JSON.stringify(data); console.log("some"+some); if(!data || !data.access_token || data.expires_in){ return false } console.log("what"); var access_token = data.access_token; var expires_in = data.expires_in; var curTime = (new Date().getTime()); //console.log("time"+curTime); //1476293619539 if(curTime < expires_in){ return true; }else{ return false; } } //上传材料 Wechat.prototype.uploadMaterial = function (type,filePath){ var that = this //console.log('this1:'+this) console.log('readfile path:'+filePath) var formData = { media: fs.createReadStream(filePath) } return new Promise(function (resolve, reject){ //console.log('this2:'+this) that .fetchAccessToken() .then(function(data){ //console.log('that:'+data) var method = 'upload'; var access_token = data; var type = type; var url = prefix+'media/'+method+'?'+'access_token='+access_token+'&type='+'image'; console.log('upload url:'+url); request({method: 'Post',url: url,formData: formData,json: true }) .then( function(response){ //response contains full response of request //console.log(response); //console.log('request success:'+response.created_at); var uploadc = JSON.stringify(response) console.log('upload success:'+uploadc); var _data = response; //console.log(data); if(_data){ resolve(_data); }else{ throw new Error('upload uploadMaterial failed') } }) .catch(function(err){ reject(err); }) }) }) } Wechat.prototype.updateAccessToken = function (){ //console.log('upade') var url = prefix+'token?'+'grant_type='+grant_type+'&appid='+this.appID+'&secret='+this.appsecret; return new Promise(function (resolve, reject){ request({url:url, json: true }).then( function(response){ //response contains full response of request //console.log(response); var data = response; var result = { access_token:'', expires_in:'', } //console.log(data); var curTime = (new Date().getTime()); var expires_in = curTime + (data.body.expires_in - 20) * 1000; result.expires_in = expires_in; result.access_token = data.body.access_token; resolve(result); }) }) } Wechat.prototype.reply = function (){ var content = this.body; var message = this.weixinData; //提取模板处理数据 var xml = util.tplM(content, message); console.log('reply content:'+xml); this.status = 200 this.type ='application/xml' this.body = xml } module.exports = Wechat;
我reply里面打印出来了输出消息包,正如你在shell输出里面看到的,消息没问题。
下面是回复的js
'use strict' //实现微信的依据状况的 -- 消息路由 var config = require('../config/config') var Wechat = require('../wechat/wechat') var wechatApi = new Wechat(config.wechat); var path = require('path') exports.reply = function *(next){ var message = this.weixinData; //console.log('message:'+message.Event); //console.log('message event EventKey:'+message.EventKey); if(message.MsgType ==='event'){ if(message.Event ==='subscribe'){ if(message.EventKey){ console.log('扫描二维码而来:'+message.Eventkey+''+message.ticket) } this.body = '宝贝你好,请输入:1,2,3,4其中之一 '; }else if(message.Event ==='unsubscribe'){ console.log('撒有哪啦'); this.body ='无情取消关注' }else if(message.Event ==='LOCATION'){ this.body = '你的位置是:'+ message.Latitude+'/'+message.Longtitude+'-'+message.EventKey; }else if(message.Event ==='CLICK'){ this.body = '您点击了菜单:'+message.EventKey; }else if(message.Event ==='SCAN'){ this.body = '谢谢扫描'; } }else if (message.MsgType === 'text') { var content = message.Content; var reply = '你说的太复杂了:'+message.Content; if(content ==='1'){ reply ='陆总你好' }else if(content == '2'){ reply = '陆总你好2' }else if(content == '3'){ reply = '陆总我睡了' } else if(content == '4'){ reply = [{ title:'电音之王', description:'欢迎来到电音之王的世界', picUrl:'http://img.xiami.net/images/collect/772/72/42220772_1425550553_vLXZ.jpg', url:'www.baidu.com' },{ title:'你好陆总', description:'欢迎来到电音之王的世界哈哈', picUrl:'http://img.xiami.net/images/collect/772/72/42220772_1425550553_vLXZ.jpg', url:'www.baidu.com' }] } else if(content == '5'){ //console.log('5+0') var newpath = path.join(__dirname,'../config/aimage.jpg') var uploadImage = yield wechatApi.uploadMaterial('image',newpath) //console.log('5+1') //console.log("id:"+show); reply = { type: 'image', mediaId: uploadImage.body.media_id } } this.body = reply } //console.log('A') yield next // console.log('B') }
再下面是g.js
'use strict' var sha1 = require('sha1'); var Promise = require('bluebird'); //var request = Promise.promisify(require('request')); var Wechat = require('./wechat'); var getRawBody = require('raw-body'); var util = require('../lib/util'); module.exports = function(opts, handler){ //实例化一个和wechat交互的对象 var wechat = new Wechat(opts); return function *(next){//这个地方怎么用的还需要继续学习 var token = opts.token; var signature = this.query.signature; var nonce = this.query.nonce; var timestamp = this.query.timestamp; var echostr = this.query.echostr; var str = [token,timestamp,nonce].sort().join('') var sha = sha1(str) //判断是否验证成功 if(sha === signature){ if(this.method === 'GET'){ this.body = echostr +''; //console.log('this is a get method'); }else if(this.method === 'POST'){ var data = yield getRawBody(this.req, { length: this.length, limit: '1mb', encoding:this.charset }) data = yield util.parseXMLAsync(data); // console.log(data); //console.log('data.xml:'+data.xml) // console.log('G') data = yield util.formatMessage(data.xml); //console.log(data); this.weixinData = data; //用外面传进来的weixinhandler处理具体的回复内容 //这个地方传入 next的目的? //console.log('D') yield handler.reply.call(this, next); wechat.reply.call(this); //解析请求,回复完毕后,处理回复的路由 } }else{ this.body = 'wrong'; } } }