分享下 我的 开源项目 Wechat Message

最近做了几个微信公众号自动回复的小程序,时间紧促,代码写的非常混乱。

近期闲下来,把代码重构了,按这个模式就可以 以非常优雅的方式 处理微信消息。只需要 继承 消息类,重构类的方法(比如:onTextMessage),就可以处理 接收到的文本信息。根据用户回复,返回 textMessage 即可将文本信息发送给用户。

现在已经将 相关代码开源,访问 https://gitee.com/mqycn/WechatMessage 即可下载,简单的使用例子如下:

<?php class WechatMessageApp extends WechatMessageCommon { protected function onSubscribeEvent() { $msg = "你好,非常感谢您的订阅。\n\n"; return $this->textMessage($msg);
	}
	protected function onTextMessage($content) {
		return $this->textMessage("[自动回复]${content}");
	}
	protected function onImageMessage($image, $media_id) {
		return $this->imageMessage($media_id);
	}
}

消息类型和对应的方法

消息事件 需要重写的方法
用户订阅 onSubscribeEvent()
文字消息 onTextMessage($content)
图片消息 onImageMessage($image,$media_id)
语音消息 onVoiceMessage($media_id,$format,$to_text)
视频消息 onVideoMessage($media_id,$media_thumb_id)
分享消息 onLinkMessage($title,$desc,$url)
文件上传 onFileMessage($filename,$desc,$file_key,$file_md5,$file_size)
位置信息 onLocationMessage($address,$lat,$lng,$scale)
进入客服界面(小程序) onUserEnterTempsessionEvent()
回复类型 回复的方法
文字消息 textMessage($content)
图片消息 imageMessage($media_id)
语音消息 voiceMessage($media_id)
视频消息 videoMessage($media_id,$title = '',$desc = '')
分享消息 linkMessage($articles = array())

核心代码:

 

<?php

/**
 * 类名:WechatMessageCommon
 * 作者:mqycn
 * 博客:http://www.shiekolong1788.icu
 * 源码:https://gitee.com/mqycn/WechatMessage
 * 说明:微信消息处理核心类,使用时直接 继承此类,重写 on[事件] 即可,使用 $this->textMessage 可以输出回复
 */
abstract class WechatMessageCommon {

	protected $fromUsername;
	protected $toUsername;
	protected $msgId;
	protected $msgTime;

	/**
	 * 验证消息事件
	 */
	protected function onValid($request) {}

	/**
	 * 原始消息事件
	 */
	protected function onMessage($request) {}

	/**
	 * 回复事件
	 */
	protected function onSendMessage($body) {}

	/**
	 * 文字消息事件
	 */
	protected function onTextMessage($content) {
		return $this->onOtherMessage('文字消息', array($content));
	}

	/**
	 * 图片消息事件
	 */
	protected function onImageMessage($image, $media_id) {
		return $this->onOtherMessage('图片消息', array($image, $media_id));
	}

	/**
	 * 语音消息事件
	 */
	protected function onVoiceMessage($media_id, $format, $to_text) {
		return $this->onOtherMessage('语音消息', array($media_id, $format, $to_text));
	}

	/**
	 * 视频消息事件
	 */
	protected function onVideoMessage($media_id, $media_thumb_id) {
		return $this->onOtherMessage('视频消息', array($media_id, $media_thumb_id));
	}

	/**
	 * 分享事件
	 */
	protected function onLinkMessage($title, $desc, $url) {
		return $this->onOtherMessage('分享消息', array($title, $desc, $url));
	}

	/**
	 * 上传事件
	 */
	protected function onFileMessage($file_name, $desc, $file_key, $file_md5, $file_size) {
		return $this->onOtherMessage('文件上传', array($file_name, $desc, $file_key, $file_md5, $file_size));
	}

	/**
	 * 位置信息事件
	 */
	protected function onLocationMessage($address, $lat, $lng, $scale) {
		return $this->onOtherMessage('位置信息', array($address, $lat, $lng, $scale));
	}

