微信小程序订阅消息

背景

微信小程序的模板消息即将下线,将使用订阅消息。

订阅消息

订阅消息分两种
1.一次性订阅:即想发送一次消息就要用户授权一次。(如果用户勾选了“默认同意,下次不再提醒”,则不再弹窗提醒,但是依然需要走流程触发一次授权)
2.长期长期:授权一次之后,可以发送多次消息。(具体上限没试)

大概逻辑

1.用户在小程序前端完成授权
2.接口发送消息

示例

消息模板
在这里插入图片描述

小程序代码

 /**
   * 订阅消息授权
   */
  subscribeMessage: function () {
    wx.requestSubscribeMessage({
      tmplIds: [
        'JsbOalU4xY8UVLWM3oa8-J1MO6XZbTLwV0Z3-mpUtZE',
        ''
      ],
      success(res) {
        console.log('subscribeMessage success');
        console.log(res);
      },
      fail(res) {
        console.log('subscribeMessage fail');
        console.log(res);
      }
    });
  },

发送消息接口代码subscribe.php

<?php
require_once './curl.php';
class subscribe
{
    /**
     * 微信appid
     * @var string 
     */
    private $appId = '';

    /**
     * 微信appseceret
     * @var string 
     */
    private $appSecret = '';

    /**
     * 订阅消息模板id
     * @var string 
     */
    private $tplId = '';

    /**
     * 接收模板消息用户openid
     * @var string 
     */
    private $toUser = '';

    /**
     * 小程序跳转页面
     * @var string 
     */
    private $page = '';

    /**
     * subscribe constructor.
     * @param $appId
     * @param $appSecret
     * @param $tplId
     * @param $toUser
     * @param $page
     */
    public function __construct($appId, $appSecret, $tplId, $toUser, $page)
    {
        $this->appId = $appId;
        $this->appSecret = $appSecret;
        $this->tplId = $tplId;
        $this->toUser = $toUser;
        $this->page = $page;
    }

    /**
     * 发送模板消息
     * 
     * @param $orderRow
     * @return mixed
     */
    public function sendNotification($orderRow)
    {
        $accessToken = $this->getAccessToken();
        $url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={$accessToken}";
        $postData = array(
            'touser' => $this->toUser,
            'template_id' => $this->tplId,
            'page' => $this->page,
        );

        $data = array(
            'character_string1' => array(
                'value' => $orderRow['order_no']
            ),
            'date3' => array(
                'value' => $orderRow['sch_date'] . " " . $orderRow['sch_time']
            ),
            'thing8' => array(
                'value' => $orderRow['start_station']
            ),
            'thing9' => array(
                'value' => $orderRow['end_station']
            ),
            'thing7' => array(
                'value' => $orderRow['line_name'].'('.$orderRow['ticket_count'].'人'.')'
            )
        );

        $postData['data'] = $data;

        $curl = new CUrl(2);
        $ret = $curl->post($url,json_encode($postData));
        return json_decode($ret,true);
    }


    /**
     * 获取access_token
     * @return string
     */
    public function getAccessToken()
    {
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appId}&secret={$this->appSecret}";
        $curl = new CUrl(2);
        $ret = $curl->get($url);
        $ret = json_decode($ret, true);
        if(isset($ret['errcode'])) {
            return '';

        }else {
            $accessToken = $ret['access_token'];
            return $accessToken;
        }
    }

}

curl请求代码curl.php

<?php

/**
 * CUrl CURL请求类
 *
 * 通过curl实现的快捷方便的接口请求类
 *
 * <br>示例:<br>
 *

 *  // 失败时再重试2次
 *  $curl = new CUrl(2);
 *
 *  // GET
 *  $rs = $curl->get('http://phalapi.oschina.mopaas.com/Public/demo/?service=Default.Index');
 *
 *  // POST
 *  $data = array('username' => 'dogstar');
 *  $rs = $curl->post('http://phalapi.oschina.mopaas.com/Public/demo/?service=Default.Index', $data);

 *
 * @package     PhalApi\CUrl
 * @license     http://www.phalapi.net/license GPL 协议
 * @link        http://www.phalapi.net/
 * @author      dogstar <chanzonghuang@gmail.com> 2015-01-02
 */

class CUrl {

    /**
     * 最大重试次数
     */
    const MAX_RETRY_TIMES = 10;

    /**
     * @var int $retryTimes 超时重试次数;注意,此为失败重试的次数,即:总次数 = 1 + 重试次数
     */
    protected $retryTimes;

    protected $header = array();

    protected $option = array();

    protected $hascookie = FALSE;

    protected $cookie = array();

    /**
     * @param int $retryTimes 超时重试次数,默认为1
     */
    public function __construct($retryTimes = 1) {
        $this->retryTimes = $retryTimes < static::MAX_RETRY_TIMES
            ? $retryTimes : static::MAX_RETRY_TIMES;
    }

