发布日期 » 2017年9月9日 星期六

版权声明 » 自媒体人·陈帅华原创内容,转载请注明出处

微信公众平台开发接收消息与事件及回复消息

当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。

我们不妨先尝试着将微信服务器转发自用户发送给公众号的消息XML内容打印出来看看先。

wechat.use('/', (req, res) => {
	var body = '';
	req.on('data', (d) => {
		body += d;
	});
	req.on('end', () => {
		console.log(body);
	});
});
点击阅读官方文档怎么说:接收普通消息-微信开发者文档

这里介绍一个能将XML格式字符串解析为JSON对象的模块:xml2js

帅华君直接将源代码贴出来,方便大家学习交流。

const dealTextMessage = (msgType, toUserName, fromUserName, msgId, createTime, content, cb) => {
	var timestamp = (new Date())
		.getTime();
	var responseContent = '文字';
	var result = `<xml>
				<ToUserName><![CDATA[${fromUserName}]]></ToUserName>
				<FromUserName><![CDATA[${toUserName}]]></FromUserName>
				<CreateTime>${timestamp}</CreateTime>
				<MsgType><![CDATA[text]]></MsgType>
				<Content><![CDATA[${responseContent}]]></Content>
				</xml>`;
	cb(result);
}
const dealImageMessage = (msgType, toUserName, fromUserName, msgId, createTime, picUrl, mediaId, cb) => {
	var timestamp = (new Date())
		.getTime();
	var responseContent = '图片';
	var result = `<xml>
				<ToUserName><![CDATA[${fromUserName}]]></ToUserName>
				<FromUserName><![CDATA[${toUserName}]]></FromUserName>
				<CreateTime>${timestamp}</CreateTime>
				<MsgType><![CDATA[text]]></MsgType>
				<Content><![CDATA[${responseContent}]]></Content>
				</xml>`;
	cb(result);
}
const dealVoiceMessage = (msgType, toUserName, fromUserName, msgId, createTime, mediaId, format, recognition, cb) => {
	var timestamp = (new Date())
		.getTime();
	var responseContent = '声音 > ' + recognition;
	var result = `<xml>
				<ToUserName><![CDATA[${fromUserName}]]></ToUserName>
				<FromUserName><![CDATA[${toUserName}]]></FromUserName>
				<CreateTime>${timestamp}</CreateTime>
				<MsgType><![CDATA[text]]></MsgType>
				<Content><![CDATA[${responseContent}]]></Content>
				</xml>`;
	cb(result);
}
const dealVideoMessage = (msgType, toUserName, fromUserName, msgId, createTime, mediaId, thumbMediaId, cb) => {
	var timestamp = (new Date())
		.getTime();
	var responseContent = '视频';
	var result = `<xml>
				<ToUserName><![CDATA[${fromUserName}]]></ToUserName>
				<FromUserName><![CDATA[${toUserName}]]></FromUserName>
				<CreateTime>${timestamp}</CreateTime>
				<MsgType><![CDATA[text]]></MsgType>
				<Content><![CDATA[${responseContent}]]></Content>
				</xml>`;
	cb(result);
}
const dealShortVideoMessage = (msgType, toUserName, fromUserName, msgId, createTime, mediaId, thumbMediaId, cb) => {
	var timestamp = (new Date())
		.getTime();
	var responseContent = '短视频';
	var result = `<xml>
				<ToUserName><![CDATA[${fromUserName}]]></ToUserName>
				<FromUserName><![CDATA[${toUserName}]]></FromUserName>
				<CreateTime>${timestamp}</CreateTime>
				<MsgType><![CDATA[text]]></MsgType>
				<Content><![CDATA[${responseContent}]]></Content>
				</xml>`;
	cb(result);
}
const dealLocationMessage = (msgType, toUserName, fromUserName, msgId, createTime, location_X, location_Y, scale, label, cb) => {
	var timestamp = (new Date())
		.getTime();
	var responseContent = '位置';
	var result = `<xml>
				<ToUserName><![CDATA[${fromUserName}]]></ToUserName>
				<FromUserName><![CDATA[${toUserName}]]></FromUserName>
				<CreateTime>${timestamp}</CreateTime>
				<MsgType><![CDATA[text]]></MsgType>
				<Content><![CDATA[${responseContent}]]></Content>
				</xml>`;
	cb(result);
}
const dealLinkMessage = (msgType, toUserName, fromUserName, msgId, createTime, title, description, url, cb) => {
	var timestamp = (new Date())
		.getTime();
	var responseContent = '链接';
	var result = `<xml>
				<ToUserName><![CDATA[${fromUserName}]]></ToUserName>
				<FromUserName><![CDATA[${toUserName}]]></FromUserName>
				<CreateTime>${timestamp}</CreateTime>
				<MsgType><![CDATA[text]]></MsgType>
				<Content><![CDATA[${responseContent}]]></Content>
				</xml>`;
	cb(result);
}
const dealSubscribeMessage = (msgType, toUserName, fromUserName, createTime, eventKey, cb) => {
	var timestamp = (new Date())
		.getTime();
	var responseContent = '你好哇~';
	var result = `<xml>
				<ToUserName><![CDATA[${fromUserName}]]></ToUserName>
				<FromUserName><![CDATA[${toUserName}]]></FromUserName>
				<CreateTime>${timestamp}</CreateTime>
				<MsgType><![CDATA[text]]></MsgType>
				<Content><![CDATA[${responseContent}]]></Content>
				</xml>`;
	cb(result);
}
const dealUnsubscribeMessage = (msgType, toUserName, fromUserName, createTime, eventKey, cb) => {
	var timestamp = (new Date())
		.getTime();
	var responseContent = '取消关注';
	var result = `<xml>
				<ToUserName><![CDATA[${fromUserName}]]></ToUserName>
				<FromUserName><![CDATA[${toUserName}]]></FromUserName>
				<CreateTime>${timestamp}</CreateTime>
				<MsgType><![CDATA[text]]></MsgType>
				<Content><![CDATA[${responseContent}]]></Content>
				</xml>`;
	cb(result);
}
const dealReceiveMessage = (xmlString, cb) => {
	const result = xmlString['xml'];
	// console.log(result);

	var msgType = result.MsgType[0];
	var toUserName = result.ToUserName[0];
	var fromUserName = result.FromUserName[0];
	var createTime = result.CreateTime[0];
	var msgId = result.MsgId && result.MsgId[0];

	switch (msgType) {
		case 'text':
			var content = result.Content[0];
			dealTextMessage(msgType, toUserName, fromUserName, msgId, createTime, content, cb);
			break;
		case 'image':
			var picUrl = result.PicUrl[0];
			var mediaId = result.MediaId[0];
			dealImageMessage(msgType, toUserName, fromUserName, msgId, createTime, picUrl, mediaId, cb);
			break;
		case 'voice':
			var mediaId = result.MediaId[0];
			var format = result.Format[0];
			var recognition = result.Recognition[0];
			dealVoiceMessage(msgType, toUserName, fromUserName, msgId, createTime, mediaId, format, recognition, cb);
			break;
		case 'video':
			var mediaId = result.MediaId[0];
			var thumbMediaId = result.ThumbMediaId[0];
			dealVideoMessage(msgType, toUserName, fromUserName, msgId, createTime, mediaId, thumbMediaId, cb);
			break;
		case 'shortvideo':
			var mediaId = result.MediaId[0];
			var thumbMediaId = result.ThumbMediaId[0];
			dealShortVideoMessage(msgType, toUserName, fromUserName, msgId, createTime, mediaId, thumbMediaId, cb);
			break;
		case 'location':
			var location_X = result.Location_X[0];
			var location_Y = result.Location_Y[0];
			var scale = result.Scale[0];
			var label = result.Label[0];
			dealLocationMessage(msgType, toUserName, fromUserName, msgId, createTime, location_X, location_Y, scale, label, cb);
			break;
		case 'link':
			var title = result.Title[0];
			var description = result.Description[0];
			var url = result.Url[0];
			dealLinkMessage(msgType, toUserName, fromUserName, msgId, createTime, title, description, url, cb);
			break;
		case 'event':
			var event = result.Event[0];
			switch (event) {
				case 'subscribe':
					var eventKey = result.EventKey[0];
					dealSubscribeMessage(msgType, toUserName, fromUserName, createTime, eventKey, cb);
					break;
				case 'unsubscribe':
					var eventKey = result.EventKey[0];
					dealUnsubscribeMessage(msgType, toUserName, fromUserName, createTime, eventKey, cb);
					break;
				case 'unsubscribe':
					var eventKey = result.EventKey[0];
					dealUnsubscribeMessage(msgType, toUserName, fromUserName, createTime, eventKey, cb);
					break;
			}
			break;
	}
}

const wechat = express.Router();
wechat.use((req, res, next) => {
	tools.checkWechatServer(req.ip, (state) => {
		if (!state) {
			res.send('吼!帅华表示然并卵!!');
			console.log('吼!帅华表示然并卵!!');
			return;
		}
		next();
	});
});
wechat.use('/', (req, res) => {
	var body = '';
	req.on('data', (d) => {
		body += d;
	});
	req.on('end', () => {
		var parseString = xml.parseString;
		parseString(body, function(err, result) {
			dealReceiveMessage(result, (responseXML) => {
				res.send(responseXML);
			});
		});
	});
});