	/**
	 * 其他消息事件
	 */
	protected function onOtherMessage($event_type, $argument = array()) {
		return $this->textMessage('暂时不支持的消息' . $event_type . ',参数(' . join($argument, ', ') . ')');
	}

	/**
	 * 订阅事件
	 */
	protected function onSubscribeEvent() {
		return $this->textMessage('您好,请问有什么可以帮助您?');
	}

	/**
	 * 客服事件
	 */
	protected function onUserEnterTempsessionEvent() {
		return $this->textMessage('您好,请问有什么可以帮助您?');
	}

	/**
	 * 其他消息事件
	 */
	protected function onOtherEvent($event_type, $argument = array()) {
		return $this->textMessage('暂时不支持的事件' . $event_type . ',参数(' . join($argument, ', ') . ')');
	}

	/**
	 * 处理一个请求
	 */
	public function auto() {
		if (!isset($HTTP_RAW_POST_DATA)) {
			$HTTP_RAW_POST_DATA = file_get_contents('php://input');
		}
		if (!empty($HTTP_RAW_POST_DATA)) {
			return $this->answer($HTTP_RAW_POST_DATA);
		} else {
			return $this->valid();
		}
	}

	/**
	 * 验证
	 */
	public function valid() {
		$this->onValid($_SERVER['QUERY_STRING']);
		return isset($_GET["echostr"]) ? $_GET["echostr"] : '';
	}

	/**
	 * 自动应答
	 */
	public function answer($post_raw = false) {
		if ($post_raw === false) {
			if (!isset($HTTP_RAW_POST_DATA)) {
				$HTTP_RAW_POST_DATA = file_get_contents('php://input');
			}
			$post_raw = $HTTP_RAW_POST_DATA;
		}
		$this->onMessage($post_raw);
		if (empty($post_raw)) {
			die("Error");
		} else {
			$message_request = simplexml_load_string($post_raw, 'SimpleXMLElement', LIBXML_NOCDATA);

			//提取公共参数
			$this->fromUsername = trim($message_request->FromUserName);
			$this->toUsername = trim($message_request->ToUserName);
			$this->msgId = (int) $message_request->MsgId;
			$this->msgTime = (int) $message_request->CreateTime;

			switch (trim($message_request->MsgType)) {
			case 'text':
				return $this->onTextMessage($message_request->Content);
				break;
			case 'image':
				return $this->onImageMessage($message_request->PicUrl, $message_request->MediaId);
				break;
			case 'voice':
				return $this->onVoiceMessage($message_request->MediaId, $message_request->Format, $message_request->Recognition);
				break;
			case 'video':
				return $this->onVideoMessage($message_request->MediaId, $message_request->ThumbMediaId);
				break;
			case 'link':
				return $this->onLinkMessage($message_request->Title, $message_request->Description, $message_request->Url);
				break;
			case 'file':
				return $this->onFileMessage($message_request->Title, $message_request->Description, $message_request->FileKey, $message_request->FileMd5, $message_request->FileTotalLen);
				break;
			case 'location':
				return $this->onLocationMessage($message_request->Label, $message_request->Location_X, $message_request->Location_Y, $message_request->Scale);
				break;
			case 'event':
				return $this->onEvent($message_request);
				break;
			default:
				return $this->onOtherMessage($message_request->Event);
				break;
			}
		}
	}

	/**
	 * 事件
	 */
	protected function onEvent($message_request) {
		switch (trim($message_request->Event)) {
		case "subscribe":
			return $this->onSubscribeEvent();
		case "user_enter_tempsession":
			return $this->onUserEnterTempsessionEvent();
		default:
			return $this->onOtherEvent($message_request->Event);
		}
	}

