微信小程序结合后端php发送模版消息
前端:
<view class="container"><button bindtap="requestSubscribeMessage">订阅消息</button>
</view>
// index.js
Page({data: {tmplIds: ['UTgCUfsjHVESf5FjOzls0I9i_FVS1N620G2VQCg1LZ0'] // 使用你的模板ID},requestSubscribeMessage() {const tmplIds = this.data.tmplIds;if (wx.requestSubscribeMessage) {// 使用基础库 2.4.4 及以上版本wx.requestSubscribeMessage({tmplIds: tmplIds,success: (res) => {// 处理订阅消息成功的结果console.log('Subscribe message success:', res);// 遍历结果,检查用户是否同意订阅for (let tmplId of tmplIds) {if (res[tmplId] === 'accept') {console.log(`Template ID ${tmplId} subscription accepted.`);} else {console.log(`Template ID ${tmplId} subscription denied or filtered.`);}}},fail: (err) => {// 处理订阅消息失败的结果console.error('Subscribe message failed:', err);},complete: () => {// 接口调用结束console.log('RequestSubscribeMessage complete');}});} else {// 兼容低版本wx.showModal({title: '提示',content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'});}},onLoad() {// 页面加载时的逻辑}
});
后端:php7.4
/*function getWeChatToken($appid, $secret) {$url = "https://api.weixin.qq.com/cgi-bin/token";$params = http_build_query(['grant_type' => 'client_credential','appid' => $appid,'secret' => $secret,]);$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url . '?' . $params);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // 忽略 SSL 证书验证curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true); // 忽略 SSL 证书验证$response = curl_exec($ch);if (curl_errno($ch)) {echo 'cURL Error: ' . curl_error($ch);return null;}curl_close($ch);return json_decode($response, true);
}// 替换为你的 AppID 和 AppSecret
$appid = '';
$secret = '';$tokenInfo = getWeChatToken($appid, $secret);if ($tokenInfo && isset($tokenInfo['access_token'])) {echo 'Access Token: ' . $tokenInfo['access_token'];$accessToken = $tokenInfo['access_token'];
} else {echo 'Failed to get access token. Response: ' . json_encode($tokenInfo);
}*/function sendSubscribeMessage($accessToken, $templateId, $touser, $data, $page = '', $miniprogramState = 'formal', $lang = 'zh_CN') {$url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=$accessToken";$postData = json_encode(['touser' => $touser,'template_id' => $templateId,'page' => $page,'data' => $data,'miniprogram_state' => $miniprogramState,'lang' => $lang,]);$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 忽略 SSL 证书验证curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 忽略 SSL 证书验证$response = curl_exec($ch);if (curl_errno($ch)) {echo 'cURL Error: ' . curl_error($ch);return null;}curl_close($ch);return json_decode($response, true);
}// 替换为你的 AccessToken, TemplateID, Touser, 和 Data
$accessToken = 'your_access_token_here'; // 请替换为实际的 access token
$templateId = 'UTgCUfsjHVESf5FjOzls0I9i_FVS1N620G2VQCg1LZ0';
$touser = 'oCmkd7cO3vjwvHhLUtjDJwklvLOE';
$data = ['time1' => ['value' => '2024-7-25 12:23:25'],'amount2' => ['value' => '128'],'thing3' => ['value' => '黑金卡'],'thing4' => ['value' => '24小时内发货'],'character_string5' => ['value' => '202407251236962365']
];
$page = 'index?foo=bar'; // 可选
$miniprogramState = 'formal'; // 可选,默认 'formal'
$lang = 'zh_CN'; // 可选,默认 'zh_CN'$response = sendSubscribeMessage($accessToken, $templateId, $touser, $data, $page, $miniprogramState, $lang);if ($response && isset($response['errcode'])) {if ($response['errcode'] == 0) {echo 'Message sent successfully!';} else {echo 'Failed to send message. Error code: ' . $response['errcode'] . ', Error message: ' . $response['errmsg'];// 根据错误码提供解决方案switch ($response['errcode']) {case 40001:echo ' - 获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口。';break;case 40003:echo ' - 不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID。';break;case 40014:echo ' - 不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口。';break;case 40037:echo ' - 不合法的 template_id。';break;case 43101:echo ' - 用户未订阅消息。检查订阅弹窗回调结果或事件推送确认是否订阅成功,检查是否一次性订阅的次数之前已下发完。';break;case 43107:echo ' - 订阅消息能力封禁。检查账号是否被封禁订阅消息能力,检查模板id对应的模板是否被封禁。';break;case 43108:echo ' - 并发下发消息给同一个粉丝。检查是否有同时下发多个消息给同一粉丝的情况。';break;case 45168:echo ' - 命中敏感词。检查下发消息中是否带有敏感词。';break;case 47003:echo ' - 参数错误。根据wiki文档检查data结构格式是否正确,检查各个关键词是否满足对应规则。';break;default:echo ' - 未知错误,请参考微信公众平台文档。';break;}}
} else {echo 'Failed to send message. Invalid response.';
}
php8.0及以上版本
function sendSubscribeMessage(string $accessToken,string $templateId,string $touser,array $data,string $page = '',string $miniprogramState = 'formal',string $lang = 'zh_CN'
): ?array {$url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=$accessToken";$postData = json_encode(['touser' => $touser,'template_id' => $templateId,'page' => $page,'data' => $data,'miniprogram_state' => $miniprogramState,'lang' => $lang,]);$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 忽略 SSL 证书验证curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 忽略 SSL 证书验证$response = curl_exec($ch);if (curl_errno($ch)) {echo 'cURL Error: ' . curl_error($ch);return null;}curl_close($ch);return json_decode($response, true);
}// 替换为你的 AccessToken, TemplateID, Touser, 和 Data
$accessToken = 'your_access_token_here'; // 请替换为实际的 access token
$templateId = 'UTgCUfsjHVESf5FjOzls0I9i_FVS1N620G2VQCg1LZ0';
$touser = 'oCmkd7cO3vjwvHhLUtjDJwklvLOE';
$data = ['time1' => ['value' => '2024-7-25 12:23:25'],'amount2' => ['value' => '128'],'thing3' => ['value' => '黑金卡'],'thing4' => ['value' => '24小时内发货'],'character_string5' => ['value' => '202407251236962365']
];
$page = 'index?foo=bar'; // 可选
$miniprogramState = 'formal'; // 可选,默认 'formal'
$lang = 'zh_CN'; // 可选,默认 'zh_CN'$response = sendSubscribeMessage($accessToken, $templateId, $touser, $data, $page, $miniprogramState, $lang);if ($response && isset($response['errcode'])) {if ($response['errcode'] === 0) {echo 'Message sent successfully!';} else {echo 'Failed to send message. Error code: ' . $response['errcode'] . ', Error message: ' . $response['errmsg'];// 根据错误码提供解决方案match ($response['errcode']) {40001 => print(' - 获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口。'),40003 => print(' - 不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID。'),40014 => print(' - 不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口。'),40037 => print(' - 不合法的 template_id。'),43101 => print(' - 用户未订阅消息。检查订阅弹窗回调结果或事件推送确认是否订阅成功,检查是否一次性订阅的次数之前已下发完。'),43107 => print(' - 订阅消息能力封禁。检查账号是否被封禁订阅消息能力,检查模板id对应的模板是否被封禁。'),43108 => print(' - 并发下发消息给同一个粉丝。检查是否有同时下发多个消息给同一粉丝的情况。'),45168 => print(' - 命中敏感词。检查下发消息中是否带有敏感词。'),47003 => print(' - 参数错误。根据wiki文档检查data结构格式是否正确,检查各个关键词是否满足对应规则。'),default => print(' - 未知错误,请参考微信公众平台文档。'),};}
} else {echo 'Failed to send message. Invalid response.';
}
thinkphp8+easywechat6.0 在php8.3下的测试,测试成功
declare (strict_types = 1);namespace app\index\controller;use EasyWeChat\MiniApp\Application;class Msg
{public function index(){$config = ['app_id' => '', // 请填写小程序的appId'secret' => '', // 请填写小程序的appsecret'token' => 'easywechat','aes_key' => '','http' => ['throw' => true, // 状态码非 200、300 时是否抛出异常,默认为开启'timeout' => 5.0,'retry' => true, // 使用默认重试配置],];$app = new Application($config);$accessToken = $app->getAccessToken();$access_token = $accessToken->getToken(); // string// return $access_token;$api = $app->getClient();$data = ['time1' => ['value' => '2024-7-25 12:23:25'],'amount2' => ['value' => '128'],'thing3' => ['value' => '黑金卡'],'thing4' => ['value' => '24小时内发货'],'character_string5' => ['value' => '202407251236962365']];$response = $api->postJson('/cgi-bin/message/subscribe/send?access_token='.$access_token, ['touser' => 'oCmkd7cO3vjwvHhLUtjDJwklvLOE','template_id' => 'UTgCUfsjHVESf5FjOzls0I9i_FVS1N620G2VQCg1LZ0','data' => $data]);return $response->getContent();}
}
返回的数据为json
{"errcode": 0,"errmsg": "ok","msgid": 3563045918154752007
}
相关文章:
微信小程序结合后端php发送模版消息
前端: <view class"container"><button bindtap"requestSubscribeMessage">订阅消息</button> </view> // index.js Page({data: {tmplIds: [UTgCUfsjHVESf5FjOzls0I9i_FVS1N620G2VQCg1LZ0] // 使用你的模板ID},requ…...
sqlalchemy报错sqlalchemy.orm.exc.DetachedInstanceError
解决方案: 在初始化数据库的代码中,将 maker sessionmaker(bindeng)修改为 maker sessionmaker(bindeng, expire_on_commitFalse)为什么要添加 expire_on_commitFalse 参数? expire_on_commit 可以用来更改 SQLAlchemy 的对象刷新机制&…...

华为网络模拟器eNSP安装部署教程
eNSP是图形化网络仿真平台,该平台通过对真实网络设备的仿真模拟,帮助广大ICT从业者和客户快速熟悉华为数通系列产品,了解并掌握相关产品的操作和配置、提升对企业ICT网络的规划、建设、运维能力,从而帮助企业构建更高效࿰…...

【React】详解样式控制:从基础到进阶应用的全面指南
文章目录 一、内联样式1. 什么是内联样式?2. 内联样式的定义3. 基本示例4. 动态内联样式 二、CSS模块1. 什么是CSS模块?2. CSS模块的定义3. 基本示例4. 动态应用样式 三、CSS-in-JS1. 什么是CSS-in-JS?2. styled-components的定义3. 基本示例…...

【ROS2】高级:安全-理解安全密钥库
目标:探索位于 ROS 2 安全密钥库中的文件。 教程级别:高级 时间:15 分钟 内容 背景安全工件位置 公钥材料 私钥材料域治理政策 安全飞地 参加测验! 背景 在继续之前,请确保您已完成设置安全教程。 sros2 包可以用来创…...

C语言 ——— 数组指针的定义 数组指针的使用
目录 前言 数组指针的定义 数组指针的使用 前言 之前有编写过关于 指针数组 的相关知识 C语言 ——— 指针数组 & 指针数组模拟二维整型数组-CSDN博客 指针数组 顾名思义就是 存放指针的数组 那什么是数组指针呢? 数组指针的定义 何为数组指针…...

opencascade AIS_ManipulatorOwner AIS_MediaPlayer源码学习
前言 AIS_ManipulatorOwner是OpenCascade中的一个类,主要用于操纵对象的交互控制。AIS_ManipulatorOwner结合AIS_Manipulator类,允许用户通过可视化工具(如旋转、平移、缩放等)来操纵几何对象。 以下是AIS_ManipulatorOwner的基…...
如何防止用户通过打印功能复制页面文字
简单防白嫖,要让打印出来的页面是空白,通常的做法是在打印时隐藏页面上的所有内容。这可以通过CSS的媒体查询(Media Queries)来实现,特别是针对media print的查询。 在JavaScript中,你通常不会直接控制打印…...

Python3网络爬虫开发实战(3)网页数据的解析提取
文章目录 一、XPath1. 选取节点2. 查找某个特定的节点或者包含某个指定的值的节点3. XPath 运算符4. 节点轴5. 利用 lxml 使用 XPath 二、CSS三、Beautiful Soup1. 信息提取2. 嵌套选择3. 关联选择4. 方法选择器5. css 选择器 四、PyQuery1. 初始化2. css 选择器3. 信息提取4. …...

基于 HTML+ECharts 实现监控平台数据可视化大屏(含源码)
构建监控平台数据可视化大屏:基于 HTML 和 ECharts 的实现 监控平台的数据可视化对于实时掌握系统状态、快速响应问题至关重要。通过直观的数据展示,运维团队可以迅速发现异常,优化资源配置。本文将详细介绍如何利用 HTML 和 ECharts 实现一个…...

立创梁山派--移植开源的SFUD和FATFS实现SPI-FLASH文件系统
本文主要是在sfud的基础上进行fatfs文件系统的移植,并不对sfud的移植再进行过多的讲解了哦,所以如果想了解sfud的移植过程,请参考我的另外一篇文章:传送门 正文开始咯 首先我们需要先准备资料准备好,这里对于fatfs的…...
MySQL之视图和索引实战
1.新建数据库 mysql> create database myudb5_indexstu; Query OK, 1 row affected (0.01 sec) mysql> use myudb5_indexstu; Database changed 2.新建表 1.学生表student,定义主键,姓名不能重名,性别只能输入男或女,所在…...

快速参考:用C# Selenium实现浏览器窗口缩放的步骤
背景介绍 在现代网络环境中,浏览器自动化已成为数据抓取和测试的重要工具。Selenium作为一个强大的浏览器自动化工具,能够与多种编程语言结合使用,其中C#是非常受欢迎的选择之一。在实际应用中,我们常常需要调整浏览器窗口的缩放…...
MyBatis 插件机制、分页插件如何实现的
MyBatis 插件机制允许开发者在 SQL 执行的各个阶段(如预处理、执行、结果处理等)中插入自定义逻辑,从而实现对 MyBatis 行为的扩展和增强。以下是 MyBatis 插件运行原理的详细介绍: 插件接口 MyBatis 插件通过实现 org.apache.i…...

CentOS6.0安装telnet-server启用telnet服务
CentOS6.0安装telnet-server启用telnet服务 一步到位 fp"/etc/yum.repos.d" ; cp -a ${fp} ${fp}.$(date %0y%0m%0d%0H%0M%0S).bkup echo [base] nameCentOS-$releasever - Base baseurlhttp://mirrors.163.com/centos-vault/6.0/os/$basearch/http://mirrors.a…...

H5+CSS+JS工作性价比计算器
工作性价比=平均日新x综合环境系数/35 x(工作时长+通勤时长—0.5 x摸鱼时长) x学历系数 如果代码中的公式不对,请指正 效果图 源代码 <!DOCTYPE html> <html> <head> <style> .calculator { width: 300px; padd…...

Linux:基础命令学习
目录 一、ls命令 实例:-l以长格式显示文件和目录信息 实例:-F根据文件类型在列出的文件名称后加一符号 实例: -R 递归显示目录中的所有文件和子目录。 实例: 组合使用 Home目录和工作目录 二、目录修改和查看命令 三、mkd…...

遇到Websocket就不会测了?别慌,学会这个Jmeter插件轻松解决....
websocket 是一种双向通信协议,在建立连接后,websocket服务端和客户端都能主动向对方发送或者接收数据,而在http协议中,一个request只能有一个response,而且这个response也是被动的,不能主动发起。 websoc…...

高性能 Java 本地缓存 Caffeine 框架介绍及在 SpringBoot 中的使用
在现代应用程序中,缓存是一种重要的性能优化技术,它可以显著减少数据访问延迟,降低服务器负载,提高系统的响应速度。特别是在高并发的场景下,合理地使用缓存能够有效提升系统的稳定性和效率。 Caffeine 是一个高性能的…...

Http 和 Https 的区别(图文详解)
在现代网络通信中,保护数据的安全性和用户的隐私是至关重要的。HTTP(Hypertext Transfer Protocol)和 HTTPS(Hypertext Transfer Protocol Secure)是两种常见的网络通信协议,但它们在数据保护方面的能力存在…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...