PHP微信公眾號開發——群發訊息
高階群發介面
二.關於群發介面
1.訂閱號每天可以群發訊息一條,服務號每月(自然月)四條的群發許可權。開發者模式下,可以通過高階群發介面,實現更靈活的群發能力。
2.注意
● 對於認證訂閱號,群發介面每天可成功呼叫1次,此次群發可選擇傳送給全部使用者或某個標籤;
● 對於認證服務號雖然開發者使用高階群發介面的每日呼叫限制為100次,但是使用者每月只能接收4條,無論在公眾平臺網站上,還是使用介面群發,使用者每月只能接收4條群發訊息,多於4條的群發將對該使用者傳送失敗;
● 具備微信支付許可權的公眾號,在使用群發介面上傳、群發圖文訊息型別時,可使用a標籤加入外鏈;
● 開發者可以使用預覽介面校對訊息樣式和排版,通過預覽介面可傳送編輯好的訊息給指定使用者校驗效果。
通俗的說就是
● 服務號一個月只能發四條訊息,雖然一個月就四條 但它是即時呈現到客戶眼前 只要你開啟微信就有一條未讀
● 訂閱號每天一條,但訂閱號所有的商家都在一起顯示,而且不會主動提醒,需要你點開服務號才可以看到
● 一條群發訊息裡,是可以包括多條圖文訊息。
● 群發的訊息不包括商家推送訊息等其他訊息型別。
如下所示,為京東的服務號訊息介面。上面的是群發訊息,下面是發貨通知訊息。
這就是為什麼有的人會疑惑,自己接受來自服務號的訊息1個月不止4條,或者接受的訊息怎麼有好幾條。
3.群發圖文訊息的過程
● 首先,預先將圖文訊息中需要用到的圖片,使用上傳圖文訊息內圖片介面,上傳成功並獲得圖片URL
● 上傳圖文訊息素材,需要用到圖片時,請使用上一步獲取的圖片URL
● 使用對使用者標籤的群發,或對OpenID列表的群發,將圖文訊息群發出去
● 在上述過程中,如果需要,還可以預覽圖文訊息、查詢群髮狀態,或刪除已群發的訊息等
4.群發圖片、文字等其他訊息型別的過程
● 如果是群發文本訊息,則直接根據下面的介面說明進行群發即可
● 如果是群發圖片、視訊等訊息,則需要預先通過素材管理介面準備好mediaID
5.關於群發時使用is_to_all為true使其進入公眾號在微信客戶端的歷史訊息列表
● 使用is_to_all為true且成功群發,會使得此次群發進入歷史訊息列表。
● 為防止異常,認證訂閱號在一天內,只能使用is_to_all為true進行群發一次,或者在公眾平臺官網群發(不管本次群發是對全體還是對某個分組)一次。以避免一天內有2條群發進入歷史訊息列表。
● 類似地,服務號在一個月內,使用is_to_all為true群發的次數,加上公眾平臺官網群發(不管本次群發是對全體還是對某個分組)的次數,最多隻能是4次。
● 設定is_to_all為false時是可以多次群發的,但每個使用者只會收到最多4條,且這些群發不會進入歷史訊息列表。
注意
1.本介面中所有使用到media_id的地方,現在都可以使用素材管理中的永久素材media_id了。請但注意,使用同一個素材群發出去的連結是一樣的,這意味著,刪除某一次群發,會導致整個連結失效。
2.建議使用開發者模式的情況下,先使用預覽介面,因為介面每日可以調取100次。預覽達到預期效果後,才使用正式介面(openId列表群發)。
6.附說明:getWxAccessToken和https_request分別是我程式碼中關於獲取微信全域性token和呼叫第三方介面的方法。
三.群發訊息介面——關於素材與介面
初學者很容易分不清楚開發文章當中,’素材管理‘與’訊息管理-群發介面‘中,一些操作步驟的區別和用途,本人當時也是饒了很多坑,各種搜尋與詢問,故記錄下來,為的就是日後能夠幫助同行少繞彎路,以及自己日後的溫習。如有錯誤的地方,懇請不臨指教,謝謝。
1.官文連結
● 高階群發
https://mp.weixin.qq.com/wiki...
● 素材管理
https://mp.weixin.qq.com/wiki...
2.關於素材
● 素材:在微信開發中,素材指的就是原始的媒體檔案(如圖片、視訊、聲音等)以及圖文型別的檔案
● 媒體檔案是最基礎的素材,圖文素材等(比如含其他媒體檔案的檔案素材)其他素材需要獲取到基礎媒體檔案素材,這個看具體也無需求
● 也就是說,你也可以選擇在群發訊息的時候,發純文字素材
● 媒體素材通過介面上傳成功後,都會有一個媒體id,也就是media_id,這個媒體id用在之後需要呼叫的時候,是個關鍵。
注意
● 上傳圖片素材分兩種:返回URL和返回media_id
● 素材管理分兩大類:永久和臨時
3.臨時素材與永久素材
● 臨時素材
公眾號經常有需要用到一些臨時性的多媒體素材的場景,例如在使用介面特別是傳送訊息時,對多媒體檔案、多媒體訊息的獲取和呼叫等操作,是通過media_id來進行的。素材管理介面對所有認證的訂閱號和服務號開放。通過本介面,公眾號可以新增臨時素材(即上傳臨時多媒體檔案)。
請注意:
1、對於臨時素材,每個素材(media_id)會在開發者上傳或粉絲髮送到微信伺服器3天后自動刪除(所以使用者傳送給開發者的素材,若開發者需要,應儘快下載到本地),以節省伺服器資源。
2、media_id是可複用的。
3、素材的格式大小等要求與公眾平臺官網一致。具體是,圖片大小不超過2M,支援png/jpeg/jpg/gif格式,語音大小不超過5M,長度不超過60秒,支援mp3/amr格式
4、需使用https呼叫本介面。
● 永久素材
除了3天就會失效的臨時素材外,開發者有時需要永久儲存一些素材,屆時就可以通過本介面新增永久素材。
最近更新,永久圖片素材新增後,將帶有URL返回給開發者,開發者可以在騰訊系域名內使用(騰訊系域名外使用,圖片將被遮蔽)。
請注意:
1、新增的永久素材也可以在公眾平臺官網素材管理模組中看到
2、永久素材的數量是有上限的,請謹慎新增。圖文訊息素材和圖片素材的上限為5000,其他型別為1000
3、素材的格式大小等要求與公眾平臺官網一致。具體是,圖片大小不超過2M,支援bmp/png/jpeg/jpg/gif格式,語音大小不超過5M,長度不超過60秒,支援mp3/wma/wav/amr格式
4、呼叫該介面需https協議
注意
● “永久素材”裡的“最近更新...”文字所說的返回URL,就是前面提到的上傳圖片素材種類之一:返回圖片URL
臨時素材與永久素材的不同之處
4.素材與群發介面的結合使用(以下講解的素材均以永久素材來說明)
第一步:上傳圖片
前面有提過,上傳圖片素材分兩種,主要是返回引數的不同
a.返回media_id(其實可以同時返回media_id和url)——文件名:新增其他型別永久素材
使用說明
● 傳入引數:全域性token和型別type
● 返回:media_id和url
● 可以根據業務邏輯需求,只返回media_id或者做判斷
● 注意:視訊素材的請求連結是不同的
● 使用:URL可以直接放在群發訊息之圖文訊息中的img標籤,media_id可以用在圖文訊息的封面圖片id。
b.只返回URL——文件名:上傳圖文訊息內的圖片獲取URL
使用說明
● 傳入引數:全域性token
● 返回:url
● URL作用:放在圖文訊息中使用(使用img標籤)。
c.總結:只返回URL和返回media_id的區別就在於使用地方的不同,當然返回media_id的方法也可以返回URL。media_id用於群發圖文訊息的封面,url用在文字的Img標籤。
第二步:上傳圖文素材等檔案素材
a.新增永久圖文素材
b.上傳圖文訊息素材
由於和上面的新增永久圖文素材差異不大,故這裡不做贅述,詳情見第七條。
簡單說明
● thumb_media_id:前面提到的上傳圖片返回media_id(也就是“新增其他型別永久素材”)就是用在此處,作為圖文訊息的封面圖片。
● content:前面提到的上傳圖片2種類型,返回的URL就是用在此處的img標籤裡。
5.關於“上傳圖文訊息素材”和“新增永久圖文素材”的區別
● 上傳圖文訊息素材:等於是直接把圖文素材傳到微信的伺服器,每次憑藉media_id獲取素材,並且不佔用素材庫
● 新增永久圖文素材:在開發者和微信伺服器之間,多了一個素材庫。素材庫的素材有數量限制,但是可以直接檢視到。
四.群發訊息介面——第1步:上傳圖片(返回URL)
1.說明
● 功能:上傳圖文訊息內的圖片獲取URL【訂閱號與服務號認證後均可用】
● 注意:本介面所上傳的圖片不佔用公眾號的素材庫中圖片數量的5000個的限制。圖片僅支援jpg/png格式,大小必須在1MB以下
● 官方文件參考
2.程式碼實現
a.思路
● 呼叫介面
https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
看到後面需要用token,就知道,肯定也是需要獲取到全域性的token,再組裝url。
● 引數說明
呼叫示例(使用curl命令,用FORM表單方式上傳一個圖片):
curl -F media=@test .jpg "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN"
從官文中可以看出,圖片名(帶格式的圖片名)需要在media(代表媒體)之後,並加@符號。
這裡就涉及到CURL的知識:
curl上傳:檔案的標識@+相對路徑
b.程式碼實現
注:以下是我的程式碼實現,大家可以根據自己的專案去實際編寫
function addMaterial() {
$access_token = $this->getWxAccessToken();
$url = "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=".$access_token;
$filename = '檔名,帶路徑';
$data=array("media"=>'@'. $filename);
print_R($data);
$res=$this->https_request( $url ,'post', 'json', $data);
dump($res); exit();
return $res;
}
● 說明
——方法為了實現功能,寫的都比較直接。後續可以對程式碼進行改編,方法裡的引數可以使用傳參的方式,這樣使用起來也比較靈活。
—— filename:檔名,相對於專案的入口檔案,一般是根目錄的路徑。比如我編寫此程式碼的時候用的是ThinkPHP框架,專案根目錄有個index.php入口檔案,在根目錄有個Public,圖片是直接放在Public下的,所以上述的filename應該是Public/圖片名.格式,請大家根據自己實際圖片路徑去寫。
——print_r和dump是為了看列印的結果,這個大家測試的時候可以使用下,方便檢視,無誤後去掉即可。
四.群發訊息介面——第1步:上傳素材(包括圖片、視訊、聲音等,返回URL和MediaId,推薦)
1.說明
● 新增的永久素材也可以在公眾平臺官網素材管理模組中看到
● 永久素材的數量是有上限的,請謹慎新增。圖文訊息素材和圖片素材的上限為5000,其他型別為1000
● 素材的格式大小等要求與公眾平臺官網一致。具體是,圖片大小不超過2M,支援bmp/png/jpeg/jpg/gif格式,語音大小不超過5M,長度不超過60秒,支援mp3/wma/wav/amr格式
● 呼叫介面需https協議
● 官方文件參考
● 注意:官方說明,視訊素材需要另外一個表單,這裡暫不做說明。
● 通過POST表單來呼叫介面,表單id為media,包含需要上傳的素材內容,有filename、filelength、content-type等資訊
● 注意:圖片素材將進入公眾平臺官網素材管理模組中的預設分組
2.程式碼實現
a.思路
● 呼叫介面
https://api.weixin.qq.com/cgi-bin/material/add_material? access_token=ACCESS_TOKEN&type=TYPE
看到後面需要用token,就知道,肯定也是需要獲取到全域性的token,再組裝url,此外type型別也需要指定。
● 官方關於型別等其他引數說明如下
引數是否必須說明access_token是呼叫介面憑證type是媒體檔案型別,分別有圖片(image)、語音(voice)、視訊(video)和縮圖(thumb)media是form-data中媒體檔案標識,有filename、filelength、content-type等資訊
b.程式碼實現
注:以下是我的程式碼實現,大家可以根據自己的專案去實際編寫
function addMaterial() {
$access_token = $this->getWxAccessToken();
$type='image';
//https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=TYPE
$url = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=".$access_token."&type=".$type;
$filename = '檔名';
$data=array("media"=>'@'. $filename);
$res=$this->https_request( $url ,'post', 'json', $data);
return $res['media_id'];
}
● 說明
——方法為了實現功能,寫的都比較直接。後續可以對程式碼進行改編,方法裡的引數可以使用傳參的方式,這樣使用起來也比較靈活。
—— filename:帶格式的檔名,相對於專案的入口檔案,一般是根目錄的路徑。比如我編寫此程式碼的時候用的是ThinkPHP框架,專案根目錄有個index.php入口檔案,在根目錄有個Public,圖片是直接放在Public下的,所以上述的filename才是如此格式,請大家根據自己實際圖片路徑去寫。
——type:傳入的媒體型別
——作用:返回的media_id用作新增圖文素材中的圖文訊息封面素材id,url用作新增圖文素材中,content(圖文訊息的具體內容)的img標籤。
六.群發訊息介面——第2步:上傳圖文之新增永久圖文素材
2.注意
● thumb_media_id:需要先上傳圖片素材,且圖文訊息的封面圖片素材id必須是永久mediaID
● content:上傳圖片素材的2種方式,都有返回url,就是用在此處的img標籤中。
● 返回:media_id用於呼叫後面的群發訊息時使用
● 注意:圖文訊息內容,將過濾外部的圖片連結
3.程式碼實現
function addNews(){
$access_token = $this->getWxAccessToken();
$thumb_media_id=$this->addMaterial();
$content_img=$this->addMaterialUrl();
$url = "https://api.weixin.qq.com/cgi-bin/material/add_news?access_token=".$access_token;
$array = array(
"articles" => array( /*若新增的是多圖文素材,則此處應還有幾段articles結構 */
array(
"title" => urlencode('最後一組測試——1'),
"thumb_media_id" => $thumb_media_id, //圖文訊息的封面圖片素材id(必須是永久mediaID)
"author" => urlencode('測試編輯1'), //作者
"digest" => urlencode('這是測試的摘要1'), //圖文訊息的摘要,僅有單圖文訊息才有摘要,多圖文此處為空
"show_cover_pic" => 1, //是否顯示封面,0為false,即不顯示,1為true,即顯示
"content" => urlencode("<h1>這是一個測試文章1</h1><br /><img src='{$content_img}' /><br /><div>測試下圖文素材的效果</div><br /><div>測試下圖文素材的效果</div>"), //圖文訊息的具體內容,支援HTML標籤,必須少於2萬字符,小於1M,且此處會去除JS
"content_source_url" => urlencode("http://www.地址") //圖文訊息的原文地址,即點選“閱讀原文”後的URL
),
array(
"title" => urlencode('最後一組測試——2'),
"thumb_media_id" => $thumb_media_id, //圖文訊息的封面圖片素材id(必須是永久mediaID)
"author" => urlencode('測試編輯2'), //作者
"digest" => urlencode('這是測試的摘要2'), //圖文訊息的摘要,僅有單圖文訊息才有摘要,多圖文此處為空
"show_cover_pic" => 1, //是否顯示封面,0為false,即不顯示,1為true,即顯示
"content" => urlencode("<h1>這是一個測試文章2</h1><br /><img src='{$content_img}' /><br /><div>測試下圖文素材的效果</div><br /><div>測試下圖文素材的效果</div>"), //圖文訊息的具體內容,支援HTML標籤,必須少於2萬字符,小於1M,且此處會去除JS
"content_source_url" => urlencode("http://www.地址") //圖文訊息的原文地址,即點選“閱讀原文”後的URL
),
),
);
$postJson = urldecode( json_encode( $array ) );
//dump($postJson);
$res=$this->https_request( $url ,'post', 'json', $postJson);
//dump($res['media_id']);exit();
return $res['media_id'];
}
說明
● addMaterial():是我寫的新增其他型別永久素材,裡面新增的是圖片。
● addMaterialUrl():是我寫的一個關於上傳圖片只返回URL的方法。雖然返回的只有URL,但也是個陣列,所以,要麼在方法裡返回結果的時候,就取下標url返回,要麼呼叫的時候取下標url使用。
● urlencode和urldecode:因為後面POST的是一個JSON陣列。如果JSON資料裡有中文,那麼需要用urlencode先轉,後面再用urldecode轉過來。
● 需要注意的是,我的html標記屬性用的是單引號,所以無需轉義。如果你使用了雙引號,需要用htmlspecialchars轉義,再用htmlspecialchars_decode轉回來。
● 請使用三維陣列!!!看官方示例,如果以PHP寫陣列的寫法來看,似乎不熟悉的人都會寫成二維陣列,但是這樣是無法解析的,在articles裡,還有一層陣列!!
2.程式碼實現
function uploadNews(){
//1.獲取全域性access_token
$access_token = $this->getWxAccessToken();
$url = "https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token=".$access_token;
//2.組裝資料
$thumb_media_id=$this->addMaterial();
$content_img=$this->addMaterialUrl();
$array = array(
"articles" => array( /*若新增的是多圖文素材,則此處應還有幾段articles結構 */
array(
"thumb_media_id" => $thumb_media_id, //圖文訊息縮圖的media_id,可以在基礎支援-上傳多媒體檔案介面中獲得
"author" => urlencode('編輯1'), //作者
"title" => urlencode('這是測試的標題——1'),
"content_source_url" => urlencode("http://www.地址"), //圖文訊息的原文地址,即點選“閱讀原文”後的URL
"content" => urlencode("<h1>這是一個測試文章——1</h1><br /><img src='{$content_img}' /><br /><div>測試下圖文素材的效果——1</div><br /><div>測試下圖文素材的效果——1</div>"), //圖文訊息的具體內容,支援HTML標籤,必須少於2萬字符,小於1M,且此處會去除JS
"digest" => urlencode('這是測試的摘要1'), //圖文訊息的摘要,僅有單圖文訊息才有摘要,多圖文此處為空
"show_cover_pic" => 1 //是否顯示封面,0為false,即不顯示,1為true,即顯示
),//第一個圖文文
array(
"thumb_media_id" => $thumb_media_id, //圖文訊息縮圖的media_id,可以在基礎支援-上傳多媒體檔案介面中獲得
"author" => urlencode('編輯2'), //作者
"title" => urlencode('這是測試的標題——2'),
"content_source_url" => urlencode("http://www.地址"), //圖文訊息的原文地址,即點選“閱讀原文”後的URL
"content" => urlencode("<h1>這是一個測試文章——2</h1><br /><img src='{$content_img}' /><br /><div>測試下圖文素材的效果——1</div><br /><div>測試下圖文素材的效果——1</div>"), //圖文訊息的具體內容,支援HTML標籤,必須少於2萬字符,小於1M,且此處會去除JS
"digest" => urlencode('這是測試的摘要2'), //圖文訊息的摘要,僅有單圖文訊息才有摘要,多圖文此處為空
"show_cover_pic" => 1 //是否顯示封面,0為false,即不顯示,1為true,即顯示
),//第2個圖文
),
);
$postJson = urldecode( json_encode( $array ) );
$res=$this->https_request( $url ,'post', 'json', $postJson);
//dump($res);
return $res['media_id'];
}
說明
● $thumb_media_id和$content_img的獲取方法:均為前文中提到的方法
● 注意:articles下的陣列個數,取決於你要傳送的圖文訊息個數,但一次最多8個
八.群發訊息介面——第3步:預覽介面(非必須步驟,但建議保留)
1.意義:為了防止開發者模式下,每月傳送4條訊息的限制,從而導致不滿意訊息的效果現象。
2.官方文件
注意:雖然預覽介面呼叫的次數較多,但是每天有100次的限制,請注意!!!
3.程式碼實現——純文字
function sendMsgAll(){
//1.獲取全域性access_token
$access_token = $this->getWxAccessToken();
$openid="我的openid";
//2.組裝群發預覽介面資料 array
$url = "https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=".$access_token;
$array =array(
'touser'=> $openid, //openid
'text' => array('content' => '雨紛紛,舊故里草木深'), //文字內容
'msgtype' => 'text' //格式
);
//3.將陣列轉成json格式
$postJson = json_encode ( $array );
//4.呼叫第三方介面
$res = $this->https_request( $url ,'post', 'json',$postJson);
return $res;
}
4.程式碼實現——圖文
function sendMsgAllPreview(){
//1.獲取全域性access_token
$access_token = $this->getWxAccessToken();
$openid="我的openid";
$media_id=$this->addNews();
//2.組裝群發預覽介面資料 array
$url = "https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=".$access_token;
$array = array(
"touser" =>$openid,
"mpnews"=>array("media_id"=>$media_id),
"msgtype"=>"mpnews"
);
//3.將陣列轉成json格式
$postJson = json_encode ( $array );
//4.呼叫第三方介面
$res = $this->https_request( $url ,'post', 'json',$postJson);
//dump($res);
return $res;
}
說明
● $openid:此處因為是做預覽,只需要一個ID,獲取有很多種方法。比如之前獲取使用者資訊的時候,可以獲取到openid,或者是測試號的id都可以,只要是合法的openid。
● mpnews:媒體id。需要你之前有上傳過圖文訊息的素材,獲得素材的id。
疑問:我預覽介面是成功的,返回是0,但是沒有官方示例的msg_id...難道改版了?知道的麻煩不吝賜教,謝謝。
2.程式碼實現
//根據標籤進行群發
function sendAllByTag(){
//1.獲取全域性access_token
$access_token = $this->getWxAccessToken();
$url = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=".$access_token;
//2.組裝資料
$media_id=$this->addNews();
$array=array(
'filter' => array( //用於設定圖文訊息的接收者
'is_to_all' => true, //是否向全部使用者傳送,值為true或false,選擇true該訊息群發給所有使用者,選擇false可根據tag_id傳送給指定群組的使用者
'tag_id' =>'', //群發到的標籤的tag_id,參加使用者管理中使用者分組介面,若is_to_all值為true,可不填寫tag_id
),
'mpnews' => array( //用於設定即將傳送的圖文訊息
'media_id' => $media_id, //用於群發的訊息的media_id
),
'msgtype'=> 'mpnews', //群發的訊息型別,圖文訊息為mpnews,文字訊息為text,語音為voice,音樂為music,圖片為image,視訊為video,卡券為wxcard
);
$postJson = json_encode( $array );
$res=$this->https_request( $url ,'post', 'json', $postJson);
//dump($res);
return $res;
}