分享下 我的 開源項目 Wechat Message

最近做了幾個微信公眾號自動回復的小程序,時間緊促,代碼寫的非?;靵y。

近期閑下來,把代碼重構了,按這個模式就可以 以非常優雅的方式 處理微信消息。只需要 繼承 消息類,重構類的方法(比如: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.shiekolong1185.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來減少垃圾評論。了解我們如何處理您的評論數據。