net core 微信公众号发送模板消息完整实现

第一完整看一下微信官方的文档

链接:开发前必读 / 首页 (qq.com)

想要发送模板消息分为一下几步

第一步:想要发消息需要有这几个参数,

        openid,这是给谁发消息

        access_token,调用接口必要的

        appid、secret 这两个是生成access_token 的

ok,只要有这几个参数就意味着你就可以发模板消息了,但前提是你在微信公众号平台已经配置好了具体可以参考这篇文章:手把手教你微信公众号如何给指定用户发送消息提醒_微信公众号推送消息-CSDN博客

上面配置过程中需要注意的是,有一个txt文件

这个txt 文件要放到 服务器上,如果服务器找不到这个文件的话例如我这是一个API站,那就要在Program.cs 文件中配置一下

var app = builder.Build();app.UseStaticFiles();

这样才能找到txt文件。

第一步代码如下

	public string SendRemindMsg(string open_id, string msg_title, string redirect_url){try{string access_token = GetAccessToken();string msgid = "";bool IsSuccess = false;string poster = "{\"touser\": \"" + open_id + "\",\"template_id\":\"这里是你的模板id\", "+ "\"url\":\"" + redirect_url + "\","+ "\"data\":{\"first\":{\"value\":\"" + msg_title + "\",\"color\":\"#ff0000\"},"+ "\"thing2\":{\"value\":\"测试\",\"color\":\"#ff0000\"},"+ "\"number3\":{\"value\":\"1\",\"color\":\"#ff0000\"},"+ "\"thing4\":{\"value\":\"测试\",\"color\":\"#ff0000\"},"+ "\"time5\":{\"value\":\"" + DateTime.Now.ToString("yyyy年MM月dd日 HH:mm:ss") + "\",\"color\":\"#ff0000\"},"+ "\"remark\":{\"value\":\"点击这里查看详情。\",\"color\":\"#0000ff\"}"+ " } }";string resultStr = GetPage("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + access_token, poster);dynamic result = JsonConvert.DeserializeObject(resultStr);return resultStr;}catch (Exception e){return e.Message;}}

这就是发送逻辑,需要注意的是poster 中的内容

data中的 thing2、number3、thing4、time5 这些参数是根据平台上配置的模板参数来的

例如 我申请的模板是这样的

详细内容中的参数名就是 上面代码中poster -data 中的参数名

SendRemindMsg() 方法中 用到的基础方法代码如下 GetAccessToken() :

public string GetAccessToken()
{var tokenRecord =  _goodtooth.WeChatToken.FirstOrDefault();if (tokenRecord != null && tokenRecord.Expiration > DateTime.UtcNow){return tokenRecord.AccessToken; // 返回有效的 Token}return GetAccessToken_base(); // 获取新的 Token
}public string GetAccessToken_base()
{JObject objre = new JObject();try{string accesstoken = "";string expiresin = "";string appid = "你公众号平台的appid";string secret = "你公众号平台的secret"; string strResult;string strurl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret + "";try{HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strurl);HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();Stream myStream = HttpWResp.GetResponseStream();StreamReader sr = new StreamReader(myStream, Encoding.UTF8);StringBuilder strBuilder = new StringBuilder();while (-1 != sr.Peek()){strBuilder.Append(sr.ReadLine());}strResult = strBuilder.ToString();}catch{strResult = "err";}JObject obj = (JObject)JsonConvert.DeserializeObject(HttpUtility.UrlDecode(strResult));objre = obj;accesstoken = obj["access_token"].ToString().Replace("\"", "");expiresin = obj["expires_in"].ToString().Replace("\"", "");if (!string.IsNullOrEmpty(accesstoken) && !string.IsNullOrEmpty(expiresin)){var tokenRecord = _goodtooth.WeChatToken.FirstOrDefault();int expin = Convert.ToInt32(expiresin);var expiration = DateTime.UtcNow.AddSeconds(expin);var newTokenRecord = new WeChatToken{AccessToken = accesstoken,Expiration = expiration};// 更新或插入数据库记录if (tokenRecord != null){_goodtooth.WeChatToken.Remove(tokenRecord); // 清除旧记录}_goodtooth.WeChatToken.Add(newTokenRecord);_goodtooth.SaveChanges();return accesstoken;}throw new Exception("Failed to get access token.");}catch (Exception e){return e.Message+ objre;}}public class WeChatToken
{public int Id { get; set; }public string AccessToken { get; set; }public DateTime Expiration { get; set; }
}

这里是用appid和secret 参数获取accesstoken,注意这个接口调用有次数限制具体参加顶部的微信文档,库里建一个表WeChatToken表把AccessToken存上,这个比较关键代码已经完整给出直接沾就行。

GetPage() 方法:直接粘贴就行

public  string GetPage(string posturl, string postData)
{Stream outstream = null;Stream instream = null;StreamReader sr = null;HttpWebResponse response = null;HttpWebRequest request = null;Encoding encoding = Encoding.UTF8;byte[] data = encoding.GetBytes(postData);// 准备请求...  try{// 设置参数  request = WebRequest.Create(posturl) as HttpWebRequest;CookieContainer cookieContainer = new CookieContainer();request.CookieContainer = cookieContainer;request.AllowAutoRedirect = true;request.Method = "POST";request.ContentType = "application/x-www-form-urlencoded";request.ContentLength = data.Length;outstream = request.GetRequestStream();outstream.Write(data, 0, data.Length);outstream.Close();//发送请求并获取相应回应数据  response = request.GetResponse() as HttpWebResponse;//直到request.GetResponse()程序才开始向目标网页发送Post请求  instream = response.GetResponseStream();sr = new StreamReader(instream, encoding);//返回结果网页(html)代码  string content = sr.ReadToEnd();string err = string.Empty;return content;}catch (Exception ex){string err = ex.Message;return string.Empty;}
}

ok把上面代码都粘上,把要填的参数都填上 就能给你配的openid 发送消息了。

那么我问你 openid 怎么来?

第一种 通过授权页面

前台 要有一个页面来让用户进行点击

@{Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>居中显示</title><style>body {display: flex;justify-content: center;align-items: center;height: 100vh; /* 使用视口高度 */margin: 0;}.center-div {width: 300px;height: 200px;background-color: lightblue;}</style>
</head>
<body><div class="center-div"><h1><a href="@ViewBag.shouquanurl">授权</a></h1></div>
</body>
</html>
 public IActionResult ShouQuan(){string url = HttpUtility.UrlEncode("https://apihyb.fuliplat.com/api/SendWeChatMessage/getcode");ViewBag.shouquanurl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的appid&redirect_uri=" + url + "&response_type=code&scope=snsapi_base&state=STATE";return View();}

这里要注意,url,为你后端得地址得一个方法用于接收授权之后返回得code,通过code 就能获取到openid 了,传入openid 给 sendreminmsg 方法 就能发模板消息了。

方法为:

public string getcode()
{var code = HttpContext.Request.Query["code"];string openid = GetOpenId(code);return SendRemindMsg(openid, "消息提醒" , "http://www.baidu.com/");
}public string GetOpenId(string code)
{JObject objre = new JObject();try{string openid = "";string strResult;string appid = "你的appid";string secret = "你的secret";string strurl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + secret + "&code="+ code + "&grant_type=authorization_code";try{HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strurl);HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();Stream myStream = HttpWResp.GetResponseStream();StreamReader sr = new StreamReader(myStream, Encoding.UTF8);StringBuilder strBuilder = new StringBuilder();while (-1 != sr.Peek()){strBuilder.Append(sr.ReadLine());}strResult = strBuilder.ToString();}catch{strResult = "err";}JObject obj = (JObject)JsonConvert.DeserializeObject(HttpUtility.UrlDecode(strResult));objre = obj;openid = obj["openid"].ToString().Replace("\"", "");return openid;}catch (Exception e){return e.Message + objre;}}

ok 以上代码都写好 你就可以在页面上点击 授权 ,你的公众号就能收到模板消息了。

这里点击 查看详情 跳转的是百度页面 就是 上面传参数传得百度地址,可以改为你想要跳转的地址

第二种,用户关注公众号,就发消息

这里要新建一个控制器,用来建立于微信沟通得桥梁 具体参见 顶部微信官方文档

代码完整给出

using GoodToothAPI.Data;
using GoodToothAPI.Models;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;namespace GoodToothAPI.Controllers
{[Route("api/wechat")]public class WeChatController : Controller{private readonly GoodToothConnection _goodtooth;public WeChatController( GoodToothConnection goodtooth){_goodtooth = goodtooth;}private readonly string token = "你自定义的token"; // 在公众号后台设置的token[HttpGet]public IActionResult Validate(string signature, string timestamp, string nonce, string echostr){if (CheckSignature(signature, timestamp, nonce)){return Content(echostr); // 验证成功,返回echostr}return BadRequest();}[HttpPost]public async Task<IActionResult> ReceiveMessage(){using (var reader = new StreamReader(Request.Body)){var xmlString = await reader.ReadToEndAsync(); // 使用异步读取var message = Deserialize<WeChatMessage>(xmlString);// 处理消息switch (message.MsgType){case "event":HandleEvent(message);break;// 其他消息类型的处理}return Ok("Success");}}private T Deserialize<T>(string xmlString){var serializer = new XmlSerializer(typeof(T));using (var reader = new StringReader(xmlString)){return (T)serializer.Deserialize(reader);}}private void HandleEvent(WeChatMessage message){if (message.Event == "subscribe"){// 这个 message.FromUserName 就是 openid// 处理用户关注事件SendWelcomeMessage(message.FromUserName);}}private void SendWelcomeMessage(string openId){// 发送欢迎消息的逻辑// 这里可以调用发送模板消息的APISendWeChatMessageController sendWeChatMessageController = new SendWeChatMessageController(_goodtooth);sendWeChatMessageController.SendRemindMsg(openId, "消息提醒", "http://www.baidu.com/");}private void HandleUnsubscribe(string openId){// 处理用户取消关注的逻辑// 可以记录用户信息等}private bool CheckSignature(string signature, string timestamp, string nonce){var tempList = new List<string> { token, timestamp, nonce };tempList.Sort(); // 字典排序var tempStr = string.Join("", tempList);using (var sha1 = SHA1.Create()){var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(tempStr));var hashString = BitConverter.ToString(hash).Replace("-", "").ToLower();return hashString == signature; // 比较签名}}}[XmlRoot("xml")]public class WeChatMessage{[XmlElement("ToUserName")]public string ToUserName { get; set; }[XmlElement("FromUserName")]public string FromUserName { get; set; }[XmlElement("CreateTime")]public long CreateTime { get; set; }[XmlElement("MsgType")]public string MsgType { get; set; }[XmlElement("Event")]public string Event { get; set; } // 事件类型[XmlElement("Content")]public string Content { get; set; }}
}

这里还要在Program.cs 文件中配置一下

builder.Services.AddControllers().AddXmlSerializerFormatters();

ok这样 就建立起桥梁了,先写好代码发布再去公众号平台配置

在公众号配置的过程中,要注意路由   [Route("api/wechat")] 要一致。

其中的Get 方法Validate() 为固定写法直接粘即可,Get方法生效之后 公众号平台才能配置成功。

Post方法 ReceiveMessage() 为 公众号在有用户关注或者一些列事件 公众号给你 主动发送的 方法

具体要参见微信官方文档,这里仅给出 用户关注 subscribe事件

这样 代码全部粘上 在用户关注后就可以收到模板消息了。

ok 模板消息的基本逻辑 就结束了,再根据需要自己修改就好。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/448921.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何替换OCP节点(二):使用 antman脚本 | OceanBase应用实践

前言&#xff1a; OceanBase Cloud Platform&#xff08;简称OCP&#xff09;&#xff0c;是 OceanBase数据库的专属企业级数据库管理平台。 在实际生产环境中&#xff0c;OCP的安装通常是第一步&#xff0c;先搭建OCP平台&#xff0c;进而依赖OCP来创建、管理和监控我们的生…

开放式蓝牙耳机哪个品牌好用?开放式耳机排行榜测评!

开放式耳机&#xff0c;因其特殊的不入耳佩戴模式&#xff0c;让使用者在享受音乐或者进行通话的过程中&#xff0c;依然可以对外界声音保持敏感。在户外运动场景下&#xff0c;这种特性优势尽显&#xff0c;既保证了耳机佩戴的稳定和舒适&#xff0c;又提高了运动的安全性。为…

如何做好项目管理,实现高效协作?

项目管理难&#xff0c;难于上青天&#xff01; 小卫&#xff0c;某服装生产企业项目经理&#xff0c;说到项目难管理&#xff0c;他有话要说&#xff1a; 做项目&#xff0c;看似简单&#xff0c;不同部门各司其职&#xff0c;但也正因为涉及跨部门协作&#xff0c;管理难度也…

Qt:图片文字转base64程序

目录 一.Base64 1.编码原理 2.应用场景 3.优点 4.限制 5.变种 二.文字与Base64互转 1.ui设计 2.文字转Base64 3.Base64转文字 三.图片与Base64互转 1.ui设计 2.选择图片与图片路径 3.图片转Base64 4.Base64转图片 四.清空设置 五.效果 六.代码 base64conver…

基于SpringBoot+Vue+uniapp的时间管理小程序的详细设计和实现(源码+lw+部署文档+讲解等)

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不…

大厂面试一上来就手撕 Transformer,心凉半截

在这两年&#xff0c;尤其是大模型问世之后&#xff0c;有关 Transformer 的面试题不仅数量众多&#xff0c;而且颇具新意。 今日&#xff0c;我将分享 18 道 Transformer 高频面试题&#xff08;如需获取更多专业面试题&#xff0c;扫描文末二维码即可&#xff09;&#xff0…

关于为什么蒸馏后的小模型和一开始的小模型的区别是什么?

起初&#xff0c;我想写这个博客是因为无意间看到了一个采访&#xff0c;无意间浏览才发现这段说的给我一种恍然大悟的感觉。 主持人提问&#xff1a;训练一个大模型&#xff0c;然后再将其压缩蒸馏成一个小模型&#xff0c;那和直接训练一个小模型&#xff0c; 这两者的区别是…

再Android10上实现检测AHD摄像头是否接入

项目有个需要&#xff0c;需要知道tp9951是否接入AHD摄像头 1&#xff0c;驱动层可以通过读取寄存器的值来检测是否接入AHD摄像头 tp9951_write_reg(0x40, 0x00); //select decoder page tp9951_write_reg(0x41, ch); val tp9951_read_reg(TP_INPUT_STATUS_REG);…

【含文档】基于Springboot+Vue的仓库管理系统设计与实现(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

ZBrush和3D-Coat各自的优缺点是什么?

zbrush支持的模型面数高英文界面&#xff0c;3d coat支持的模型面数比zbrsh低有中文界 ZBrush优缺点 1、ZBrush优点&#xff1a; zbrush是高精度建模poser制作的首选。可搭配雕刻版使用&#xff0c;主要为烘焙高细节的铁图建模。因为是高精度模型&#xff0c;不适用于动画和游…

MySQL【知识改变命运】08

数据库约束 1&#xff1a;约束的几个类型2&#xff1a;NOT NULL非空约束3&#xff1a;UNIQUE 唯⼀约束4&#xff1a;PRIMARY KEY 主键约束4.1:回顾 5&#xff1a;FOREIGN KEY 外键约束5.1&#xff1a;创建班级表(主表)&#xff0c;并初始化数据5.2&#xff1a;重构学⽣表(从表)…

移动云智算平台,斩获两大国际知名设计奖项

近日&#xff0c;移动云一站式智算平台从全球激烈的竞争中脱颖而出&#xff0c;斩获2024年缪斯设计奖与法国设计奖两项国际知名设计大奖。这两大奖项在全球设计与创新领域颇具影响力&#xff0c;致力于表彰来自全球的优秀和原创设计作品。此次获奖&#xff0c;体现了移动云出色…

5. Node.js Http模块

2.4 Http模块 2.4.1创建Http服务端 //1.导入http模块 let http=require(http)//2.创建服务对象 let server=http.createServer((request,response)=>{console.log(request.method) //获取请求方式console.log(request.url) //获取请求url(路径和参数部份…

JavaWeb Servlet--09深入:注册系统04--修改页面

修改页面 分析&#xff1a;点击修改超链接&#xff0c;就跳转到一个修改界面&#xff0c;要显示原本的数据&#xff0c;且密码显示出来&#xff0c;在该页面将对用户的数据的进行修改&#xff0c;最后提交。 开始业务&#xff1a; 1.在web下创建一个修改界面update.jsp 写法…

蓝牙资讯|苹果AirPods Pro 2耳机推送开发者Beta固件

科技媒体 MacRumors 报道&#xff0c;苹果公司邀请开发者&#xff0c;针对 Lightning 和 USB-C 接口的 AirPods Pro 2 耳机&#xff0c;推送了新的 7B5013d 固件版本&#xff0c;较之前的 7B5013c 有所提升。 苹果未来会向所有 AirPods Pro 2 用户推送本次固件更新&#xff0…

基于OpenFOAM和Python的流场动态模态分解:从数据提取到POD-DMD分析

本文探讨了Python脚本与动态模态分解(DMD)的结合应用。我们将利用Python对从OpenFOAM模拟中提取的二维切片数据进行DMD计算。这种方法能够有效地提取隐藏的流动模式,深化对流体动力学现象的理解。 使用开源CFD软件OpenFOAM,有两种方法可以对CFD数据进行DMD计算。第一种方法是直…

外卖平台开发定制全攻略:从选技术到上线运营

随着外卖行业的蓬勃发展&#xff0c;越来越多的餐饮企业希望拥有一个定制化的外卖平台&#xff0c;以便在激烈的市场竞争中脱颖而出。那么&#xff0c;如何从技术选型到平台开发再到上线运营&#xff0c;打造一个适合自身业务的外卖平台&#xff1f;本文将从开发技术、系统架构…

LLM中20种提示词策略

在大型语言模型&#xff08;LLM&#xff09;应用中&#xff0c;Prompt策略是指如何设计输入提示&#xff08;Prompt&#xff09;以引导模型生成期望的输出。以下是一些常见的Prompt策略&#xff1a; 1. 零样本提示&#xff08;Zero-Shot Prompting&#xff09; 描述: 模型在没…

微信小程序-自定义组件

文章目录 微信小程序-自定义组件概述创建和使用数据、方法和属性slot 插槽默认插槽具名插槽 组件样式注意项样式隔离 数据监听组件间通信父传子子传父获取子组件实例 生命周期组件的生命周期组件所在页面的生命周期App、Page与Component生命周期对比冷启动保留当前页面和关闭当…

Hadoop集群基础搭建

目录 一.虚拟机安装 1.配置虚拟机的ip 2.配置本机的ip 3.新建虚拟机 4.克隆三台虚拟机 二.虚拟机网络配置 1.修改ip配置 2.配置主机名和主机映射 3.配置SSH免密登陆 三.安装JDK 1.tar命令解压JDK安装包 2.配置JDK的环境变量 四.安装Hadoop 1.tar命令解压Hadoop安…