• 微信小程序模板消息实现(PHP+小程序)


    参考官方文档和部分资料,总结小程序模板消息推送以及相关注意事项,楼主踩过的坑,特来与大家分享。

    一、开发准备:

    1. 在微信公众平台 - 小程序的模板中心申请消息模板

    Laravel
     
    Laravel
     

     二、实现原理:

    文档示例:小程序 + 接口(PHP)

    小程序部分:

    话不多说,先上效果图:

    Laravel
     

     示例代码:

    <form bindsubmit="formSubmit" report-submit='true' >
      <view class="btn-area"><button formType="submit">Submit</button></view>
    </form>
    formSubmit: function (e) {
      console.log('form发生了submit事件,formId为:', e.detail)
      var that = this;
      wx.request({
            url: 'https://api.XXX.com/sendTemplateMessage.api',
            data: {
                  uid: uid,
                  formId: e.detail.formId
            },
            method: 'post',
            header: {'content-type': 'application/x-www-form-urlencoded'}, //使用这种方式后台才能实现获取到数据
            success: function (res) {
              console.log("发送模板:" + res.data)
            }
      })
    

      

    注意事项:

    小程序通 submit 点击事件获 formid 在安卓和 IOS 是不一样的,安卓系统中为 13 位时间戳,而 IOS 系统中为 32 位字符串,在做接口请求时,不需要做额外处理。

                           安卓系统                                                                      

    Laravel
     

                        IOS系统 

    Laravel
     

    PHP 接口部分:
    1. 根据微信公众平台 --  设置  --  消息推送 -- URL (服务器地址),在 PHP 项目配置入口文件,实现请求分发。
    2. 验证入口文件,传递 token 令牌(消息推送的 token),进行 Signature 签名有效性验证,完成之后才能进行消息模板的服务器 URL 地址配置。

    <?php
        define('SS_START_TIME', microtime(true));
        define('RUN_SS', true);
        require '../ss/ss.php';
        $ss = new ss('xcx');
        $ss->execute('xcx', 'valid', 'xcx');
    ?>
    <?php
        // 小程序验证入口文件
        public  function xcx(){
            $type = $token;    //Token(令牌)
            if ($this->checkSignature($type) && isset($_GET['echostr'])){
                echo $_GET['echostr'];
                exit();
            }
        }   
    
        /**
         * 校验微信加密签名
         * [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) bool
         */
        private function checkSignature($type = ''){
            // 微信服务器配置Token
            $token = $type;
    
            // 1.将timestamp,token,nonce按字典序排序
            $timestamp = $_GET['timestamp'];
            $nonce = $_GET['nonce'];
            $signature = $_GET['signature'];
    
            $arr = array($timestamp, $token, $nonce);
            sort($arr, SORT_STRING);
    
            // 2.拼接为字符串并sha1加密
            $tmpStr = implode($arr);
            $tmpStr = sha1($tmpStr);
    
            // 3.与signature对比判断是否来自微信服务器
            if ($tmpStr == $signature){
                return true;
            }else{
                return false;
            }
        }     
    ?>
    

      

    可在 https://mp.weixin.qq.com/debug/ 调试获取 access_token

    Laravel
     

    3. 微信公众平台 - 设置 - 开发设置配置消息推送(需要先将入口文件上传服务器)

    Laravel
     

    4. 在微信公众平台获取相关参数:
    AppID (小程序 ID)、AppSecret (小程序密钥)、Token (令牌)、TemplateId(模板 id)、EncodingAESKey (消息加密密钥)

    4.1  小程序模板接口

    /*
         *小程序模板消息
         *@param uid 用户id
         *$param template_id 模板id
         *@param form_id 表单提交场景下formId(只能用一次)
         *@param emphasis_keyword 消息加密密钥
        */
        public function sendTemplateMessage($uid,$form_id,$template_id){
            // 检验uid合法性 防止非法越界
            $nickname = "nickname";  // 用户昵称
            // 此openid为小程序的openid切勿与微信自动登录的openid混淆
            $xcx_open['openid'] = "用户openid";
            // openid可以通过PHP接口或者小程序获取
            if ($xcx_open['openid']) {
                $temp_msg = array(
                    'touser' => "{$xcx_open['openid']}",
                    'template_id' => "{$template_id}",
                    'page' => "/pages/index/index",
                    'form_id' => "{$form_id}",
                    'data' => array(
                        'keyword1' => array(
                            'value' => "{$nickname}",
                        ),
                        'keyword2' => array(
                            'value' => date('Y-m-d H:i:s', time()),
                        ),
                        'keyword3' => array(
                            'value' => "好友已完成测试,快去看看吧!",
                        ),
                        'keyword4' => array(
                            'value' => "你收到1封新信件,快去看看吧~",
                        ),
                    ),
                    'emphasis_keyword'=> "{$emphasis_keyword}"
                );
                $res = $this->sendXcxTemplateMsg(json_encode($temp_msg));
                echo "<pre>";var_dump($res);exit;
            }
        }

    4.2 发送小程序模板消息

      /**
         * 发送小程序模板消息
         * @param $data
         * [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) array
        */
        public function sendXcxTemplateMsg($data,$appid = "",$appsecret = "")
        {
            // 具体模板格式参考公众平台申请的template_id
            if (!$appid || !$appsecret)
            {
                $appid        = '';    //小程序id
                $appsecret    = '';    //小程序秘钥 
            }
            $access_token = $this->getXcxAccessToken($appid,$appsecret);
            $url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token={$access_token}";
            return $this->http_request($url, $data);
        }

    请求数据格式如下:

    {
      "touser": "OPENID",
      "template_id": "TEMPLATE_ID",
      "page": "index",
      "form_id": "FORMID",
      "data": {
          "keyword1": {
              "value": "339208499"
          },
          "keyword2": {
              "value": "2015年01月05日 12:30"
          },
          "keyword3": {
              "value": "腾讯微信总部"
          } ,
          "keyword4": {
              "value": "广州市海珠区新港中路397号"
          }
      },
      "emphasis_keyword": "keyword1.DATA"
    }

    4.3 获取 access_token

    /**
         * 获取微信接口调用凭证
         * @param string $appid
         * @param string $appsecret
         * [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) mixed
        */
        public function getXcxAccessToken($appid = '', $appsecret = '')
        {
            if (!$appid || !$appsecret)
            {
                $appid        = '';
                $appsecret    = '';
            }
    
            // 缓存获取
            $cache = &factory::cache();
            if (!$cache->get($appid.'xcx_access_token'))
            {
                $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$appsecret}";
                $res = $this->http_request($url);
                // access_token设置到缓存中
                $cache->set($appid.'xcx_access_token', $res['access_token'], 7000);
                return $res['access_token'];
            }
    
            return $cache->get($appid.'xcx_access_token');
        }

    4.4 CURL 模拟 HTTP 请求(POST)`

     /**
         * curl模拟http请求GET/POST
         * @param $url
         * @param null $data
         * [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) array
         */
        public function http_request($url, $data = null)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            // 以文件流形式返回
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    
            if (!empty($data))
            {
                // POST请求
                curl_setopt($ch, CURLOPT_POST, 1);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            }
    
            $output = curl_exec($ch);
            curl_close($ch);
    
            // 返回数组
            return json_decode($output, true);
        }
    

      

    传递参数:根据定义接口传递相关参数,用户 uid  通过 uid 获取 openid,此 openid 为小程序的 openid, formId 为表单提交场景下,为 submit 事件带上的 formId,formid 在安卓和 ios 下的数据格式和长度不一致,而且小程序获取 formid 只支持真机调试。

    接口调试:errcode 的合法值
    值 说明
    40037 template_id 不正确
    41028 form_id 不正确,或者过期
    41029 form_id 已被使用
    41030 page 不正确
    45009 接口调用超过限额(目前默认每个帐号日调用限额为 100 万)
    请求成功:

    {
        "state": 1,
        "data": {
            "errcode": 0,
            "errmsg": "ok"
        },
        "info": "successful!"
    }
    

      

    至此,推送功能完整实现!

  • 相关阅读:
    【Rust】文件操作
    【Rust】转义字符
    【Rust】原始标识符
    【Rust】字节数组
    【Rust】文档测试
    【Rust】外部函数接口
    【Rust】不安全操作
    【Rust】单元测试
    【Rust】集成测试
    WPF之ComboBox 安静点
  • 原文地址:https://www.cnblogs.com/wangsky/p/11229874.html
Copyright © 2020-2023  润新知