当前,微信订阅号默认的群发权限是每天一条,服务号默认的群发权限是每月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小时内有互动的用户的群发。