天天看點

PHP微信公衆号開發——群發消息

一.官方文檔

進階群發接口

https://mp.weixin.qq.com/wiki...

二.關于群發接口

1.訂閱号每天可以群發消息一條,服務号每月(自然月)四條的群發權限。開發者模式下,可以通過進階群發接口,實作更靈活的群發能力。

2.注意

● 對于認證訂閱号,群發接口每天可成功調用1次,此次群發可選擇發送給全部使用者或某個标簽;

● 對于認證服務号雖然開發者使用進階群發接口的每日調用限制為100次,但是使用者每月隻能接收4條,無論在公衆平台網站上,還是使用接口群發,使用者每月隻能接收4條群發消息,多于4條的群發将對該使用者發送失敗;

● 具備微信支付權限的公衆号,在使用群發接口上傳、群發圖文消息類型時,可使用a标簽加入外鍊;

● 開發者可以使用預覽接口校對消息樣式和排版,通過預覽接口可發送編輯好的消息給指定使用者校驗效果。

通俗的說就是

● 服務号一個月隻能發四條消息,雖然一個月就四條 但它是即時呈現到客戶眼前 隻要你打開微信就有一條未讀 

● 訂閱号每天一條,但訂閱号所有的商家都在一起顯示,而且不會主動提醒,需要你點開服務号才可以看到

● 一條群發消息裡,是可以包括多條圖文消息。

● 群發的消息不包括商家推送消息等其他消息類型。

如下所示,為京東的服務号消息界面。上面的是群發消息,下面是發貨通知消息。

PHP微信公衆号開發——群發消息

這就是為什麼有的人會疑惑,自己接受來自服務号的消息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

臨時素材與永久素材的不同之處
           
PHP微信公衆号開發——群發消息

4.素材與群發接口的結合使用(以下講解的素材均以永久素材來說明)

第一步:上傳圖檔

前面有提過,上傳圖檔素材分兩種,主要是傳回參數的不同

a.傳回media_id(其實可以同時傳回media_id和url)——文檔名:新增其他類型永久素材

PHP微信公衆号開發——群發消息
PHP微信公衆号開發——群發消息

使用說明

● 傳入參數:全局token和類型type

● 傳回:media_id和url

● 可以根據業務邏輯需求,隻傳回media_id或者做判斷

● 注意:視訊素材的請求連結是不同的

● 使用:URL可以直接放在群發消息之圖文消息中的img标簽,media_id可以用在圖文消息的封面圖檔id。

b.隻傳回URL——文檔名:上傳圖文消息内的圖檔擷取URL

PHP微信公衆号開發——群發消息

使用說明

● 傳入參數:全局token

● 傳回:url

● URL作用:放在圖文消息中使用(使用img标簽)。

c.總結:隻傳回URL和傳回media_id的差別就在于使用地方的不同,當然傳回media_id的方法也可以傳回URL。media_id用于群發圖文消息的封面,url用在文本的Img标簽。

第二步:上傳圖文素材等檔案素材

a.新增永久圖文素材

PHP微信公衆号開發——群發消息

b.上傳圖文消息素材

由于和上面的新增永久圖文素材差異不大,故這裡不做贅述,詳情見第七條。

簡單說明

● thumb_media_id:前面提到的上傳圖檔傳回media_id(也就是“新增其他類型永久素材”)就是用在此處,作為圖文消息的封面圖檔。

● content:前面提到的上傳圖檔2種類型,傳回的URL就是用在此處的img标簽裡。

5.關于“上傳圖文消息素材”和“新增永久圖文素材”的差別

● 上傳圖文消息素材:等于是直接把圖文素材傳到微信的伺服器,每次憑借media_id擷取素材,并且不占用素材庫

● 新增永久圖文素材:在開發者和微信伺服器之間,多了一個素材庫。素材庫的素材有數量限制,但是可以直接檢視到。

四.群發消息接口——第1步:上傳圖檔(傳回URL)

1.說明

● 功能:上傳圖文消息内的圖檔擷取URL【訂閱号與服務号認證後均可用】

● 注意:本接口所上傳的圖檔不占用公衆号的素材庫中圖檔數量的5000個的限制。圖檔僅支援jpg/png格式,大小必須在1MB以下

● 官方文檔參考

PHP微信公衆号開發——群發消息

2.代碼實作

a.思路

● 調用接口

看到後面需要用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協定

● 官方文檔參考

PHP微信公衆号開發——群發消息

● 注意:官方說明,視訊素材需要另外一個表單,這裡暫不做說明。

● 通過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步:上傳圖文之新增永久圖文素材

1.說明

● 接口

https://api.weixin.qq.com/cgi...

PHP微信公衆号開發——群發消息

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"      => ,            //是否顯示封面,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"      => ,            //是否顯示封面,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步:上傳圖文之上傳圖文消息素材

1.說明

● 接口

https://api.weixin.qq.com/cgi...

● 官文說明

PHP微信公衆号開發——群發消息
PHP微信公衆号開發——群發消息

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"      =>             //是否顯示封面,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"      =>             //是否顯示封面,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.官方文檔

PHP微信公衆号開發——群發消息

注意:雖然預覽接口調用的次數較多,但是每天有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...難道改版了?知道的麻煩不吝賜教,謝謝。

PHP微信公衆号開發——群發消息
PHP微信公衆号開發——群發消息

九.群發消息接口——第4步:根據标簽進行群發

1.說明

● 接口

https://api.weixin.qq.com/cgi...

● 官方說明

PHP微信公衆号開發——群發消息
PHP微信公衆号開發——群發消息

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;
    }