对于每一个POST请求,开发者在响应包(Get)中返回特定XML结构,对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。请注意,回复图片等多媒体消息时需要预先上传多媒体文件到微信服务器,只支持认证服务号。
今天说说下面三个
1、关注回复
2、自动回复
3、关键字回复
一、关注回复,自动默认回复
所谓关注回复,就是当关注着搜到公众号的时候,点击关注之后,微信返回给用户的信息,具体的实现办法
自动默认回复,就是无论你发送什么信息,如果没有特别处理,系统默认回复的信息。
接收微信的信息和发送信息,都是xml格式的,具体在开发文档中都有具体的说明的,现在就来说说如果实现微信信息的处理和应答。
1、先把预先设置好的回复信息保存到数据库表里面
CREATE TABLE [dbo].[w_reply](
[reply_id] [int] IDENTITY(1,1) NOT NULL,
[reply_text] [varchar](max) NULL,
[reply_type] [varchar](50) NULL,
[article_id] [int] NULL,
[wechat_id] [int] NULL,
[reply_fangshi] [int] NULL,
CONSTRAINT [PK_w_reply] PRIMARY KEY CLUSTERED
(
[reply_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
View Code
wechatapi.aspx页面处理下面信息
2、接收微信发过来的信息
#region 接收微信消息
/// <summary>
/// 接收微信信息
/// </summary>
private void RequestMsg()
{
//接收信息流
Stream requestStream = System.Web.HttpContext.Current.Request.InputStream;
byte[] requestByte = new byte[requestStream.Length];
requestStream.Read(requestByte, 0, (int)requestStream.Length);
//转换成字符串
string requestStr = Encoding.UTF8.GetString(requestByte);
if (!string.IsNullOrEmpty(requestStr))
{
//封装请求类到xml文件中
XmlDocument requestDocXml = new XmlDocument();
requestDocXml.LoadXml(requestStr);
XmlElement rootElement = requestDocXml.DocumentElement;
XmlNode MsgType = rootElement.SelectSingleNode("MsgType");
//将XML文件封装到实体类requestXml中
RequestXml requestXml = new RequestXml();
requestXml.ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText;//开发者微信号
requestXml.FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText;//发送方微信号
requestXml.CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText;//消息发送信息
requestXml.MsgType = MsgType.InnerText;
//获取接收信息的类型
switch (requestXml.MsgType)
{
//接收普通信息
case "text"://文本信息
requestXml.Content = rootElement.SelectSingleNode("Content").InnerText;
break;
case "image"://图片信息
requestXml.PicUrl = rootElement.SelectSingleNode("PicUrl").InnerText;
break;
case "location"://地理位置信息
requestXml.Location_X = rootElement.SelectSingleNode("Location_X").InnerText;
requestXml.Location_Y = rootElement.SelectSingleNode("Location_Y").InnerText;
break;
//接收事件推送
//大概包括有:关注/取消关注事件、扫描带参数二维码事件、上报地理位置事件、自定义菜单事件、点击菜单拉取消息时的事件推送、点击菜单跳转链接时的事件推送
case "event":
requestXml.Event = rootElement.SelectSingleNode("Event").InnerText;
requestXml.EventKey = rootElement.SelectSingleNode("EventKey").InnerText;
break;
}
string selday = "0";
int hh = selday == "0" ? 60 : int.Parse(selday) * 24 * 60;
//将发送方和接收方写入cookie中,后期使用
CookieHelper.WriteCookie("WeChatFrom", "ToUserName", requestXml.ToUserName, hh);
CookieHelper.WriteCookie("WeChatFrom", "FromUserName", requestXml.FromUserName, hh);
//回复消息
ResponseMsg(requestXml);
}
}
#endregion 接收微信消息
View Code
3、回复信息
#region 回复消息(微信信息返回)
/// <summary>
/// 回复消息(微信信息返回)
/// </summary>
/// <param name="weixinXML"></param>
private void ResponseMsg(RequestXml requestXml)
{
string resXml = "";
string WeChat_Key = Request.QueryString["key"];
try
{
DataTable dtWeChat = wechatdal.GetList("wechat_key='" + WeChat_Key + "'").Tables[0];
if (dtWeChat.Rows.Count > 0)
{
replyset.User_ID = dtWeChat.Rows[0]["user_id"].ToString();
replyset.WeChat_ID = dtWeChat.Rows[0]["wechat_id"].ToString();
replyset.WeChat_Type = dtWeChat.Rows[0]["wechat_type"].ToString();
replyset.WeChat_Name = dtWeChat.Rows[0]["wechat_name"].ToString();
switch (requestXml.MsgType)
{
//当收到文本信息的时候回复信息
case "text":
resXml = replyset.GetKeyword(requestXml.FromUserName, requestXml.ToUserName, requestXml.Content);
break;
//当接收推送事件时回复的信息
case "event":
switch (requestXml.Event)
{
//关注的时候回复信息
case "subscribe":
resXml = replyset.GetSubscribe(requestXml.FromUserName, requestXml.ToUserName);
break;
//自定义菜单的时候回复信息
case "CLICK":
resXml = replyset.GetMenuClick(requestXml.FromUserName, requestXml.ToUserName, requestXml.EventKey);
break;
}
break;
}
}
}
catch (Exception ex)
{
Writebug("异常:" + ex.Message + "Struck:" + ex.StackTrace.ToString());
}
//发送xml格式的信息到微信中
Response.Write(resXml);
Response.End();
}
#endregion 回复消息(微信信息返回)
View Code
加载wechatapi.aspx的load时间
protected void Page_Load(object sender, EventArgs e)
{
if (Request.HttpMethod.ToLower() == "post")
{
RequestMsg();
}
else
{
//微信通过get请求验证api接口
CheckWeChat();
}
}
reply.cs
public class replyset
{
public string hostUrl = "http://" + HttpContext.Current.Request.Url.Authority; //域名
public string upfileurl = "http://file.api.weixin.qq.com/cgi-bin/media/upload";
public string baiduImg = "http://api.map.baidu.com/staticimage?center={0},{1}&width=700&height=300&zoom=11";
public string User_ID = "";
public string WeChat_ID = "";
public string WeChat_Type = "";
public string WeChat_Name = "";
w_caidan_dal caidandal = new w_caidan_dal();
w_reply_dal replydal = new w_reply_dal();
w_article_dal articledal = new w_article_dal();
w_keyword_dal keyworddal = new w_keyword_dal();
w_vlimg_dal vlimgdal = new w_vlimg_dal();
w_vlimg_model vlimgmodel = new w_vlimg_model();
w_images_dal imagesdal = new w_images_dal();
common wxCommand = new common();
JsonOperate JsonOperate = new JsonOperate();
JavaScriptSerializer Jss = new JavaScriptSerializer();
public replyset()
{ }
#region 关注回复
/// <summary>
/// 关注的时候回复
/// </summary>
/// <param name="FromUserName"></param>
/// <param name="ToUserName"></param>
/// <returns></returns>
public string GetSubscribe(string FromUserName, string ToUserName)
{
string resXml = "";
string sqlWhere = !string.IsNullOrEmpty(WeChat_ID) ? "WeChat_ID=" + WeChat_ID + " and reply_fangshi=2" : "";
DataTable dtSubscribe = replydal.GetRandomList(sqlWhere, "1").Tables[0];
if (dtSubscribe.Rows.Count > 0)
{
string article_id = dtSubscribe.Rows[0]["article_id"].ToString();
string reply_type = dtSubscribe.Rows[0]["reply_type"].ToString();
string reply_text = dtSubscribe.Rows[0]["reply_text"].ToString();
if (reply_type == "text")
{
resXml = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + reply_text + "]]></Content><FuncFlag>0</FuncFlag></xml>";
}
else
{
resXml = GetArticle(FromUserName, ToUserName, article_id, User_ID);
}
}
return resXml;
}
#endregion 关注回复
#region 自动回复
/// <summary>
/// 自动默认回复
/// </summary>
/// <param name="FromUserName"></param>
/// <param name="ToUserName"></param>
/// <param name="WeChat_ID"></param>
/// <param name="User_ID"></param>
/// <returns></returns>
public string GetDefault(string FromUserName, string ToUserName, string WeChat_ID, string User_ID)
{
string resXml = "";
string sqlWhere = !string.IsNullOrEmpty(WeChat_ID) ? "WeChat_ID=" + WeChat_ID + " and reply_fangshi=1" : "";
//获取保存的默认回复设置信息
DataTable dtDefault = replydal.GetRandomList(sqlWhere, "1").Tables[0];
if (dtDefault.Rows.Count > 0)
{
string article_id = dtDefault.Rows[0]["article_id"].ToString();
string reply_type = dtDefault.Rows[0]["reply_type"].ToString();
string reply_text = dtDefault.Rows[0]["reply_text"].ToString();
//如果选择的是文本
if (reply_type == "text")
{
resXml = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + reply_text + "]]></Content><FuncFlag>0</FuncFlag></xml>";
}
else
{
//返回素材(图文列表)
resXml = GetArticle(FromUserName, ToUserName, article_id, User_ID);
}
}
return resXml;
}
#endregion 默认回复
#region 关键字回复
/// <summary>
/// 关键字回复
/// </summary>
/// <param name="FromUserName"></param>
/// <param name="ToUserName"></param>
/// <param name="Content"></param>
/// <returns></returns>
public string GetKeyword(string FromUserName, string ToUserName, string Content)
{
string resXml = "";
string sqlWhere = "wechat_id=" + WeChat_ID + " and keyword_name='" + Content+"'";
DataTable dtKeyword = keyworddal.GetList(sqlWhere).Tables[0];
if (dtKeyword.Rows.Count > 0)
{
dtKeyword = keyworddal.GetRandomList(sqlWhere, "1").Tables[0];
if (dtKeyword.Rows.Count > 0)
{
string article_id = dtKeyword.Rows[0]["article_id"].ToString();
string keyword_type = dtKeyword.Rows[0]["keyword_type"].ToString();
string keyword_text = dtKeyword.Rows[0]["keyword_text"].ToString();
switch (keyword_type)
{
case "text":
resXml = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + keyword_text + "]]></Content><FuncFlag>0</FuncFlag></xml>";
break;
case "news":
resXml = GetArticle(FromUserName, ToUserName, article_id, User_ID);
break;
}
}
}
else
{
resXml = GetDefault(FromUserName, ToUserName, WeChat_ID, User_ID);
}
return resXml;
}
#endregion 关键字回复
#region 菜单单击
/// <summary>
/// 菜单点击事件回复信息
/// </summary>
/// <param name="FromUserName"></param>
/// <param name="ToUserName"></param>
/// <param name="EventKey"></param>
/// <returns></returns>
public string GetMenuClick(string FromUserName, string ToUserName, string EventKey)
{
string resXml = "";
string sqlWhere = "wechat_id=" + WeChat_ID + " and caidan_key='" + EventKey + "'";
WriteTxt(sqlWhere);
try
{
DataTable dtMenu = caidandal.GetList(sqlWhere).Tables[0];
if (dtMenu.Rows.Count > 0)
{
string article_id = dtMenu.Rows[0]["article_id"].ToString();
string caidan_retype = dtMenu.Rows[0]["caidan_retype"].ToString();
string caidan_retext = dtMenu.Rows[0]["caidan_retext"].ToString();
switch (caidan_retype)
{
case "text":
resXml = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + caidan_retext + "]]></Content><FuncFlag>0</FuncFlag></xml>";
break;
case "news":
resXml = GetArticle(FromUserName, ToUserName, article_id, User_ID);
break;
}
}
}
catch (Exception ex)
{
WriteTxt("异常:" + ex.Message + "Struck:" + ex.StackTrace.ToString());
}
return resXml;
}
#endregion 菜单单击
#region 获取素材
/// <summary>
/// 获取素材
/// </summary>
/// <param name="FromUserName"></param>
/// <param name="ToUserName"></param>
/// <param name="Article_ID"></param>
/// <param name="User_ID"></param>
/// <returns></returns>
public string GetArticle(string FromUserName, string ToUserName, string Article_ID, string User_ID)
{
string resXml = "";
DataTable dtArticle = articledal.GetList("article_id=" + Article_ID + " OR article_layid=" + Article_ID).Tables[0];
if (dtArticle.Rows.Count > 0)
{
resXml = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[news]]></MsgType><Content><![CDATA[]]></Content><ArticleCount>" + dtArticle.Rows.Count + "</ArticleCount><Articles>";
foreach (DataRow Row in dtArticle.Rows)
{
string article_title = Row["article_title"].ToString();
string article_description = Row["article_description"].ToString();
string article_picurl = Row["article_picurl"].ToString();
string article_url = Row["article_url"].ToString();
string article_type = Row["article_type"].ToString();
switch (article_type)
{
case "Content":
article_url = hostUrl + "/web/wechat/api/article.aspx?aid=" + Row["Article_ID"].ToString();
break;
case "Href":
article_url = Row["article_url"].ToString();
break;
}
if (string.IsNullOrEmpty(article_url))
{
article_url = hostUrl + "/web/wechat/api/article.aspx?aid=" + Row["Article_ID"].ToString();
}
article_url += (article_url.IndexOf("uid=") > -1 ? "" : (article_url.IndexOf("?") > -1 ? "&" : "?") + "uid=" + User_ID);
article_url += (article_url.IndexOf("wxid=") > -1 ? "" : (article_url.IndexOf("?") > -1 ? "&" : "?") + "wxid=" + FromUserName);
article_url += (article_url.IndexOf("wxref=") > -1 ? "" : (article_url.IndexOf("?") > -1 ? "&" : "?") + "wxref=mp.weixin.qq.com");
resXml += "<item><Title><![CDATA[" + article_title + "]]></Title><Description><![CDATA[" + article_description + "]]></Description><PicUrl><![CDATA[" + article_picurl + "]]></PicUrl><Url><![CDATA[" + article_url + "]]></Url></item>";
}
resXml += "</Articles><FuncFlag>1</FuncFlag></xml>";
}
return resXml;
}
#endregion 获取图文列表
#region 通用方法
/// <summary>
/// unix时间转换为datetime
/// </summary>
/// <param name="timeStamp"></param>
/// <returns></returns>
private DateTime UnixTimeToTime(string timeStamp)
{
DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
long lTime = long.Parse(timeStamp + "0000000");
TimeSpan toNow = new TimeSpan(lTime);
return dtStart.Add(toNow);
}
/// <summary>
/// datetime转换为unixtime
/// </summary>
/// <param name="time"></param>
/// <returns></returns>
private int ConvertDateTimeInt(System.DateTime time)
{
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
return (int)(time - startTime).TotalSeconds;
}
/// <summary>
/// 记录bug,以便调试
/// </summary>
/// <returns></returns>
public bool WriteTxt(string str)
{
try
{
FileStream fs = new FileStream(HttpContext.Current.Server.MapPath("Log/wxbugLog.txt"), FileMode.Append);
StreamWriter sw = new StreamWriter(fs);
//开始写入
sw.WriteLine(str);
//清空缓冲区
sw.Flush();
//关闭流
sw.Close();
fs.Close();
}
catch (Exception)
{
return false;
}
return true;
}
#endregion 通用方法
}
}
View Code
二、关键字回复
关键字的回复也很简单,我们先把对应的关键字和返回的信息都设置好,然后根据接收的信息中是否存在设置好的关键词来返回对应的信息即可
1、设置关键词(这里就不在多说了)
2、接收信息和回复信息前面也说到了,在这里只把关键词回复判断的方法贴出来供大家参考一下
#region 关键字回复
/// <summary>
/// 关键字回复
/// </summary>
/// <param name="FromUserName"></param>
/// <param name="ToUserName"></param>
/// <param name="Content"></param>
/// <returns></returns>
public string GetKeyword(string FromUserName, string ToUserName, string Content)
{
string resXml = "";
string sqlWhere = "wechat_id=" + WeChat_ID + " and keyword_name='" + Content+"'";
DataTable dtKeyword = keyworddal.GetList(sqlWhere).Tables[0];
if (dtKeyword.Rows.Count > 0)
{
dtKeyword = keyworddal.GetRandomList(sqlWhere, "1").Tables[0];
if (dtKeyword.Rows.Count > 0)
{
string article_id = dtKeyword.Rows[0]["article_id"].ToString();
string keyword_type = dtKeyword.Rows[0]["keyword_type"].ToString();
string keyword_text = dtKeyword.Rows[0]["keyword_text"].ToString();
switch (keyword_type)
{
case "text":
resXml = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + keyword_text + "]]></Content><FuncFlag>0</FuncFlag></xml>";
break;
case "news":
resXml = GetArticle(FromUserName, ToUserName, article_id, User_ID);
break;
}
}
}
else
{
resXml = GetDefault(FromUserName, ToUserName, WeChat_ID, User_ID);
}
return resXml;
}
#endregion 关键字回复
View Code
其他还有很多图片回复,二维码扫描回复信息等都大同小异,处理方式都差不多,参考开发文档很快就能搞定,这里就不在多说了,不明白的地方在讨论。