因项目需要做推送服务。小程序推送太多限制。因此,改为服务号通知。
首先,公众号回调地址在另外的服务器上,获取不到。所以采用的思路是,获取全部用户的openid,存入数据库。(之后做定时,获取新增用户。)
项目主要涉及 消息回复。
当用户回复消息时,进入数据库获取unionid,再取公众号的openid,取到之后再进行推送。
实现步骤:
1.将小程序与公众号绑定(绑定后才可获取unionid),官方文档:小程序与公众号绑定获取unionid
2.通过微信公众号的AppId和AppSecret
获取微信公众号的access_token(7200秒有效) 这边需要自己做缓存
地址:https://api./cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
//获取公众号access_token 2个小时过期public function getAccessToken(){$url = 'https://api./cgi-bin/token?grant_type=client_credential&appid=111&secret=111';$data = $this->httpRequest($url);$access_token = $data['access_token'];//存入缓存$mc = &load_cache('redis');$mc->save('access_token', $access_token, 7200);return $access_token;}
3.通过刚才获取到的access_token去获取所有用户的openId 官方文档:获取公众号用户列表
地址:https://api./cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID
(NEXT_OPENID为超出10000个取10001继续请求,这个会在每次请求后返回的json字符串中有)
4.将所有的openId全部放在一个新的数组中,然后for
循环,循环次数为openId的数组的长度,循环请求每个用户的基本信息
地址:https://api./cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
(第一次,获取全部用户的openid。这边比较耗时,8000个用户,我花了2.5个小时。获取后删除代码,重写为定时代码)
5.定时获取新增用户
//获取公众号全部用户的openidpublic function getPublicUserOpenid(){ini_set('max_execution_time','200');$mc = &load_cache('redis');$access_token =$mc->get('access_token');if (empty($access_token)){$access_token = $this->getAccessToken();}$url = "https://api./cgi-bin/user/get?access_token=$access_token&next_openid=";$data = $this->httpRequest($url);//token失效if ($data['errcode']==40001){$this->getAccessToken();$this->getPublicUserOpenid();}$openidList = $data['data']['openid'];//返回的数据是无序的,只能做数组对比,取出差集,再保存到数据库。$result = $this->AppPublicUserModel->select('','','','','openid');foreach ($result as $item){$List[]=$item['openid'];}//取差集foreach ($openidList as $key => $item) {if (in_array($item, $List, true)) {unset($openidList[$key]);}}foreach ($openidList as $key=>$v){$url = "https://api./cgi-bin/user/info?access_token=$access_token&openid=$v&lang=zh_CN";$userData = $this->httpRequest($url);//两种情况1已关注和0未关注if ($userData['subscribe']==1){$saveData=['openid'=>$userData['openid'],'nickname'=>$userData['nickname'],'unionid'=>$userData['unionid'],'headimg'=>$userData['headimgurl'],];//保存$this->AppPublicUserModel->add($saveData);}}return $this->success('','同步成功');}
6.推送服务号消息。官方文档:公众号发送模版消息
//公众号消息推送public function pushMessages($fid,$name,$msg){//取openid$fData = $this->AppUserModel->get(array('id'=>$fid));$unionId = $fData['unionid'];$openid = $this->AppPublicUserModel->get(array('unionid'=>$unionId))['openid'];$mc = &load_cache('redis');$access_token =$mc->get('access_token');if (empty($access_token)){$access_token = $this->getAccessToken();}$url = 'https://api./cgi-bin/message/template/send?access_token='.$access_token ;$data = ['touser'=>$openid,'template_id'=>'ZK7ZfM3r02Iyv-xe4UoaBPt9FmjJ4jzC9k-cASM3M84','url' => '','miniprogram' => array('appid'=>'111','pagepath'=>'/pages/message'),'data' => array('first' => array('value' => '你有一条新的消息'),'keyword1' => array('value' => $name),'keyword2' => array('value' => date('Y-m-d H:i:s',time())),'keyword3' => array('value' => $msg),//'remark' => array('value' => '这是备注'),)];$result = $this->httpPostJson($url, urldecode(json_encode($data)));$returnData = json_decode($result[1],1);if ($returnData['errcode']==0){return $this->success('','发送模板消息成功');}else{return $this->fail($returnData['errcode'],'发送模板消息失败');}}
备注:以上内容参考以下地址,侵删
/qq_39687901/article/details/85243514
/p/5a388a5afac7