第一完整看一下微信官方的文档
链接:开发前必读 / 首页 (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 模板消息的基本逻辑 就结束了,再根据需要自己修改就好。