# 訂閱號的注冊
由于我們這個只是演示,我也不好拿公司的公眾號來講,所以只能自己注冊一個訂閱號 freelog。
微信公眾平臺 首頁點注冊:



選擇訂閱號 后填一些信息。

前面都是公司運營應該做的。
# 獲取`appid`和`secret_token`及aeskey
注冊完畢后,點微信公眾平臺的左側菜單里的開發者中心,可以看到我們想要的appid和secret_token

需要掃碼后完整顯示。
至于AESKEY ,下面初次配置開發的應用url時會隨機生成一個:

獲取到以后,我們就要在項目公共配置里配置上:
~~~
//微信相關
'WEIXIN'=>array(
'TOKEN' => 'freelog',
'APPID' => 'wx72e0b206f3fb96af',
'AESKEY' => 'PbYuJRJ1UKYzpZoH7PUA6MQySGaqiLTit0XveNPtWQ',
'SECRET' => 'e733caf9234ed2ea1342e85366172513',
),
~~~
在配置應用微信接入地址時,我們傳了slog_force_client_id,這樣我們可以用socketlog 進行調試微信響應。
并且,如果在我們每次修改微信開發配置時,保存不成功說明,我們程序端沒通過驗證。
用了麥當苗兒寫的wechat 類,我們可以不用寫任何驗證代碼。
# 訂閱號開發者模式能做到的接口

