讀古今文學網 > 微信公眾平台開發:從零基礎到ThinkPHP5高性能框架實踐 > 9.3.2 服務號每日群發 >

9.3.2 服務號每日群發

當前,微信訂閱號默認的群發權限是每天一條,服務號默認的群發權限是每月4條。但通過客服接口可以對48小時內有互動的用戶使用客服接口發送消息。使用這一特性,可以對這些用戶進行群發。

圖9-9 同時使用消息接口和客服接口回復

首先設計一個存儲用戶基本資料的表,其中需要包含用戶的OpenID,以及最後互動的時間記錄。

建表的SQL語句如下。


DROP TABLE IF EXISTS 'wx_user';
CREATE TABLE IF NOT EXISTS 'wx_user' (
    'id' int(11) NOT NULL AUTO_INCREMENT COMMENT '序號',
    'openid' varchar(30) NOT NULL COMMENT '微信id',
    'nickname' varchar(20) CHARACTER SET utf8mb4 NOT NULL COMMENT '暱稱',
    'sex' varchar(4) NOT NULL COMMENT '性別',
    'country' varchar(10) NOT NULL COMMENT '國家',
    'province' varchar(16) NOT NULL COMMENT '省份',
    'city' varchar(16) NOT NULL COMMENT '城市',
    'headimgurl' varchar(200) NOT NULL COMMENT '頭像',
    'heartbeat' varchar(100) NOT NULL COMMENT '最後心跳',
    'subscribe' varchar(15) NOT NULL COMMENT '關注時間',
    PRIMARY KEY ('id'),
    UNIQUE KEY 'openid' ('openid')
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
  

其中,heartbeat字段用於記錄用戶最後的互動時間。

當用戶關注公眾號的時候,將寫入用戶基本信息並將最後的互動時間記錄為關注時間。


 1 // 接收事件消息
 2 private function receiveEvent($object)
 3 {
 4     require_once('class/mysql.class.php');
 5     $db = new class_mysql();
 6     require_once('class/weixin.class.php');
 7     $weixin = new class_weixin();
 8     $openid = strval($object->FromUserName);
 9     $content = "";
10     switch ($object->Event)
11     {
12         case "subscribe":
13             $info = $weixin->get_user_info($openid);
14             $mysql_state = "INSERT INTO 'wx_user' ('id', 'openid', 'nickname', 'sex', 
       'country', 'province', 'city', 'headimgurl', 'heartbeat', 'subscribe') VALUES 
       (NULL, '".$openid."', '".$info['nickname']."', '".$info['sex']."', '".$info
       ['country']."', '".$info['province']."', '".$info['city']."', '".$info['head
       imgurl']."', '".$info['subscribe_time']."', '".$info['subscribe_time']."');";
15             $result = $db->query($mysql_state);
16             $content = "歡迎關注,".$info['nickname'];
17             break;
18         case "unsubscribe":
19             $mysql_state = "DELETE FROM 'wx_user' WHERE 'openid' = '".$openid."';";
20             $result = $db->query($mysql_state);
21             break;
22         default:
23             $content = "receive a new event: ".$object->Event;
24             break;
25     }
26     if(is_array($content)){
27         if (isset($content[0]['PicUrl'])){
28             $result = $this->transmitNews($object, $content);
29         }else if (isset($content['MusicUrl'])){
30             $result = $this->transmitMusic($object, $content);
31         }
32     }else{
33         $result = $this->transmitText($object, $content);
34     }
35     return $result;
36 }
  

上述代碼解讀如下。

第13行:用於獲取用戶的基本信息。

第14~15行:構造用戶信息插入語句並將數據插入數據庫。

第18~21行:取消關注的用戶將刪除記錄。

除了關注和取消關注之外,用戶有其他互動時,將更新用戶最後的互動時間,代碼實現如下。


 1 // 響應消息
 2 public function responseMsg()
 3 {
 4     $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
 5     if (!empty($postStr)){
 6         $this->logger("R ".$postStr);
 7         $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_
           NOCDATA);
 8         $RX_TYPE = trim($postObj->MsgType);
 9 
10         if (($postObj->MsgType == "event") && ($postObj->Event == "subscribe" || 
           $postObj->Event == "unsubscribe")){
11             // 過濾關注和取消關注事件
12         }else{
13             require_once('class/mysql.class.php');
14             $db = new class_mysql();
15             $mysql_state = "UPDATE 'wx_user' SET 'heartbeat' = '".time()."' WHERE 
               'openid' = '".$postObj->FromUserName."';";
16             $result = $db->query($mysql_state);
17         }
18 
19         // 消息類型分離
20         switch ($RX_TYPE)
21         {
22             case "event":
23                 $result = $this->receiveEvent($postObj);
24                 break;
25             case "text":
26                 $result = $this->receiveText($postObj);
27                 break;
28             default:
29                 $result = "unknown msg type: ".$RX_TYPE;
30                 break;
31         }
32         $this->logger("T ".$result);
33         echo $result;
34     }else {
35         echo "";
36         exit;
37     }
38 }
 

上述代碼解讀如下。

第10行:過濾關注和取消關注事件。

第13~16行,更新用戶最後的互動時間,為下面的群發做準備。

接下來獲取48小時內有互動的用戶,實現代碼如下。


1 $mysql_state = "SELECT 'id','openid','heartbeat' FROM 'tp_user' WHERE 'heart
      beat' > ". (time() - 172800);
2 $result = $db->query($mysql_state);
  

上述代碼中,48小時即172800s,將當前時間前移48小時後,再查詢該時間之後的用戶,即可得到48小時內有互動的用戶。

最後對用戶進行群發,實現代碼如下。


 1 $content = array();
 2 $content[] = array("Title"=>"多圖文1標題", "Description"=>"", "PicUrl"=>"http:// 
       discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"http:// m.cnblogs.
       com/?u=txw1958");
 3 $content[] = array("Title"=>"多圖文2標題", "Description"=>"", "PicUrl"=>"http:// 
       d.hiphotos.bdimg.com/wisegame/pic/item/f3529822720e0cf3ac9f1ada0846f21fb
       e09aaa3.jpg", "Url" =>"http:// m.cnblogs.com/?u=txw1958");
 4 $content[] = array("Title"=>"多圖文3標題", "Description"=>"", "PicUrl"=>"http:// 
       g.hiphotos.bdimg.com/wisegame/pic/item/18cb0a46f21fbe090d338acc6a600c3386
       44adfd.jpg", "Url" =>"http:// m.cnblogs.com/?u=txw1958");
 5 
 6 for($j = 0; $j < count($result); $j++)
 7 {
 8     $openid = $result[$j]["openid"];
 9     $result = $weixin->send_custom_message($openid, "news", $content);
10 }
  

上述代碼解讀如下。

第1~4行:構造一個圖文消息,用於群發。

第6~10行:遍歷進行消息發送。

這樣就實現了對48小時內有互動的用戶的群發。