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

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

首先,公众号回调地址在另外的服务器上,获取不到。所以采用的思路是,获取全部用户的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

 

### 实现微信小程序公众号推送模板消息 为了实现从小程序公众号的模板消息推送,整个流程涉及多个环节。首先,在服务器端需准备必要的接口来处理来自前端的请求并调用微信API完成实际的消息发送操作。 #### 准备工作 确保拥有合法的应用凭证(`appid`, `appsecret`),这些信息用于换取访问令牌(`access_token`),这是发起任何微信公众平台HTTP API调用的前提条件[^2]。 #### 获取Access Token 使用应用凭证中的`appid`和`appsecret`通过GET方法请求如下URL以获得`access_token`: ```http https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET ``` 响应数据中会包含一个有效的`access_token`字符串以及过期时间戳。 #### 构建消息体 构建待发送的信息结构,这通常包括接收者OpenID (`touser`)、模板ID (`template_id`)、点击链接后的跳转路径(`url`)或关联的小程序页面(`miniprogram`)以及其他自定义字段如颜色设置等。对于具体的数据部分,则可以参照Spring Boot项目里的`TemplateData`类实例化相应对象填充所需内容[^3]。 ```java // 创建模板数据项 TemplateData first = new TemplateData("尊敬的用户", "#173177"); TemplateData keyword1 = new TemplateData(orderNumber, null); ... Map<String, Object> data = Maps.newHashMap(); data.put("first", first); data.put("keyword1", keyword1); ... ``` #### 发送消息 准备好以上各项之后就可以组装成最终POST请求载荷并向指定URL发出HTTPS POST请求了: ```json { "touser": "OPENID", "template_id": "TEMPLATE_ID", "page": "index", "form_id": "FORM_ID", "data": { ... } } ``` 目标URL为: ```http https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN ``` 成功执行上述步骤后即完成了由微信小程序触发至同主体下的服务号/订阅号的一次模板消息通知过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值