微信小程序发送订阅消息-一次订阅,一直发送消息。

实现思路

长期订阅要求太高,需要政府、公共交通等单位才有资格,所以只能使用一次性订阅。

就像是买奶茶,下单以后,会弹出让用户订阅消息那种。

以买奶茶为例:

用户第一次下单成功,点击了订阅消息。(一般都有三个,可能有什么新品发售、订单完成等等消息)

商家小程序就可以给用户发送一次消息。

用户过几天又点了一杯奶茶,下单成功,有点击了订阅消息。商家就可以再发一次。

但是这种就比较麻烦,不可以重复多次发送。

并且我们公司现在需要多次主动给用户发送通知。

所以就这么做的:

用户点击小程序里面的某个tab,切换的时候,会弹出窗询问是否订阅消息。

用户同意订阅并且勾选了左下角的以后总是默认订阅的选项

用户哪天再点击了这个tab,就不会弹窗了,订阅次数自动+1.

这么做的前提是,用户必须同意订阅并且还要勾选那个"总是默认订阅"的选项。

这么做并不适合一些场景,因为按照常理来说,就是需要每次用户都同意才行。我们这么做就等于用户第一次同意,后面就默认的帮用户选择了。但是公司内部员工用的小程序。不在乎这些。

注意:

  1. 一次订阅就等于可以发送一次消息!
  2. 用户订阅必须是用户主动触发!不可以在打开小程序的时候,就立马弹出窗口询问是否订阅消息!
  3. 用户第一次必须勾选左下角总是默认订阅选项,不然无法在代码里给用户悄悄的加订阅次数!

附加php发送小程序订阅消息代码:

php 复制代码
<?php
class WechatNotification
{
    // 微信小程序配置
    private $miniProgramConfig = [
        'appId' => '',          // 小程序APPID
        'appSecret' => '',      // 小程序APPSECRET
        'templateIds' => []     // 小程序消息模板ID
    ];

    // 缓存的access_token
    private $accessTokens = [
        'miniProgram' => null,
        'workWechat' => null,
        'workWechatExpires' => 0,
        'miniProgramExpires' => 0
    ];

    /**
     * 构造函数,初始化配置
     * @param array $config 配置数组
     */
    public function __construct($config = [])
    {
        if (!empty($config['miniProgram'])) {
            $this->miniProgramConfig = array_merge($this->miniProgramConfig, $config['miniProgram']);
        }
    }


    /**
     * 获取微信小程序access_token
     * @return string|bool
     */
    private function getMiniProgramAccessToken()
    {
        $now = time();
        if ($this->accessTokens['miniProgram'] && $this->accessTokens['miniProgramExpires'] > $now) {
            return $this->accessTokens['miniProgram'];
        }

        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->miniProgramConfig['appId']}&secret={$this->miniProgramConfig['appSecret']}";
        $result = $this->httpRequest($url);
        if (isset($result['access_token'])) {
            $this->accessTokens['miniProgram'] = $result['access_token'];
            $this->accessTokens['miniProgramExpires'] = $now + $result['expires_in'] - 300; // 提前5分钟过期
            return $result['access_token'];
        }

        return false;
    }


    /**
     * 发送微信小程序订阅消息
     * @param string $openid 用户openid
     * @param string $templateId 模板ID
     * @param array $data 模板数据
     * @param string $page 点击模板卡片跳转页面
     * @return array
     */
    public function sendMiniProgramMessage($openid, $templateId, $data, $page = '')
    {
        $accessToken = $this->getMiniProgramAccessToken();
        if (!$accessToken) {
            return ['success' => false, 'error' => '获取access_token失败'];
        }

        $url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={$accessToken}";

        $postData = [
            'touser' => $openid,
            'template_id' => $templateId,
            'data' => $data
        ];

        if (!empty($page)) {
            $postData['page'] = $page;
        }

        $result = $this->httpRequest($url, 'POST', $postData);

        if (isset($result['errcode']) && $result['errcode'] == 0) {
            return ['success' => true, 'data' => $result];
        }

        return ['success' => false, 'error' => $result['errmsg'] ? $result['errmsg'] : '发送失败', 'errcode' => $result['errcode'] ? $result['errcode'] : -1];
    }


    /**
     * HTTP请求工具
     * @param string $url 请求URL
     * @param string $method 请求方法
     * @param array $data 请求数据
     * @return array|bool
     */
    private function httpRequest($url, $method = 'GET', $data = [])
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        if (strtoupper($method) == 'POST') {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Content-Type: application/json'
            ]);
        }

        $response = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);

        if ($error) {
            return false;
        }

        return json_decode($response, true);
    }

}