	/**
	 * 回复消息
	 */
	protected function sendMessage($message_body) {
		$tpl = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime>%s</xml>";
		$body = sprintf($tpl, $this->fromUsername, $this->toUsername, time(), $message_body);
		$this->onSendMessage($body);
		return $body;
	}

	/**
	 * 回复文本信息
	 */
	protected function textMessage($content) {
		return $this->sendMessage("<MsgType><![CDATA]></MsgType><Content><![CDATA[${content}]]></Content>");
	}

	/**
	 * 回复图片消息
	 */
	protected function imageMessage($media_id) {
		return $this->sendMessage("<MsgType><![CDATA[image]]></MsgType><Image><MediaId><![CDATA[${media_id}]]></MediaId></Image>");
	}

	/**
	 * 回复语音消息
	 */
	protected function voiceMessage($media_id) {
		return $this->sendMessage("<MsgType><![CDATA[voice]]></MsgType><Voice><MediaId><![CDATA[${media_id}]]></MediaId></Voice>");
	}

	/**
	 * 回复视频消息
	 */
	protected function videoMessage($media_id, $title = '', $desc = '') {
		return $this->sendMessage("<MsgType><![CDATA]></MsgType><Video><MediaId><![CDATA[${media_id}]]></MediaId><Title><![CDATA[${title}]]></Title><Description>< ![CDATA[${desc}] ]></Description></Video>");
	}

	/**
	 * 回复分享信息
	 */
	protected function linkMessage($articles = array()) {
		$content = "<MsgType><![CDATA[news]]></MsgType><ArticleCount>" . count($articles) . "</ArticleCount><Articles>";
		foreach ($articles as $article) {
			list($title, $url, $image, $desc) = $this->linkMessageArticleInfo($article);
			$content .= "<item><Title><![CDATA[${title}]]></Title><Description><![CDATA[${desc}]]></Description><PicUrl><![CDATA[${image}]]></PicUrl><Url><![CDATA[${url}]]></Url></item>";
		}
		$content .= "</Articles>";
		return $this->sendMessage($content);
	}

	/**
	 * 获取分享信息记录
	 */
	protected function linkMessageArticleInfo($article) {
		if (!is_array($article)) {
			$article = array();
		}
		$title = isset($article['title']) ? $article['title'] : '';
		$url = isset($article['url']) ? $article['url'] : '';
		$image = isset($article['image']) ? $article['image'] : '';
		$desc = isset($article['desc']) ? $article['desc'] : '';
		return array($title, $url, $image, $desc);
	}

	/**
	 * 生成单条分享信息记录
	 */
	protected function linkMessageArticleItem($title, $url, $image, $desc) {
		return array(
			'title' => $title,
			'url' => $url,
			'image' => $image,
			'desc' => $desc,
		);
	}
}

使用说明(使用测试工具)

**1、下载本源码并部署到PHP的WEB环境 **

将下载的脚本安装到服务器后,比如:http://您的域名/安装路径/

测试工具的地址为:?http://您的域名/安装路径/test/index.html

如果 仅 需要测试,可以直接访问在线测试地址:http://wechatmessage.demo.miaoqiyuan.cn/test/

**2、选择消息类型,填写参数,点击立即测试,即可看到服务器执行的信息 **

这样 就可以不使用微信,直接开发了。

使用说明(真机测试)

1、申请测试帐号

打开测试接口页面,https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

点击 登录 按钮,使用微信扫码登陆。

**2、填写 测试脚本的URL **

将下载的脚本安装到服务器后,比如:http://您的域名/安装路径/

在 接口配置信息中,填写 测试地址为:?http://您的域名/安装路径/demo/message.php?访问

如果不想自己配置,可以使用 在线测试地址:http://wechatmessage.demo.miaoqiyuan.cn/demo/message.php

 

 

**3、关注 测试号二维码 **

关注 测试号二维码,进入 公众号 聊天窗口,输入内容即可测试。

默认 不支持的消息模式,会如下图显示:

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据