    /** ------------------ 核心使用方法 ------------------ **/

    /**
     * GET方式的请求
     * @param string $url 请求的链接
     * @param int $timeoutMs 超时设置,单位:毫秒
     * @return string 接口返回的内容,超时返回false
     */
    public function get($url, $timeoutMs = 3000) {
        return $this->request($url, array(), $timeoutMs);
    }

    /**
     * POST方式的请求
     * @param string $url 请求的链接
     * @param array $data POST的数据
     * @param int $timeoutMs 超时设置,单位:毫秒
     * @return string 接口返回的内容,超时返回false
     */
    public function post($url, $data, $timeoutMs = 3000) {
        return $this->request($url, $data, $timeoutMs);
    }

    /** ------------------ 前置方法 ------------------ **/

    /**
     * 设置请求头,后设置的会覆盖之前的设置
     *
     * @param array $header 传入键值对如:
    ```
     * array(
     *     'Accept' => 'text/html',
     *     'Connection' => 'keep-alive',
     * )
    ```
     *
     * @return $this
     */
    public function setHeader($header) {
        $this->header = array_merge($this->header, $header);
        return $this;
    }

    /**
     * 设置curl配置项
     *
     * - 1、后设置的会覆盖之前的设置
     * - 2、开发者设置的会覆盖框架的设置
     *
     * @param array $option 格式同上
     *
     * @return $this
     */
    public function setOption($option) {
        $this->option = $option + $this->option;
        return $this;
    }

    /**
     * @param array $cookie
     */
    public function setCookie($cookie) {
        $this->cookie = $cookie;
        return $this;
    }

    /**
     * @return array
     */
    public function getCookie() {
        return $this->cookie;
    }

    public function withCookies() {
        $this->hascookie = TRUE;

        if (!empty($this->cookie)) {
            $this->setHeader(array('Cookie' => $this->getCookieString()));
        }
        $this->setOption(array(CURLOPT_COOKIEFILE => ''));

        return $this;
    }

    /** ------------------ 辅助方法 ------------------ **/

    /**
     * 统一接口请求
     * @param string $url 请求的链接
     * @param array $data POST的数据
     * @param int $timeoutMs 超时设置,单位:毫秒
     * @return string 接口返回的内容,超时返回false
     * @throws Exception
     */
    protected function request($url, $data, $timeoutMs = 3000) {
        $options = array(
            CURLOPT_URL                 => $url,
            CURLOPT_RETURNTRANSFER      => TRUE,
            CURLOPT_HEADER              => 0,
            CURLOPT_CONNECTTIMEOUT_MS   => $timeoutMs,
            CURLOPT_HTTPHEADER          => $this->getHeaders(),
        );

        if (!empty($data)) {
            $options[CURLOPT_POST]          = 1;
            $options[CURLOPT_POSTFIELDS]    = $data;
        }

        $options = $this->option + $options; //$this->>option优先

        $ch = curl_init();
        curl_setopt_array($ch, $options);
        $curRetryTimes = $this->retryTimes;
        do {
            $rs = curl_exec($ch);
            $curRetryTimes--;
        } while ($rs === FALSE && $curRetryTimes >= 0);
        $errno = curl_errno($ch);
        if ($errno) {
            throw new InternalServerErrorException(sprintf("%s::%s(%d)\n", $url, curl_error($ch), $errno));
        }

        //update cookie
        if ($this->hascookie) {
            $cookie = $this->getRetCookie(curl_getinfo($ch, CURLINFO_COOKIELIST));
            !empty($cookie) && $this->cookie = $cookie + $this->cookie;
            $this->hascookie = FALSE;
            unset($this->header['Cookie']);
            unset($this->option[CURLOPT_COOKIEFILE]);
        }
        curl_close($ch);

        return $rs;
    }

    /**
     *
     * @return array
     */
    protected function getHeaders() {
        $arrHeaders = array();
        foreach ($this->header as $key => $val) {
            $arrHeaders[] = $key . ': ' . $val;
        }
        return $arrHeaders;
    }

    protected function getRetCookie(array $cookies) {
        $ret = array();
        foreach ($cookies as $cookie) {
            $arr = explode("\t", $cookie);
            if (!isset($arr[6])) {
                continue;
            }
            $ret[$arr[5]] = $arr[6];
        }
        return $ret;
    }

    protected function getCookieString() {
        $ret = '';
        foreach ($this->getCookie() as $key => $val) {
            $ret .= $key . '=' . $val . ';';
        }
        return trim($ret, ';');
    }
}

每种字段的规则

在这里插入图片描述


版权声明:本文为qq_34739614原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。