// 快速格式化打印
function dd($data)
{
    echo '<pre>';
    var_dump($data);
    die;
}




// 以下为测试代码


// 配置参数 (请替换为您自己的实际配置)
$config = [
    'miniProgram' => [
        'appId' => '',      // 微信小程序APPID
        'appSecret' => '',  // 微信小程序APPSECRET
        'templateIds' => [
            'test' => '',  // 消息模板ID
        ]
    ],
];

// 初始化通知类
$notification = new WechatNotification($config);

// 辅助函数:打印测试结果
function printResult($title, $result) {
    echo "===== {$title} =====\n";
    if ($result['success']) {
        echo "状态:成功\n";
        echo "返回数据:" . print_r($result['data'], true) . "\n";
    } else {
        echo "状态:失败\n";
        echo "错误信息:{$result['error']}\n";
        if (isset($result['errcode'])) echo "错误代码:{$result['errcode']}\n";
        if (isset($result['code'])) echo "错误代码:{$result['code']}\n";
    }
    echo "\n";
}

echo '<pre>';
1. 测试发送微信小程序通知
echo "开始测试微信小程序通知...\n";
$miniProgramResult = $notification->sendMiniProgramMessage(
   '',  // 测试用户的openid
   $config['miniProgram']['templateIds']['test'],  // 模板ID
   [
       // 模板数据,需根据您的实际模板字段进行调整
       'name2' => ['value' => '的飞'],
       'thing6' => ['value' => '有新任务包待接收!'],
       'time8' => ['value' => date('Y-m-d H:i:s')],
       'time9' => ['value' => date('Y-m-d H:i:s')],
   ],
   '/pages/index/index'  // 点击跳转页面
);
printResult("微信小程序通知测试", $miniProgramResult);
相关推荐
码农水水17 小时前
京东Java面试被问:HTTP/2的多路复用和头部压缩实现
java·开发语言·分布式·http·面试·php·wpf
_童年的回忆_19 小时前
【PHP】关于守护进程报错:SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
开发语言·oracle·php
edisao20 小时前
六、 读者高频疑问解答 & 架构价值延伸
大数据·开发语言·人工智能·科技·架构·php
catchadmin20 小时前
Laravel12 + Vue3 的免费可商用 PHP 管理后台 CatchAdmin V5.1.0 发布 新增 AI AGENTS 配置
开发语言·php
漏刻有时1 天前
微信小程序学习实录14:微信小程序手写签名功能完整开发方案
学习·微信小程序·notepad++
运筹vivo@1 天前
攻防世界:Web_php_unserialize
前端·web安全·php
说私域1 天前
全民电商时代下的链动2+1模式与S2B2C商城小程序:社交裂变与供应链协同的营销革命
开发语言·人工智能·小程序·php·流量运营
莫桐1 天前
微信小程序tab模块滚动至顶部导航栏置顶效果实现
微信小程序·小程序
sheji34161 天前
【开题答辩全过程】以 基于微信小程序健康跑平台的设计与实现为例,包含答辩的问题和答案
微信小程序·小程序
catchadmin1 天前
2026 年 PHP 函数式编程 优势与实际应用
数据库·php