基本上就是獲得access_token、服務器ip地址,然后處理一些消息的響應和給用戶留言回復一個消息。
# 我的實現
我給微信定義了一個控制器,并且所以響應放在index方法里處理。
老規矩先上代碼:
~~~
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 麥當苗兒 <zuojiazi@vip.qq.com> <http://www.zjzit.cn>
// +----------------------------------------------------------------------
namespace Home\Controller;
use Think\Controller;
use Com\Wechat;
use Com\WechatAuth;
class WeixinController extends Controller{
public $wc;
/**
* 微信消息接口入口
* 所有發送到微信的消息都會推送到該操作
* 所以,微信公眾平臺后臺填寫的api地址則為該操作的訪問地址
*/
public function index($id = ''){
$token = C('WEIXIN.TOKEN'); //微信后臺填寫的TOKEN
/* 加載微信SDK */
$this->wc = $wechat = new Wechat($token);
/* 獲取請求信息 */
$data = $wechat->request();
slog($data);
if($data && is_array($data)){
switch ($data['MsgType']) {
//事件
case Wechat::MSG_TYPE_EVENT:
switch ($data['Event']) {
case Wechat::MSG_EVENT_SUBSCRIBE:
$wechat->replyText('歡迎關注freelog, 你可以留言引號內內容獲得本賬號的某些服務比如: 回復"聽大白", 會收到一條語音消息, 回復“看視頻”,會收到JobDeer官方介紹視頻,回復"看圖片",看到一個Jobdeer的三行廣告,回復“推薦文章”,收到一個推薦的圖文消息,回復“功能菜單”,收到歡迎文本');
break;
//退訂
case Wechat::MSG_EVENT_UNSUBSCRIBE:
# TODO 添加微信消息記錄日志里去
break;
}
break;
case Wechat::MSG_TYPE_TEXT:
$this->onText($data['Content']);
break;
default:
$wechat->response('其他功能尚在開發中', Wechat::MSG_TYPE_TEXT);
break;
}
/**
* 你可以在這里分析數據,決定要返回給用戶什么樣的信息
* 接受到的信息類型有9種,分別使用下面九個常量標識
* Wechat::MSG_TYPE_TEXT //文本消息
* Wechat::MSG_TYPE_IMAGE //圖片消息
* Wechat::MSG_TYPE_VOICE //音頻消息
* Wechat::MSG_TYPE_VIDEO //視頻消息
* Wechat::MSG_TYPE_MUSIC //音樂消息
* Wechat::MSG_TYPE_NEWS //圖文消息(推送過來的應該不存在這種類型,但是可以給用戶回復該類型消息)
* Wechat::MSG_TYPE_LOCATION //位置消息
* Wechat::MSG_TYPE_LINK //連接消息
* Wechat::MSG_TYPE_EVENT //事件消息
*
* 事件消息又分為下面五種
* Wechat::MSG_EVENT_SUBSCRIBE //訂閱
* Wechat::MSG_EVENT_SCAN //二維碼掃描
* Wechat::MSG_EVENT_LOCATION //報告位置
* Wechat::MSG_EVENT_CLICK //菜單點擊
* Wechat::MSG_EVENT_MASSSENDJOBFINISH //群發消息成功
*/
$content = '這里是Freelog'; //回復內容,回復不同類型消息,內容的格式有所不同
$type = Wechat::MSG_TYPE_TEXT; //回復消息的類型
/* 響應當前請求(自動回復) */
$wechat->response($content, $type);
/**
* 響應當前請求還有以下方法可以只使用
* 具體參數格式說明請參考文檔
*
* $wechat->replyText($text); //回復文本消息
* $wechat->replyImage($media_id); //回復圖片消息
* $wechat->replyVoice($media_id); //回復音頻消息
* $wechat->replyVideo($media_id, $title, $discription); //回復視頻消息
* $wechat->replyMusic($title, $discription, $musicurl, $hqmusicurl, $thumb_media_id); //回復音樂消息
* $wechat->replyNews($news, $news1, $news2, $news3); //回復多條圖文消息
* $wechat->replyNewsOnce($title, $discription, $url, $picurl); //回復單條圖文消息
*
*/
}
}
public function onText($text){
slog($text);
$wechat = $this->wc;
//以下媒體id 是寫死的,而且除了音樂調用成功,其他的視頻和圖片,完全不能正常返回消息。因為不是認證用戶沒有權限使用接口
if(false !== strpos('聽大白', $text)){
//回復音頻消息
$wechat->replyMusic('大白balala', '超能陸戰隊', 'http://att.chinauui.com/day_150309/20150309_aadb238f5998c1a79953qvZzAB41QvBj.wav', 'http://att.chinauui.com/day_150309/20150309_aadb238f5998c1a79953qvZzAB41QvBj.wav');
}else if(false !== strpos('看視頻', $text)){
//回復視頻消息
$wechat->replyVideo(204247676, 'JobDeer官方視頻', '歡迎大家觀看視頻,了解競鹿如何幫助候選人快速換工作的。');
}else if(false !== strpos('看圖片', $text)){
//回復圖片消息
$wechat->replyImage(204248824);
}else if(false !== strpos('推薦文章', $text)){
//回復單條圖文消息
$wechat->replyNewsOnce('最新一篇文章', 'Hello, Weixin', 'http://freelog.coding.io/Post/44.html', 'http://freelog.coding.io/Uploads/ueditor/image/20150326/551419ea33999.jpg');
}else{
$wechat->replyText('歡迎關注freelog, 你可以留言引號內內容獲得本賬號的某些服務比如: 回復"聽大白", 會收到一條語音消息, 回復“看視頻”,會收到JobDeer官方介紹視頻,回復"看圖片",看到一個Jobdeer的三行廣告,回復“推薦文章”,收到一個推薦的圖文消息,回復“功能菜單”,收到歡迎文本');
}
}
//獲取帶參二維碼 目前沒權限,暫時不使用
public function weixinQr($sence_id, $expire_seconds = 0){
$wechatauth = new WechatAuth(C('WEIXIN.APPID'), C('WEIXIN.SECRET'));
$result = $wechatauth->qrcodeCreate($sence_id, $expire_seconds);
if(isset($result['errcode'])){
return false;
}else{
return $wechatauth->showqrcode($result['ticket']);
}
}
}
~~~
~~~
$token = C('WEIXIN.TOKEN'); //微信后臺填寫的TOKEN
/* 加載微信SDK */
$this->wc = $wechat = new Wechat($token);
/* 獲取請求信息 */
$data = $wechat->request();
slog($data);
~~~
首先是實例化wechat類和獲取響應事件。關注和解除關注也是一種事件。
然后就是根據事件的類型進行處理。
~~~
if($data && is_array($data)){
switch ($data['MsgType']) {
//事件
case Wechat::MSG_TYPE_EVENT:
switch ($data['Event']) {
case Wechat::MSG_EVENT_SUBSCRIBE:
$wechat->replyText('歡迎關注freelog, 你可以留言引號內內容獲得本賬號的某些服務比如: 回復"聽大白", 會收到一條語音消息, 回復“看視頻”,會收到JobDeer官方介紹視頻,回復"看圖片",看到一個Jobdeer的三行廣告,回復“推薦文章”,收到一個推薦的圖文消息,回復“功能菜單”,收到歡迎文本');
break;
//退訂
case Wechat::MSG_EVENT_UNSUBSCRIBE:
# TODO 添加微信消息記錄日志里去
break;
}
break;
case Wechat::MSG_TYPE_TEXT:
$this->onText($data['Content']);
break;
default:
$wechat->response('其他功能尚在開發中', Wechat::MSG_TYPE_TEXT);
break;
~~~
接收到的消息類型
接受到的信息類型有9種,分別使用下面九個常量標識
- Wechat::MSG_TYPE_TEXT //文本消息
- Wechat::MSG_TYPE_IMAGE //圖片消息
- Wechat::MSG_TYPE_VOICE //音頻消息
- Wechat::MSG_TYPE_VIDEO //視頻消息
- Wechat::MSG_TYPE_MUSIC //音樂消息
- Wechat::MSG_TYPE_NEWS //圖文消息(推送過來的應該不存在這種類型,但是可以給用戶回復該類型消息)
- Wechat::MSG_TYPE_LOCATION //位置消息
- Wechat::MSG_TYPE_LINK //連接消息
- Wechat::MSG_TYPE_EVENT //事件消息
事件消息又分為下面五種:
- Wechat::MSG_EVENT_SUBSCRIBE //訂閱
- Wechat::MSG_EVENT_SCAN //二維碼掃描
- Wechat::MSG_EVENT_LOCATION //報告位置
- Wechat::MSG_EVENT_CLICK //菜單點擊
- Wechat::MSG_EVENT_MASSSENDJOBFINISH //群發消息成功
默認關注,提示首次關注信息,其他文字調用onText處理響應。
index 里 其他的注釋是 使用示列,我寫出來方便大家自己參照調用。
我們,看一下onText 方法:
~~~
public function onText($text){
slog($text);
$wechat = $this->wc;
//以下媒體id 是寫死的,而且除了音樂調用成功,其他的視頻和圖片,完全不能正常返回消息。因為不是認證用戶沒有權限使用接口
if(false !== strpos('聽大白', $text)){
//回復音頻消息
$wechat->replyMusic('大白balala', '超能陸戰隊', 'http://att.chinauui.com/day_150309/20150309_aadb238f5998c1a79953qvZzAB41QvBj.wav', 'http://att.chinauui.com/day_150309/20150309_aadb238f5998c1a79953qvZzAB41QvBj.wav');
}else if(false !== strpos('看視頻', $text)){
//回復視頻消息
$wechat->replyVideo(204247676, 'JobDeer官方視頻', '歡迎大家觀看視頻,了解競鹿如何幫助候選人快速換工作的。');
}else if(false !== strpos('看圖片', $text)){
//回復圖片消息
$wechat->replyImage(204248824);
}else if(false !== strpos('推薦文章', $text)){
//回復單條圖文消息
$wechat->replyNewsOnce('最新一篇文章', 'Hello, Weixin', 'http://freelog.coding.io/Post/44.html', 'http://freelog.coding.io/Uploads/ueditor/image/20150326/551419ea33999.jpg');
}else{
$wechat->replyText('歡迎關注freelog, 你可以留言引號內內容獲得本賬號的某些服務比如: 回復"聽大白", 會收到一條語音消息, 回復“看視頻”,會收到JobDeer官方介紹視頻,回復"看圖片",看到一個Jobdeer的三行廣告,回復“推薦文章”,收到一個推薦的圖文消息,回復“功能菜單”,收到歡迎文本');
}
}
~~~
其實就是根據留言的消息里,文本內容來做switch 分支菜單。沒菜單權限的訂閱號只能這么做了。
里面注意的是,媒體資源的媒體id,只能在公眾平臺里的素材庫里先準備好。
比方說 我回復視頻時的204247676,是從下面圖片上id部分獲得的:

這樣,即使沒有管理素材的權限,我們也可以人工的獲取媒體id。
上面說的是錯誤的(都是我在文檔不全的情況下猜測的),那個不是真正的媒體id,那樣寫的我的視頻放不出來。
我請教了微信類的作者左家梓,他說媒體id一般通過媒體上傳接口返回過來。不是數字。像這樣的:

總算見到豬跑了。
順便貼一下他的demo,https://github.com/Aoiujz/WechatSDK 之前sdk都沒有git沒法提issue和討論。還是沒文檔差評。
然并卵,我們個人訂閱號無法認證,沒權限上傳和獲取,微信平臺真坑人,無法微信認證,開發者認證還有啥用。

我只好求助搜索引擎,結果真讓我找到這么一個曲線救國的方法:

我自己往freelog訂閱號里傳了張圖片,用我們的socketlog,觀察,發現了mediaid

少年啊,我找你好多天了。
為了調試方便,我把default分支擴展了下:
~~~
default:
$user_send_types = array(Wechat::MSG_TYPE_IMAGE, Wechat::MSG_TYPE_VOICE, Wechat::MSG_TYPE_VIDEO, Wechat::MSG_TYPE_SHORTVIDEO, Wechat::MSG_TYPE_MUSIC);
if(in_array($data['MsgType'], $user_send_types)){
$wechat->replyText('用戶傳了媒體消息'.$data['MsgType']."媒體id為:{$data['MediaId']}");
}else{
$wechat->response('其他功能尚在開發中', Wechat::MSG_TYPE_TEXT);
}
break;
~~~
這樣獲取的媒體id ,發圖片沒問題,小視頻的媒體id 怎么都不行。
如果只是研究,可以使用測試平臺,啥權限都有。如果是在想這些功能。少年,重頭注冊一個認證的公眾號吧,或者找第三方公眾平臺。
還有,訂閱號的服務器配置是可以隨時停止和開啟的。
然后,如果開啟了服務器配置,表示所有的響應和自動回復,都通過我們程序接口處理。關閉了就不會進入程序處理邏輯。
像我們程序里的做的幾件事:
關注回復、消息自動回復和關鍵詞回復,都可以通過公眾平臺做到。

這里被添加就是被關注。
而且,公眾平臺的好處是,自動回復的定制化支持表情、圖片還有換行。

而且,同時多個關鍵詞

所以,如果只是訂閱號的話,完全可以在開發完接口自動回復和關注回復的時候。
再去公眾平臺實現同樣的功能。這樣,當你程序服務器接口出問題時。可以直接把接口停用,讓公眾平臺處理,做個災備。
# 出錯的時候的調試
當用戶留言時,微信提示“該公眾號暫時無法提供服務,請稍后再試”,如下圖的時候,就表示我們的程序沒有響應正確的微信響應格式。

# 在線接口調試工具和測試號的使用
微信公眾平臺里有這么2個東西:

## 在線接口調試工具
它可以幫我們在沒有寫好接口時,通過自己的appid、secret_key等,去直接調用線上接口。然后我們根據響應結果,來觀察并處理可能要開發的微信接口的數據結構。
像這樣:

我們知道access_token的長度,和過期時間。
像這樣,我手機留言了一條“測試”的文本消息。

再通過調試工具,完全可以模擬測試各種內容:

我們只要偽造時間戳,內容和msgId,就可以重復測試多次。
## 接口測試申請系統
這個是給你的網站應用可以配制一個測試微信接口地址。
有的時候你開發的接口消息功能消息,不想讓線上微信訂閱用戶收到。
可以分配一個測試地址,和測試appid、AESKEY、和secret_key。
只要測試的服務器響應時調用的這些測試賬號配置,那么微信消息響應和回復就會進入測試訂閱號和測試關注者里去了。不會影響到線上,給開發者一個試驗田。
- 序
- 前言
- 內容簡介
- 目錄
- 基礎知識
- 起步
- 控制器
- 模型
- 模板
- 命名空間
- 進階知識
- 路由
- 配置
- 緩存
- 權限
- 擴展
- 國際化
- 安全
- 單元測試
- 拿來主義
- 調試方法
- 調試的步驟
- 調試工具
- 顯示trace信息
- 開啟調試和關閉調試的區別
- netbeans+xdebug
- Socketlog
- PHP常見錯誤
- 小黃鴨調試法,每個程序員都要知道的
- 應用場景
- 第三方登錄
- 圖片處理
- 博客
- SAE
- REST實踐
- Cli
- ajax分頁
- barcode條形碼
- excel
- 發郵件
- 漢字轉全拼和首字母,支持帶聲調
- 中文分詞
- 瀏覽器useragent解析
- freelog項目實戰
- 需求分析
- 數據庫設計
- 編碼實踐
- 前端實現
- rest接口
- 文章發布
- 文件上傳
- 視頻播放
- 音樂播放
- 圖片幻燈片展示
- 注冊和登錄
- 個人資料更新
- 第三方登錄的使用
- 后臺
- 微信的開發
- 首頁及個人主頁
- 列表
- 歸檔
- 搜索
- 分頁
- 總結經驗
- 自我提升
- 進行小項目的鍛煉
- 對現有輪子的重構和移植
- 寫技術博客
- 制作視頻教程
- 學習PHP的知識和新特性
- 和同行直接溝通、交流
- 學好英語,走向國際
- 如何參與
- 瀏覽官網和極思維還有看云
- 回答ThinkPHP新手的問題
- 嘗試發現ThinkPHP的bug,告訴官方人員或者push request
- 開發能提高效率的ThinkPHP工具
- 嘗試翻譯官方文檔
- 幫新手入門
- 創造基于ThinkPHP的產品,進行連帶推廣
- 展望未來
- OneThink
- ThinkPHP4
- 附錄