小程序用户操作后通过公众号(服务号)推送通知

因项目需要做推送服务。小程序推送太多限制。因此,改为服务号通知。

首先,公众号回调地址在另外的服务器上,获取不到。所以采用的思路是,获取全部用户的openid,存入数据库。(之后做定时,获取新增用户。) 

项目主要涉及 消息回复。

当用户回复消息时,进入数据库获取unionid,再取公众号的openid,取到之后再进行推送。

实现步骤:

1.将小程序与公众号绑定(绑定后才可获取unionid),官方文档:小程序与公众号绑定获取unionid

2.通过微信公众号的AppId和AppSecret
获取微信公众号的access_token(7200秒有效)               这边需要自己做缓存
地址:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

//获取公众号access_token 2个小时过期
    public function getAccessToken()
    {
        $url = 'https://api.weixin.qq.com/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.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID

(NEXT_OPENID为超出10000个取10001继续请求,这个会在每次请求后返回的json字符串中有)

4.将所有的openId全部放在一个新的数组中,然后for循环,循环次数为openId的数组的长度,循环请求每个用户的基本信息

地址:https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

(第一次,获取全部用户的openid。这边比较耗时,8000个用户,我花了2.5个小时。获取后删除代码,重写为定时代码)

5.定时获取新增用户

 //获取公众号全部用户的openid
    public 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.weixin.qq.com/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.weixin.qq.com/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.weixin.qq.com/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'],'发送模板消息失败');
        }

    }

备注:以上内容参考以下地址,侵删

https://blog.csdn.net/qq_39687901/article/details/85243514

https://www.jianshu.com/p/5a388a5afac7

猜你喜欢

转载自blog.csdn.net/chenabin_/article/details/88029791