通过服务号模板消息推送小程序业务事件

这个这个方法不需要小程序和公众号绑到一个开放平台。小程序内展示带参数的服务号二维码,用户扫码后利用关公众号的关注推送来绑定小程序用户和公众号openid.

1.生成带参数的公众号二维码:

    /**
     * 生成代参数的服务号二维码
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getWechatImageV2()
    {
        $path = 'uploads/a/';
        $file = $this->auth->id . '.png';
        /* if (file_exists(ROOT_PATH . DS . 'public' . DS . $path . DS . $file)) {
             $this->success('成功', '/' . $path . $file);
         }*/
        //此处更换公众号的id和密匙
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx38b************04&secret=8804*****************aaedb4d1';
        $res = file_get_contents($url);
        $res = json_decode($res,true);
        $access_token = $res['access_token'];
        $expire_seconds = 0;
        $data = [];
        $scene = (string)$this->auth->id;
        if (is_integer($scene)) { // 二维码场景类型
            $data = ['action_info' => ['scene' => ['scene_id' => $scene]]];
        } else {
            $data = ['action_info' => ['scene' => ['scene_str' => $scene]]];
        }
        if ($expire_seconds > 0) { // 临时二维码
            $data['expire_seconds'] = $expire_seconds;
            $data['action_name'] = is_integer($scene) ? 'QR_SCENE' : 'QR_STR_SCENE';
        } else { // 永久二维码
            $data['action_name'] = is_integer($scene) ? 'QR_LIMIT_SCENE' : 'QR_LIMIT_STR_SCENE';
        }
        $data = json_encode($data);
        $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=$access_token";
        $res3 =  Http::post($url, $data);
        $res3 = json_decode($res3,true);
        $url2 = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket='.$res3['ticket'];
        $content = file_get_contents($url2); // 得到二进制图片内容
        file_put_contents($path . $file, $content); // 写入文件
        $new_path = '/' . $path . $file;
        $this->success('成功', ['file'=>$new_path]);
    }

2.在小程序内引导用户扫码绑定接收推送的服务号。

3.处理微信服务器的消息推送,记得完善服务号后台——服务器配置——服务器url,我用的是明文方式代码如下:

    /**
     * 关注消息通知
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getMsg()
    {
        // 读取微信推送的原始XML数据
        $xmlData = file_get_contents('php://input');
        $xml = simplexml_load_string($xmlData, 'SimpleXMLElement', LIBXML_NOCDATA);
        $data = json_decode(json_encode((array)$xml), true);

        // 验证服务器配置时直接返回echostr
        $echostr = $this->request->get('echostr', '');
        if (!empty($echostr)) {
            exit($echostr);
        }
        Log::info(json_encode($data));
        // 处理事件推送
        if (isset($data['Event'])) {
            $event = $data['Event'];
            $openid = $data['FromUserName'] ?? '';
            $toUser = $data['ToUserName'] ?? '';

            // 初始化场景值
            $sceneValue = '';

            // 处理关注事件(包含扫码关注)
            if ($event == 'subscribe') {
                // 扫码关注时EventKey带有qrscene_前缀
                $eventKey = $data['EventKey'] ?? '';
                if (!empty($eventKey) && strpos($eventKey, 'qrscene_') === 0) {
                    $sceneValue = substr($eventKey, 8); // 移除qrscene_前缀
                }
                // 关注事件统一发送欢迎消息
                $welcomeText = "感谢您的关注!\n这里是您的专属服务!";
            }elseif ($event == 'SCAN') {// 处理已关注用户扫码事件
                $sceneValue = $data['EventKey'] ?? '';
                // 已关注用户扫码发送提示消息
                $welcomeText = "扫码成功!\n您的操作已生效!";
            }
            $responseContent = $this->buildTextResponse($openid, $toUser, $welcomeText);
            // 当场景值有效时处理用户绑定
            if (!empty($sceneValue)) {
                // 场景值即用户ID(与二维码生成逻辑一致)
                $userId = $sceneValue;

                // 查询用户记录
                $user = \app\admin\model\User::find($userId);

                if ($user) {
                    // 更新微信openid(添加事务锁避免并发问题)
                    $user->startTrans();
                    try {
                        $user->wxopen_id = $openid;
                        $user->save();
                        $user->commit();
                    } catch (\Exception $e) {
                        $user->rollback();
                        // 记录日志
                        Log::error("微信绑定失败: {$e->getMessage()} UserID:{$userId}");
                    }
                } else {
                    Log::error("无效的场景值: {$sceneValue}");
                }
            }
            exit($responseContent);
        }else{
            exit('');
        }
    }

    /**
     * 构建文本消息响应XML
     * @param string $fromUser 接收方OpenID
     * @param string $toUser   发送方(公众号ID)
     * @param string $content  消息内容
     * @return string
     */
    private function buildTextResponse($fromUser, $toUser, $content)
    {
        return <<
  
  
  {time()}
  
  

XML;
    }

4.服务号后台——广告与服务——模板消息处申请模板

通过服务号模板消息推送小程序业务事件_第1张图片

调用接口推送消息

use EasyWeChat\Factory;
    public function send(){
        //推送消息
        $user_info = \app\common\model\User::where('id',15)->find();
        if(!empty($user_info->wxopen_id)){
            $send['touser'] = $user_info->wxopen_id;
            $send['template_id'] = 'isAIBEYeFYai33MVHxQRZbhZmaEJPYwEV-19WyMPlXo';
            $send['url'] = '';
            $send['data']['thing1'] = '消费券订单';
            $send['data']['thing2'] = $user_info->nickname;
            $send['data']['phone_number3'] = $user_info->mobile;
            //发布优惠券用户的信息
            $coupons_user_info = \app\common\model\User::where('id',15)->find();
            if(!empty($coupons_user_info)){
                $send['data']['thing22'] = $coupons_user_info->nickname;
                $send['data']['phone_number23'] = $coupons_user_info->mobile;
            }
            sendMsg($send);
        }
    }

function sendMsg($send)
{
    $data = ['app_id' => 'wx38*******904', 'secret' => '8804************edb4d1'];
    $app = Factory::officialAccount($data);
    $res = $app->template_message->send($send);
}

你可能感兴趣的:(小程序)