当前位置: 首页 > news >正文

微信小程序结合后端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发送模版消息

前端&#xff1a; <view class"container"><button bindtap"requestSubscribeMessage">订阅消息</button> </view> // index.js Page({data: {tmplIds: [UTgCUfsjHVESf5FjOzls0I9i_FVS1N620G2VQCg1LZ0] // 使用你的模板ID},requ…...

sqlalchemy报错sqlalchemy.orm.exc.DetachedInstanceError

解决方案&#xff1a; 在初始化数据库的代码中&#xff0c;将 maker sessionmaker(bindeng)修改为 maker sessionmaker(bindeng, expire_on_commitFalse)为什么要添加 expire_on_commitFalse 参数&#xff1f; expire_on_commit 可以用来更改 SQLAlchemy 的对象刷新机制&…...

华为网络模拟器eNSP安装部署教程

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

【React】详解样式控制:从基础到进阶应用的全面指南

文章目录 一、内联样式1. 什么是内联样式&#xff1f;2. 内联样式的定义3. 基本示例4. 动态内联样式 二、CSS模块1. 什么是CSS模块&#xff1f;2. CSS模块的定义3. 基本示例4. 动态应用样式 三、CSS-in-JS1. 什么是CSS-in-JS&#xff1f;2. styled-components的定义3. 基本示例…...

【ROS2】高级:安全-理解安全密钥库

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

C语言 ——— 数组指针的定义 数组指针的使用

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

opencascade AIS_ManipulatorOwner AIS_MediaPlayer源码学习

前言 AIS_ManipulatorOwner是OpenCascade中的一个类&#xff0c;主要用于操纵对象的交互控制。AIS_ManipulatorOwner结合AIS_Manipulator类&#xff0c;允许用户通过可视化工具&#xff08;如旋转、平移、缩放等&#xff09;来操纵几何对象。 以下是AIS_ManipulatorOwner的基…...

如何防止用户通过打印功能复制页面文字

简单防白嫖&#xff0c;要让打印出来的页面是空白&#xff0c;通常的做法是在打印时隐藏页面上的所有内容。这可以通过CSS的媒体查询&#xff08;Media Queries&#xff09;来实现&#xff0c;特别是针对media print的查询。 在JavaScript中&#xff0c;你通常不会直接控制打印…...

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 实现监控平台数据可视化大屏(含源码)

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

立创梁山派--移植开源的SFUD和FATFS实现SPI-FLASH文件系统

本文主要是在sfud的基础上进行fatfs文件系统的移植&#xff0c;并不对sfud的移植再进行过多的讲解了哦&#xff0c;所以如果想了解sfud的移植过程&#xff0c;请参考我的另外一篇文章&#xff1a;传送门 正文开始咯 首先我们需要先准备资料准备好&#xff0c;这里对于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&#xff0c;定义主键&#xff0c;姓名不能重名&#xff0c;性别只能输入男或女&#xff0c;所在…...

快速参考:用C# Selenium实现浏览器窗口缩放的步骤

背景介绍 在现代网络环境中&#xff0c;浏览器自动化已成为数据抓取和测试的重要工具。Selenium作为一个强大的浏览器自动化工具&#xff0c;能够与多种编程语言结合使用&#xff0c;其中C#是非常受欢迎的选择之一。在实际应用中&#xff0c;我们常常需要调整浏览器窗口的缩放…...

MyBatis 插件机制、分页插件如何实现的

MyBatis 插件机制允许开发者在 SQL 执行的各个阶段&#xff08;如预处理、执行、结果处理等&#xff09;中插入自定义逻辑&#xff0c;从而实现对 MyBatis 行为的扩展和增强。以下是 MyBatis 插件运行原理的详细介绍&#xff1a; 插件接口 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工作性价比计算器

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

Linux:基础命令学习

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

遇到Websocket就不会测了?别慌,学会这个Jmeter插件轻松解决....

websocket 是一种双向通信协议&#xff0c;在建立连接后&#xff0c;websocket服务端和客户端都能主动向对方发送或者接收数据&#xff0c;而在http协议中&#xff0c;一个request只能有一个response&#xff0c;而且这个response也是被动的&#xff0c;不能主动发起。 websoc…...

高性能 Java 本地缓存 Caffeine 框架介绍及在 SpringBoot 中的使用

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

Http 和 Https 的区别(图文详解)

在现代网络通信中&#xff0c;保护数据的安全性和用户的隐私是至关重要的。HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和 HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是两种常见的网络通信协议&#xff0c;但它们在数据保护方面的能力存在…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构

React 实战项目&#xff1a;微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇&#xff01;在前 29 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...

【51单片机】4. 模块化编程与LCD1602Debug

1. 什么是模块化编程 传统编程会将所有函数放在main.c中&#xff0c;如果使用的模块多&#xff0c;一个文件内会有很多代码&#xff0c;不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里&#xff0c;在.h文件里提供外部可调用函数声明&#xff0c;其他.c文…...