一、登录微信公众号平台,进行模板消息设置
(1)URL:https://mp.weixin.qq.com/ , 扫描登录
扫码进入之后,如下图所示:
(2)进行模板消息的设置
点击左边的 新的功能,如下所示:
在这里可以使用订阅通知模板,也可以使用模板消息,我这里使用模板消息如下所示:
再点击查看功能,就可以看见你添加的历史模板:
如果你需要添加模板,点击 类目模板和从类目模板中添加,如下图所示:
我这里就只添加了服务类目中的商业服务->软件/建站/技术开发,里面有各种模板,你可以自由选择合适自己的模板,如下所示:
在这里你还可以添加类目,如下所示:
至此,在微信公众号上进行模板添加的步骤已经完成,大家可以参考,详细添加可以看看官方介绍。
二、通过微信公众号的AppID与AppSecret 获取AccessToken、openid及unionid,因为在后面构建请求的url与temp中会使用到
参考微信官方给出的请求方法(非常重要与详细,建议大家好好看一下):https://developers.weixin.qq.com/doc/channels/API/basics/getaccesstoken.html
//Requests为一个通用的get或post请求方法,RequestUrl为请求的地址,RequestMethod请求的get或post
public static string Requests(string RequestUrl, string RequestMethod)
{
string RequestUrls = RequestUrl;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(RequestUrls);
request.Method = RequestMethod;
request.ContentType = "textml;charset=UTF-8";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
string jsonData = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close();
string jsonString = jsonData;
return jsonString;
}
private static void Get(object source, ElapsedEventArgs e)
{
//通过AppID与AppSecret 获取AccessToken
string AppID = "XXXXXXX";
string AppSecret = "XXXXXXX";
string AccessTokenUrl = String.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", AppID, AppSecret); //接口地址构建
string AccessToken = Requests(AccessTokenUrl, "get");//请求方法为get
JObject json1 = JObject.Parse(AccessToken);
//Console.WriteLine(json1["access_token"]); //打印获取的access_token
//通过AccessToken 获取openid
string OpenidUrl = String.Format("https://api.weixin.qq.com/cgi-bin/user/get?access_token={0}", json1["access_token"]);//接口地址构建
string OpenidList = Requests(OpenidUrl, "get");//请求方法为get
JObject json2 = JObject.Parse(OpenidList);
//Console.WriteLine(json2["data"]["openid"]); //打印获取的openid
//通过AccessToken与openid 获取unionid(由于获取的openid很多,是一个list形式,因此遍历循环请求每一个openid获取它相应的unionid)
for (int i = 0; i < json2["data"]["openid"].Count(); i++)
{
string UserInfoUrl = String.Format(" https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang=zh_CN", json1["access_token"], json2["data"]["openid"][i]);//接口地址构建
string UserInfo = Requests(UserInfoUrl, "get");//请求方法为get
JObject json3 = JObject.Parse(UserInfo);
Console.WriteLine(json3["unionid"] + "+" + json2["data"]["openid"][i]);
}
}
三、推送代码的构建
推送的相关参数构造和接口详情,参考官方:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html#6
定时到每天上午的9点30分进行代码的执行
private static void SendTemplateMessage(object source, ElapsedEventArgs e)
{
if (DateTime.Now.Hour == 9 && DateTime.Now.Minute == 30)
{
DataTable dt1 = new DataTable();
string sql1 = " select XXXX from XXXX"; //数据库中获取数据,进行判断是否符合推送要求
string str1 = GlobalFunction.selectDB(sql1, ref dt1);
for (int i = 0; i < dt1.Rows.Count; i++)
{
DateTime start = Convert.ToDateTime(DateTime.Now);
DateTime end = Convert.ToDateTime(dt1.Rows[i]["XXXX"]);
TimeSpan sp = end.Subtract(start);
if (sp.Days == 30) //判断两个时间是否相差30天,如果正好等于30天就进行推送
{
string strReturn = "";
try
{
//获取 access_token
string AppID = "XXXXXXXX";
string AppSecret = "XXXXXXXX";
string AccessTokenUrl = String.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", AppID, AppSecret);//构建请求的url,获取access_token
string AccessToken = Requests(AccessTokenUrl, "get");
JObject json1 = JObject.Parse(AccessToken);
var accessToken = json1["access_token"];
//获取推送者的 openid
DataTable dt2 = new DataTable();
string sql2 = " select XXXX from XXXX U1 inner join XXXX U2 on U1.WxUnionId=U2.UnionId"
+ " where XXXX";
string str2 = GlobalFunction.selectDB(sql2, ref dt2);
for (int j = 0; j < dt2.Rows.Count; j++)
{
string openId = dt2.Rows[j]["WxOpenId"].ToString();
string templateId = "XXXXXX"; //设置的模板ID
string url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
//设置推送的模板,包括推送的openid、模板ID-templateId 、推送的信息:dt1.Rows[i]["XXX"]等
string temp = "{\"touser\": \"" + openId + "\"," +
"\"template_id\": \"" + templateId + "\", " +
"\"topcolor\": \"#FF0000\", " +
"\"data\": " +
"{\"thing3\": {\"value\": \""+ dt1.Rows[i]["XXX"] +"\"}," +
"\"thing11\": { \"value\": \""+ dt1.Rows[i]["XXX"] + "\"}," +
"\"thing4\": { \"value\": \""+ dt1.Rows[i]["XXX"] + "\"}," +
"\"time20\": {\"value\": \"" + Convert.ToDateTime(dt1.Rows[i]["XXX"]) + "\" }}}";
//核心:进行推送请求,并返回相应的反馈信息,如:{"errcode":0,"errmsg":"ok","msgid":XXXXX}
string results = GetResponseData(temp, url);
strReturn = dt1.Rows[i]["UserName"]+"——"+ openId + "——" + "推送成功";
Console.WriteLine(strReturn);
}
}
catch (Exception ex)
{
strReturn = ex.Message;
Console.WriteLine(strReturn);
}
}
else
{
Console.WriteLine(String.Format("目前距离推送时间还有{0}天,当前时间是--{1}",sp.Days, DateTime.Now));
}
}
}
else
{
Console.WriteLine(String.Format("未到数据推送时间,当前时间是--{0}", DateTime.Now));
}
}
//获取请求的数据并返回相应的提示信息
public static string GetResponseData(string JSONData, string Url)
{
byte[] bytes = Encoding.UTF8.GetBytes(JSONData);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
request.Method = "POST";
request.ContentLength = bytes.Length;
request.ContentType = "json";
Stream reqstream = request.GetRequestStream();
reqstream.Write(bytes, 0, bytes.Length);
//声明一个HttpWebRequest请求
request.Timeout = 90000;
//设置连接超时时间
request.Headers.Set("Pragma", "no-cache");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream streamReceive = response.GetResponseStream();
Encoding encoding = Encoding.UTF8;
StreamReader streamReader = new StreamReader(streamReceive, encoding);
string strResult = streamReader.ReadToEnd();
streamReceive.Dispose();
streamReader.Dispose();
return strResult;
}
四、定时推送代码的构建
//设置时间间隔为1分钟执行代码
static void Main(string[] args)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Enabled = true;
timer.Interval = 60000;//执行间隔时间,单位为毫秒;此时时间间隔为1分钟
timer.Start();
timer.Elapsed += new System.Timers.ElapsedEventHandler(SendTemplateMessage);
Console.ReadKey();
}
这是我实现的一个结果:
五、补充
(1)补充1
如果需要点击推送消息跳转到一个网址,只需要在模板里面添加url跳转链接即可。
string temp = "{\"touser\": \"" + openId + "\"," +
"\"template_id\": \"" + templateId + "\", " +
"\"topcolor\": \"#FF0000\", " +
"\"url\": \"https://blog.csdn.net/nfkjdx?spm=1000.2115.3001.5343\", " +
"\"data\": " +
"{\"thing4\": {\"value\": \"XXXXX\"}," +
"\"thing23\": { \"value\": \"XXXXX\"}," +
"\"thing27\": { \"value\": \"XXXXX\"}," +
"\"time32\": {\"value\": \"" + Convert.ToDateTime(DateTime.Now) + "\" }}}";
string results = GetResponseData(temp, url);
(2)补充2
如果需要点击推送消息跳转到一个小程序,需要先去登录推送消息的公众号平台,去里面的小程序管理添加关联的小程序,再去修改推送模板。
var accessToken = "XXXXXXXXX";
string openId = "XXXXXXXXX";
string templateId = "XXXXXXXXX";
string miniprogramAppId = "XXXXXXXXX";//小程序的appid
string microProgramPath = "XXXXXXXXX";//跳转页面的相对路径
string url = "XXXXXXXXX=" + accessToken;
string temp = "{\"touser\": \"" + openId + "\"," +
"\"template_id\": \"" + templateId + "\", " +
"\"topcolor\": \"#FF0000\", " +
"\"miniprogram\":{\"appid\":\"" + miniprogramAppId + "\",\"pagepath\":\"" + microProgramPath.Trim() + "\"},"+
"\"data\": " +
"{\"thing4\": {\"value\": \"XXXXXXXXX\"}," +
"\"thing23\": { \"value\": \"XXXXXXXXX\"}," +
"\"thing27\": { \"value\": \"XXXXXXXXX \"}," +
"\"time32\": {\"value\": \"" + Convert.ToDateTime(DateTime.Now) + "\" }}}";
string results = GetResponseData(temp, url);
参数类别 参数说明 参数值限制 说明
thing.DATA 事物 20个以内字符 可汉字、数字、字母或符号组合
number.DATA 数字 32位以内数字 只能数字,可带小数
letter.DATA 字母 32位以内字母 只能字母
symbol.DATA 符号 5位以内符号 只能符号
character_string.DATA 字符串 32位以内数字、字母或符号 可数字、字母或符号组合
time.DATA 时间 24小时制时间格式(支持+年月日),支持填时间段,两个时间点之间用“~”符号连接 例如:15:01,或:2019年10月1日 15:01
date.DATA 日期 年月日格式(支持+24小时制时间),支持填时间段,两个时间点之间用“~”符号连接 例如:2019年10月1日,或:2019年10月1日 15:01
amount.DATA 金额 1个币种符号+10位以内纯数字,可带小数,结尾可带“元” 可带小数
phone_number.DATA 电话 17位以内,数字、符号 电话号码,例:+86-0766-66888866
car_number.DATA 车牌 8位以内,第一位与最后一位可为汉字,其余为字母或数字 车牌号码:粤A8Z888挂
name.DATA 姓名 10个以内纯汉字或20个以内纯字母或符号 中文名10个汉字内;纯英文名20个字母内;中文和字母混合按中文名算,10个字内
phrase.DATA 汉字 5个以内汉字 5个以内纯汉字,例如:配送中
到这里全部介绍完毕,大家可以参考一下!