微信公众号开发初探
最近利用空閑時(shí)間,申請(qǐng)了個(gè)微信公眾號(hào),完成一些小功能練練手。
本文總結(jié)了開(kāi)發(fā)公眾號(hào)期間的一些步驟,心得和體會(huì),希望能幫助更多想做微信開(kāi)發(fā)的小白開(kāi)發(fā)者。
申請(qǐng)微信公眾號(hào)
要體驗(yàn)微信公眾號(hào)開(kāi)發(fā),首先得有一個(gè)公眾號(hào),直接在官網(wǎng)申請(qǐng)即可(記住需要新申請(qǐng)公眾號(hào),而不是用你原來(lái)的 QQ 或微信登錄)。
申請(qǐng)過(guò)程中,要注意的是,我們申請(qǐng)的是訂閱號(hào),用于個(gè)人開(kāi)發(fā)。
申請(qǐng)成功后,登錄到公眾號(hào)后臺(tái),左側(cè)有豐富的菜單供你使用,可以選擇傻瓜式,就是不用寫(xiě)一行代碼,通過(guò)在左側(cè)菜單配置,自己設(shè)置關(guān)注后的歡迎語(yǔ)、給用戶發(fā)消息操作等。也可以選擇開(kāi)發(fā)者模式,將左側(cè)菜單拉到最下面,可以看到如下圖所示的開(kāi)發(fā)欄。
為了后續(xù)及時(shí)查看效果,需要第一時(shí)間關(guān)注這個(gè)公眾號(hào),成為自己的第一個(gè)粉絲。
開(kāi)始編寫(xiě)代碼
首先,我們要明白微信公眾號(hào)和用戶打交道的流程,下圖簡(jiǎn)單展示了這個(gè)流程。
從圖中可以看到,當(dāng)你在微信中向公眾號(hào)發(fā)一條消息,這條消息首先會(huì)送到微信服務(wù)器,然后轉(zhuǎn)發(fā)給你的服務(wù)器,經(jīng)過(guò)處理后把響應(yīng)回給微信服務(wù)器,微信服務(wù)器再轉(zhuǎn)給你。
這個(gè)和我們開(kāi)發(fā) Web 程序 C/S 模式基本一致,不同的是,在客戶端和服務(wù)端中間,多了一個(gè)微信服務(wù)器做轉(zhuǎn)發(fā)。
因此我們要關(guān)注的,仍然是寫(xiě)服務(wù)端程序,以便接收微信服務(wù)器轉(zhuǎn)發(fā)過(guò)來(lái)的請(qǐng)求。我們的服務(wù)入口必須是微信服務(wù)器可以訪問(wèn)的,也就是一個(gè)公網(wǎng)地址,內(nèi)網(wǎng) IP 肯定是不行的,所以首先得有一臺(tái)有外網(wǎng) IP 的服務(wù)器。
以滴滴云 DC2 服務(wù)器為例,在官網(wǎng)上購(gòu)買一個(gè)帶 EIP 的 DC2 實(shí)例,ssh 登錄到 DC2,安裝 lnmp 全家桶。安裝好后,確認(rèn) Nginx 和 php-fpm 已運(yùn)行。然后就可以在微信公眾平臺(tái)上配置服務(wù)器地址了。
打開(kāi)基本配置頁(yè)面,按下圖方式填寫(xiě)表單:
填寫(xiě)好后,不要急著提交。我們?cè)?DC2 服務(wù)器的 Web 目錄下,寫(xiě)個(gè)測(cè)試程序 main.php,代碼如下所示,這段代碼也可以在 微信wiki 上找到。
define("TOKEN","your token"); //token 是剛才你在表單寫(xiě)的token function checkSignature() { $signature = $_GET['signature']; //微信加密簽名 $nonce = $_GET['nonce']; //時(shí)間戳 $timestamp = $_GET['timestamp']; //隨機(jī)數(shù) $arr = [$timestamp, $nonce, TOKEN];sort($arr); $arr = implode($arr);$m_arr = sha1($arr);if($m_arr == $signature) {return true;} return false; }if (checkSignature()) {$echostr = $_GET['echostr'];if($echostr) {echo $echostr;} }簡(jiǎn)單解釋一下,當(dāng)我們提交上述表單后,微信服務(wù)器會(huì)對(duì)我們填寫(xiě)的地址進(jìn)行驗(yàn)證,參數(shù)如上述注釋,如果表單提示成功,則說(shuō)明微信服務(wù)器訪問(wèn)到了你配置的 URL,并認(rèn)證成功,如果失敗,則檢查下你的代碼。
認(rèn)證成功后,我們就可以把上面的測(cè)試代碼刪掉,開(kāi)始寫(xiě)真正的服務(wù)端程序。
第一個(gè)服務(wù)
首先我們寫(xiě)一個(gè)天氣查詢服務(wù),就是給公眾號(hào)發(fā)一個(gè)城市名,公眾號(hào)返回該城市未來(lái)三天的天氣。我這里用的是心知天氣提供的天氣 API,我們分兩步來(lái)進(jìn)行:
1、獲取用戶輸入的城市名
由上圖我們知道,用戶的輸入最終會(huì)由微信服務(wù)器轉(zhuǎn)發(fā)給我們自己的服務(wù)端程序,微信服務(wù)器轉(zhuǎn)發(fā)給我們的數(shù)據(jù)格式如下:
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId></xml>這里簡(jiǎn)單解釋下上面的各個(gè)字段:
- ToUserName 消息要發(fā)送給誰(shuí)
- FromUserName 是消息從哪來(lái)
- CreateTime 時(shí)間戳
- MsgType 消息類型
- MsgId 消息 Id
我們的服務(wù)端程序得獲取這個(gè)數(shù)據(jù),需要注意的是,如果 PHP 版本是 5.x,可以直接使用 $GLOBALS["HTTP_RAW_POST_DATA"]超全局變量來(lái)獲取,如果是 PHP7($GLOBALS 已經(jīng)被取消),需要用以下方式來(lái)獲取:
$wx_post = file_get_contents("php://input")然后解析 xml 數(shù)據(jù),提取各類字段,如下:
$postObj = simplexml_load_string($wx_post, 'SimpleXMLElement', LIBXML_NOCDATA); $from_user_name = $postObj->FromUserName; $to_user_name = $postObj->ToUserName; $city = trim($postObj->Content); //提取用戶發(fā)送的城市名2、根據(jù)城市名,返回天氣信息
拿到了城市名,就可以通過(guò) API 查詢城市天氣信息了,但有個(gè)問(wèn)題需要解決:一般用戶發(fā)的是中文城市名,而通過(guò) API 查詢,需要的是城市的拼音,因此需要寫(xiě)一個(gè) 中文->拼音 的轉(zhuǎn)換函數(shù)。在 GitHub 上有很多這類項(xiàng)目,我用的是 這個(gè) 庫(kù),使用方法自行查看。
轉(zhuǎn)換成拼音后,即可按 API 的要求,拼接 URL,發(fā)送查詢請(qǐng)求,將返回的天氣數(shù)據(jù)簡(jiǎn)單解析,并封裝成微信需要的格式,構(gòu)造響應(yīng),假如要返回給微信服務(wù)器的天氣數(shù)據(jù)為 $weather_info,那么代碼如下:
$textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[%s]]></Content> <FuncFlag>0</FuncFlag> </xml>"; return sprintf($textTpl,$from_user_name,$to_user_name,time(),$weather_info);到這一步,我們已經(jīng)做完了所有工作,現(xiàn)在可以嘗試向公眾號(hào)發(fā)送一條消息,隨便發(fā)個(gè)城市名,如果代碼沒(méi)有錯(cuò)誤,那么會(huì)看到下圖所示的效果:
如果微信返回類似“該公眾號(hào)暫時(shí)無(wú)法提供服務(wù)”的提示,那就說(shuō)明你的代碼存在問(wèn)題,可是能你的程序沒(méi)給微信服務(wù)器返回任何內(nèi)容,也可能回復(fù)的數(shù)據(jù)不合規(guī)范,給你直接返回了 JSON 類型數(shù)據(jù)。檢查下代碼,或者看看 Nginx 日志,一般都能找到原因。
更進(jìn)一步
有了上面簡(jiǎn)單的實(shí)戰(zhàn),我們了解了微信開(kāi)發(fā)的基本流程,并實(shí)現(xiàn)了一個(gè)向公眾號(hào)的粉絲提供天氣查詢的服務(wù)。上面只是向用戶返回了文字類型消息,我們也可以嘗試發(fā)送圖片、音樂(lè)、圖文類型的消息,只需要將上述消息 MsgType 字段改為對(duì)應(yīng)類型,并按微信開(kāi)發(fā)手冊(cè)填充 Content 內(nèi)容即可,剩下的就是發(fā)揮想象力的時(shí)候了,可以嘗試添加其他功能,比如點(diǎn)歌、查快遞,甚至像 Siri 的一個(gè)機(jī)器助理。
總結(jié)
從上述開(kāi)發(fā)過(guò)程我們可以看到,微信公眾號(hào)開(kāi)發(fā)和我們開(kāi)發(fā)普通的 Web 程序基本一致,唯一不同的中間經(jīng)過(guò)了微信服務(wù)器做了一次轉(zhuǎn)發(fā)。需要注意的是,上述配置的公眾號(hào),只有部分微信 API 權(quán)限,分享、支付等功能,均需要通過(guò)認(rèn)證才可用。
本文作者:許基偉
想了解更多技術(shù)知識(shí),歡迎關(guān)注滴滴云知乎機(jī)構(gòu)號(hào),大量教程在線等你~
滴滴云官網(wǎng):https://www.didiyun.com/?channel=14112
滴滴云瘋狂雙十一,服務(wù)器最低35折起
總結(jié)
- 上一篇: Javascript之把网页加入收藏夹功
- 下一篇: Excel的上传下载