这部分调试了很久,因为在新用户扫描了好友分享的二维码之后需要分发两条消息,一条是自动推送给当前用户欢迎的消息,另一条是推送给二维码主人的消息。调试了很久都不能同时分发(也许是我的逻辑或者方法有问题吧【尴尬脸】)。后来去谷歌了一下,好像不能分发两条或者多条消息,只能分发一条消息,所以这部分需要用到客服消息接口。
不多说,先看代码
- 首先要去配置公众号的服务器配置,用于接收微信的推送消息 参考文档(https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140543)
注意:在启用了服务器配置过后,原有的自定义菜单功能等将不能使用了,所以得编写菜单功能,
参考文档(https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013)
public function customMenu(){
//组装菜单数据
$data = ' {
"button":[
{
"type":"click",
"name":"今日歌曲",
"key":"V1001_TODAY_MUSIC"
},
{
"name":"菜单",
"sub_button":[
{
"type":"view",
"name":"搜索",
"url":"http://www.soso.com/"
},
{
"type":"miniprogram",
"name":"wxa",
"url":"http://mp.weixin.qq.com",
"appid":"wx286b93c14bbf93aa",
"pagepath":"pages/lunar/index"
},
{
"type":"click",
"name":"赞一下我们",
"key":"V1001_GOOD"
}]
}]
}';
$access_token = $this->getWeiXinToken();
$url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=$access_token";
$getData = $this->httpPostFunc($url, $data, 'POST');
var_dump($getData);
- 验证消息是否来自微信后台(主要是验证echostr参数)
private $appId;
private $appSecret;
/**
* weChat constructor.
*/
public function __construct() {
parent::__construct();
$this->appId = 'xxxxxxx';
$this->appSecret = 'xxxxxxxx';
$this->load->driver('cache', array('adapter' => 'apc', 'backup' => 'file'));//这里是框架自带的缓存
}
/**
* 参数signature、nonce、timestamp验证消息是否来自微信后台,验证成功时返回echostr给微信后台服务器,已确定接口配置成功
*/
public function index(){
define("TOKEN", "xxxx");
$echostr = $this->input->get('echostr',true);
if (!$echostr) {
$this->responseMsg();
}else{
$this->valid();
}
}
private function valid(){
$echoStr = $_GET["echostr"];
if($this->checkSignature()){
echo $echoStr;
exit;
}
}
/**
* 验证签名
* @return bool
*/
private function checkSignature(){
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}
3.消息推送方法responseMsg,
private function responseMsg(){
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
if (!empty($postStr)){
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$TYPE = trim($postObj->MsgType);
$EventKey = trim((string)$postObj->EventKey);
$keyArray = explode("_", $EventKey);
if (count($keyArray) && count($keyArray) != 1) {//扫好友分享的二维码关注,未关注者关注后推送事件
$getContent = $this->getAndSaveUserInfo($postObj, $keyArray[1]);//拿到用户的openId和userId,再拿到用户的详细信息,并将个人微信信息保存至数据库
}
switch ($TYPE)
{
case "text":
$resultStr = $this->receiveText($postObj);
break;
case "event":
if($postObj->EventKey == 'V1001_wap_create_1'){//点击生成二维码图片
$resultStr = $this->receiveText($postObj);
}else{
$resultStr = $this->receiveEvent($postObj);
}
if($getContent){//是否新关注者,并调用客服接口给二维码主人发送消息
$this->replyCustomer($getContent['openId'], $getContent['content']);
}
break;
default:
$resultStr = "";
break;
}
echo $resultStr;
}else {
echo "";
exit;
}
}
4.在方法receiveText和receiveEvent中主要是组装xml数据,主要请参考文档(https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140453)
方法replyCustomer主要是给二维码主人或者其他人发消息,参考文档(https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140547)
private function replyCustomer($touser,$content){
$access_token = $this->getWeiXinToken();;
$data = '{
"touser":"'.$touser.'",
"msgtype":"text",
"text":
{
"content":"'.$content.'"
}
}';
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$access_token ;
$result = $this->httpPostFunc($url, $data, 'POST');
$data = json_decode($result);
return $data;
}
这是这个方法发的消息