使用微信公众号模板消息发送,能够在用户操作网站时对指定用户发送消息提示,不仅能够及时反馈,还能用户一个好的体验,还可以节约短息推送的成本;
下面是比较重要的部分我做了一个截取展示,详细接口介绍请移步到, 微信官网地址:https://mp.weixin.qq.com/wiki获得模板ID,从行业模板库选择模板到帐号后台,获得模板ID的过程可在微信公众平台后台完成。为方便第三方开发者,提供通过接口调用的方式来
获取模板ID,具体如下:
接口调用请求说明 http请求方式: POST
https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=ACCESS_TOKEN
POST数据说明
POST数据示例如下:
{
"template_id_short":"TM00015"
}
参数说明
参数是否必须说明access_token是接口调用凭证template_id_short是模板库中模板的编号,有“TM**”和“OPENTMTM**”等形式
返回码说明 在调用模板消息接口后,会返回JSON数据包。正常时的返回JSON数据包示例:
{
"errcode":0,
"errmsg":"ok",
"template_id":"Doclyl5uP7Aciu-qZ7mJNPtWkbkYnWBWVja26EGbNyk"
}
发送模板消息 接口调用请求说明 http请求方式: POST
https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN
POST数据说明
POST数据示例如下:
{
"touser":"OPENID",
"template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
"url":"http://weixin.qq.com/download",
"miniprogram":{
"appid":"xiaochengxuappid12345",
"pagepath":"index?foo=bar"
},
"data":{
"first": {
"value":"恭喜你购买成功!",
"color":"#173177"
},
"keynote1":{
"value":"巧克力",
"color":"#173177"
},
"keynote2": {
"value":"39.8元",
"color":"#173177"
},
"keynote3": {
"value":"2014年9月22日",
"color":"#173177"
},
"remark":{
"value":"欢迎再次购买!",
"color":"#173177"
}
}
}
参数说明
参数是否必填说明touser是接收者openidtemplate_id是模板IDurl否模板跳转链接miniprogram否跳小程序所需数据,不需跳小程序可不用传该数据appid是所需跳转到的小程序appid(该小程序appid必须与发模板消息的公众号是绑定关联关系)pagepath是所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar)data是模板数据
注:url和miniprogram都是非必填字段,若都不传则模板无跳转;若都传,会优先跳转至小程序。开发者可根据实际需要选择其中一种跳转方式即可。当用户的微信客户端版本不支持跳小程序时,将会跳转至url。返回码说明 在调用模板消息接口后,会返回JSON数据包。正常时的返回JSON数据包示例:
{
"errcode":0,
"errmsg":"ok",
"msgid":200228332
}
下面是我利用.NET实现的关键代码(注:这只是实现会员注册成功后的信息推送模板,其他模板相同处理)
调用方式,如下:
string strJSON = WeixinTemplateHelper.GetJoinMember(weiXinAccount.User.Userid, weiXinAccount.UserName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), SiteConfigManager.GetConfigStringByKey("weixinH5Domain"));//这里是获取数据库中保存的模板信息组装成接口需要发送的格式
if (strJSON != "")
{
WeixinTemplateHelper.SendMessage(strJSON);//调用微信接口发送
}
组装为微信标准格式的信息
///组装为微信标准格式的信息
public static string GetJoinMember(long UserID, string MemberNO, string JoinTime, string Url = "")
{
string UserAccount = "";
if (IsWeiXinUser(UserID, ref UserAccount))//获取用户在微信中OpeId信息
{
WeiXinMsgConfig model = new WeiXinMsgConfigBLL().GetModelByTemplateNO(WeixinTemplateType.ChengWeiHuiYuan);//这里我是将自定义模板信息保存到数据的,后台做了一个管理,这个方法是获取我配置的推送消息模板
if (model.IsSend == 0)
{
return "";
}
var obj = new
{
touser = UserAccount,
template_id = model.TemplateID,
url = Url,
topcolor = "#FF0000",
data = new
{
first = new { value = model.TemplateFirst, color = "#173177" },
keyword1 = new { value = MemberNO, color = "#173177" },
keyword2 = new { value = JoinTime, color = "#173177" },
remark = new { value = model.TemplateRemark, color = "#173177" }
}
};
return obj.GetJsonByObj();
}
else
{
return "";
}
}
发送组装的信息给指定的用户
//发送组装的信息给指定的用户
public static string SendMessage(string JsonData)
{
try
{
HttpClientHelper httpclient = new HttpClientHelper();
string strUrl = string.Format(CommonUtilities.H5Constants.WeixinApi.WeiXinSendMessage, GetAccess_Token(appid, appsecret));//根据微信的接口请求组装相应的路径
string strResult = httpclient.SendPostRequest(strUrl, JsonData);//通过Post请求访问接口
return WebHelper.ParseFormJson<SendMessageResult>(strResult).errmsg;//获取返回信息
}
catch (Exception ex)
{
return ex.Message;
}
}
获取微信的Access_Token
//获取微信的Access_Token
public static string GetAccess_Token(string appID, string appSecret)
{
//if (appID == appid && appSecret == appsecret && access_token != "" && (DateTime.Now - access_token_time).Seconds < 7000)
//{
//}
//else
//{
DataRow dr = new DeveloperInfoDAL().GetDeveloperInfo(CommonUtilities.DataBase.DataFactory.CreateDataBase());//这是获取保存在数据中微信公众号的appID和appSecret
appid = dr != null ? dr["AppId"].ToString() : "";
appsecret = dr != null ? dr["AppSecret"].ToString() : "";
HttpClientHelper httpclient = new HttpClientHelper();
httpclient.Url = string.Format(CommonUtilities.H5Constants.WeixinApi.WeixinMenuGetAccessToken, appID, appSecret);//组装获取Access_Token的接口访问路径
string strResult = httpclient.GetString();//采用GET请求访问接口
access_token = WebHelper.JSONToObject<TokenResult>(strResult).access_token;
access_token_time = DateTime.Now;
//}
return access_token;
}
需要的基础方法的封装实现
/// <summary>
/// 发起一个POST类型的Web请求,并返回响应
/// </summary>
/// <param name="requestUri">请求地址</param>
/// <param name="jsonData">json数据包</param>
/// <returns>响应</returns>
public string SendPostRequest(string requestUri, string jsonData)
{
if (requestUri.IfNull().ToLower().Trim().StartsWith("https"))
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
}
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(requestUri);
byte[] data = Encoding.UTF8.GetBytes(jsonData);
httpWebRequest.Method = "POST";
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.ContentLength = data.Length;
httpWebRequest.KeepAlive = true;
using (var requestStream = httpWebRequest.GetRequestStream())
{
requestStream.Write(data, 0, data.Length);
}
HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
string content = reader.ReadToEnd();
reader.Close();
responseStream.Close();
response.Close();
return content;
}
/// <summary>
/// 发出一次新的请求,并以字节数组形式返回回应的内容
/// 调用此方法会触发StatusUpdate事件
/// </summary>
/// <returns>包含回应主体内容的字节数组</returns>
public byte[] GetBytes()
{
HttpWebResponse res = GetResponse();
int length = (int)res.ContentLength;
MemoryStream memoryStream = new MemoryStream();
byte[] buffer = new byte[0x100];
Stream rs = res.GetResponseStream();
for (int i = rs.Read(buffer, 0, buffer.Length); i > 0; i = rs.Read(buffer, 0, buffer.Length))
{
memoryStream.Write(buffer, 0, i);
OnStatusUpdate(new StatusUpdateEventArgs((int)memoryStream.Length, length));
}
rs.Close();
return memoryStream.ToArray();
}
/// <summary>
/// 发出一次新的请求,以Http头,或Html Meta标签,或DefaultEncoding指示的编码信息对回应主体解码
/// 调用此方法会触发StatusUpdate事件
/// </summary>
/// <returns>解码后的字符串</returns>
public string GetString()
{
byte[] data = GetBytes();
string encodingName = GetEncodingFromHeaders();
if (encodingName == null)
encodingName = GetEncodingFromBody(data);
Encoding encoding;
if (encodingName == null)
encoding = defaultEncoding;
else
{
try
{
encoding = Encoding.GetEncoding(encodingName);
}
catch (ArgumentException)
{
encoding = defaultEncoding;
}
}
return encoding.GetString(data);
}