asp.net微信开发(消息应答)
程序员文章站
2023-12-21 17:59:41
当普通微信用户向公众账号发消息时,微信服务器将post消息的xml数据包到开发者填写的url上。
请注意:
1、关于重试的消息排重,推荐使用msgid排重。...
当普通微信用户向公众账号发消息时,微信服务器将post消息的xml数据包到开发者填写的url上。
请注意:
- 1、关于重试的消息排重,推荐使用msgid排重。
- 2、微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。详情请见“发送消息-被动回复消息”。
- 3、为了保证更高的安全保障,开发者可以在公众平台官网的开发者中心处设置消息加密。开启加密后,用户发来的消息会被加密,公众号被动回复用户的消息也需要加密(但开发者通过客服接口等api调用形式向用户发送消息,则不受影响)。关于消息加解密的详细说明,请见“消息加解密说明”。
各消息类型的推送xml数据包结构如下:
文本消息
<xml> <tousername><![cdata[touser]]></tousername> <fromusername><![cdata[fromuser]]></fromusername> <createtime>1348831860</createtime> <msgtype><![cdata[text]]></msgtype> <content><![cdata[this is a test]]></content> <msgid>1234567890123456</msgid> </xml>
图片消息
<xml> <tousername><![cdata[touser]]></tousername> <fromusername><![cdata[fromuser]]></fromusername> <createtime>1348831860</createtime> <msgtype><![cdata[image]]></msgtype> <picurl><![cdata[this is a url]]></picurl> <mediaid><![cdata[media_id]]></mediaid> <msgid>1234567890123456</msgid> </xml>
语音消息
<xml> <tousername><![cdata[touser]]></tousername> <fromusername><![cdata[fromuser]]></fromusername> <createtime>1357290913</createtime> <msgtype><![cdata[voice]]></msgtype> <mediaid><![cdata[media_id]]></mediaid> <format><![cdata[format]]></format> <msgid>1234567890123456</msgid> </xml>
请注意,开通语音识别后,用户每次发送语音给公众号时,微信会在推送的语音消息xml数据包中,增加一个recongnition字段 (注:由于客户端缓存,开发者开启或者关闭语音识别功能,对新关注者立刻生效,对已关注用户需要24小时生效。开发者可以重新关注此帐号进行测试)。开启语音识别后的语音xml数据包如下:
<xml> <tousername><![cdata[touser]]></tousername> <fromusername><![cdata[fromuser]]></fromusername> <createtime>1357290913</createtime> <msgtype><![cdata[voice]]></msgtype> <mediaid><![cdata[media_id]]></mediaid> <format><![cdata[format]]></format> <recognition><![cdata[腾讯微信团队]]></recognition> <msgid>1234567890123456</msgid> </xml>
多出的字段中,format为语音格式,一般为amr,recognition为语音识别结果,使用utf8编码。
视频消息
<xml> <tousername><![cdata[touser]]></tousername> <fromusername><![cdata[fromuser]]></fromusername> <createtime>1357290913</createtime> <msgtype><![cdata[video]]></msgtype> <mediaid><![cdata[media_id]]></mediaid> <thumbmediaid><![cdata[thumb_media_id]]></thumbmediaid> <msgid>1234567890123456</msgid> </xml>
小视频消息
<xml> <tousername><![cdata[touser]]></tousername> <fromusername><![cdata[fromuser]]></fromusername> <createtime>1357290913</createtime> <msgtype><![cdata[shortvideo]]></msgtype> <mediaid><![cdata[media_id]]></mediaid> <thumbmediaid><![cdata[thumb_media_id]]></thumbmediaid> <msgid>1234567890123456</msgid> </xml>
地理位置消息
<xml> <tousername><![cdata[touser]]></tousername> <fromusername><![cdata[fromuser]]></fromusername> <createtime>1351776360</createtime> <msgtype><![cdata[location]]></msgtype> <location_x>23.134521</location_x> <location_y>113.358803</location_y> <scale>20</scale> <label><![cdata[位置信息]]></label> <msgid>1234567890123456</msgid> </xml>
链接消息
<xml> <tousername><![cdata[touser]]></tousername> <fromusername><![cdata[fromuser]]></fromusername> <createtime>1351776360</createtime> <msgtype><![cdata[link]]></msgtype> <title><![cdata[公众平台官网链接]]></title> <description><![cdata[公众平台官网链接]]></description> <url><![cdata[url]]></url> <msgid>1234567890123456</msgid> </xml>
接上篇,看responsexml(poststring);方法如下
/// <summary> /// 获取用户发送的消息 /// </summary> /// <param name="poststring"></param> private void responsexml(string poststring) { //使用xmldocument加载信息结构 xmldocument xmldoc = new xmldocument(); xmldoc.loadxml(poststring); xmlelement rootelement = xmldoc.documentelement;//获取文档的根 xmlnode msgtype = rootelement.selectsinglenode("msgtype"); //获取消息的文本类型 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;//消息类型 ///对消息的不同类型进行赋值 if (requestxml.msgtype == "text") { //赋值文本信息内容 requestxml.content = rootelement.selectsinglenode("content").innertext; } if (requestxml.msgtype.trim() == "location") { ///赋值地理位置纬度,经度,地图缩放比例,地理位置说明 requestxml.location_x = rootelement.selectsinglenode("location_x").innertext; requestxml.location_y = rootelement.selectsinglenode("location_y").innertext; requestxml.scale = rootelement.selectsinglenode("scale").innertext; requestxml.label = rootelement.selectsinglenode("label").innertext; } if (requestxml.msgtype.trim().tolower() == "event") { ///赋值事件名称和事件key值 requestxml.eventname = rootelement.selectsinglenode("event").innertext; requestxml.eventkey = rootelement.selectsinglenode("eventkey").innertext; } if (requestxml.msgtype.trim().tolower() == "voice") { ///赋值语音识别结果,赋值之前一定要记得在开发者模式下,把语音识别功能开启,否则获取不到 requestxml.recognition = rootelement.selectsinglenode("recognition").innertext; } responsemsg(requestxml); }
语音识别功能开启如下:
requestxml是我单独创建的一个类,该类声明了消息中常用的属性字段,如下:
/// <summary> /// 接收消息的实体类 /// </summary> public class requestxml { private string tousername = string.empty; /// <summary> /// 本公众号 /// </summary> public string tousername{get;set;} /// <summary> /// 用户微信号 /// </summary> public string fromusername{get;set;} /// <summary> /// 创建时间 /// </summary> public string createtime{get;set;} /// <summary> /// 信息类型 /// </summary> public string msgtype{get;set;} /// <summary> /// 信息内容 /// </summary> public string content{get;set;} /*以下为事件类型的消息特有的属性*/ /// <summary> /// 事件名称 /// </summary> public string eventname{get;set;} /// <summary> /// 事件值 /// </summary> public string eventkey { get; set; } /*以下为图文类型的消息特有的属性*/ /// <summary> /// 图文消息的个数 /// </summary> public int articlecount { get; set; } /// <summary> /// 图文消息的标题 /// </summary> public string title { get; set; } /// <summary> /// 图文消息的简介 /// </summary> public string description { get; set; } /// <summary> /// 图文消息图片的链接地址 /// </summary> public string picurl { get; set; } /// <summary> /// 图文消息详情链接地址 /// </summary> public string url { get; set; } /// <summary> /// 图文消息集合 /// </summary> public list<requestxml> articles { get; set;} /*以下为地理位置类型的消息特有的属性*/ /// <summary> /// 地理位置纬度 /// </summary> public string location_x { get; set; } /// <summary> /// 地理位置经度 /// </summary> public string location_y { get; set; } /// <summary> /// 地图缩放比例 /// </summary> public string scale { get; set; } /// <summary> /// 地图位置说明 /// </summary> public string label { get; set; } /// <summary> /// 语音消息特有字段 /// </summary> public string recognition { get; set; } }
继续关注 responsemsg(requestxml);方法如下
private void responsemsg(requestxml requestxml) { string msgtype = requestxml.msgtype; try { //根据消息类型判断发送何种类型消息 switch (msgtype) { case "text": sendtextcase(requestxml);//发送文本消息 break; case "event"://发送事件消息 if (!string.isnullorwhitespace(requestxml.eventname) && requestxml.eventname.tostring().trim().equals("subscribe")) { sendwelcomemsg(requestxml);//关注时返回的图文消息 } else if (!string.isnullorwhitespace(requestxml.eventname) && requestxml.eventname.tostring().trim().equals("click")) { sendeventmsg(requestxml);//发送事件消息 } break; case "voice": sendvoicemsg(requestxml);//发送语音消息 break; case "location"://发送位置消息 sendmapmsg(requestxml); break; default: break; } } catch (exception ex) { httpcontext.current.response.write(ex.tostring()); } }
先来关注发送文本消息,sendtextcase(requestxml);//发送文本消息
/// <summary> /// 发送文本 /// </summary> /// <param name="requestxml"></param> private void sendtextcase(requestxml requestxml) { string responsecontent = formattextxml(requestxml.fromusername, requestxml.tousername, requestxml.content); httpcontext.current.response.contenttype = "text/xml"; httpcontext.current.response.contentencoding = encoding.utf8; httpcontext.current.response.write(responsecontent); httpcontext.current.response.end(); }
formattextxml方法制定格式
/// <summary> /// 返回格式化的xml格式内容 /// </summary> /// <param name="p1">公众号</param> /// <param name="p2">用户号</param> /// <param name="p3">回复内容</param> /// <returns></returns> private string formattextxml(string p1, string p2, string p3) { return "<xml><tousername><![cdata[" + p1 + "]]></tousername><fromusername><![cdata[" + p2 + "]]></fromusername><createtime>" + datetime.now.subtract(new datetime(1970, 1, 1, 8, 0, 0)).totalseconds.tostring() + "</createtime><msgtype><![cdata[text]]></msgtype><content><![cdata[" + p3 + "]]></content><funcflag>1</funcflag></xml>"; }
这样就能实现消息的应答,如果用户点击的按钮,如下代码:
case "event"://发送事件消息 if (!string.isnullorwhitespace(requestxml.eventname) && requestxml.eventname.tostring().trim().equals("subscribe")) { sendwelcomemsg(requestxml);//关注时返回的图文消息 } else if (!string.isnullorwhitespace(requestxml.eventname) && requestxml.eventname.tostring().trim().equals("click")) { sendeventmsg(requestxml);//发送事件消息 } break; /// <summary> /// 发送响应事件消息 /// </summary> /// <param name="requestxml"></param> private void sendeventmsg(requestxml requestxml) { string keystr = requestxml.eventkey.tostring(); switch (keystr) { case "mypay": sendpaydetails(requestxml);//发送薪资账单 break; case "tianqiyubao": sendweatermessage(requestxml);//发送天气预报 break; case "kaixinyixiao": sendkaixinmessage(requestxml);//发送开心一笑结果集 break; case "updatemessage": sendupdatemessage(requestxml);//发送修改信息链接 break; case "yuangonghuodong": sendyuangonghuodong(requestxml);//发送学生活动 break; case "yuangongtongzhi": sendyuangongtongzhi(requestxml);//发送员工通知 break; case "youwenbida": sendwenti(requestxml);//发送员工提交问题链接 break; case "mywen": sendwentilist(requestxml);//发送问题列表链接 break; case "phoneserices": sendkefumessage(requestxml);//接入客服 break; default: string responsecontent = string.empty; responsecontent = formattextxml(requestxml.fromusername, requestxml.tousername,"此功能暂未开放!敬请期待!"); httpcontext.current.response.contenttype = "text/xml"; httpcontext.current.response.contentencoding = encoding.utf8; httpcontext.current.response.write(responsecontent); httpcontext.current.response.end(); break; } }
sendwelcomemsg(requestxml);//关注时返回的图文消息
/// <summary> /// 发送关注时的图文消息 /// </summary> /// <param name="requestxml"></param> private void sendwelcomemsg(requestxml requestxml) { string responsecontent = string.empty; string newdate = datetime.now.subtract(new datetime(1970, 1, 1, 8, 0, 0)).totalseconds.tostring(); string purlfilename = "http://www.deqiaohr.com.cn/weixin/welcome.jpg"; responsecontent = string.format(message_news_main, requestxml.fromusername, requestxml.tousername, newdate, "1", string.format(message_news_item, "欢迎关注德桥员工服务中心", "苏州德桥人力资源创立于2002年...", purlfilename, "http://www.deqiaohr.com.cn/weixin/wxgsjianjie.aspx")); httpcontext.current.response.contenttype = "text/xml"; httpcontext.current.response.contentencoding = encoding.utf8; httpcontext.current.response.write(responsecontent); httpcontext.current.response.end(); }
message_news_main 和message_news_item是图文消息格式化
/// <summary> /// 返回图文消息主体 /// </summary> public static string message_news_main { get { return @"<xml> <tousername><![cdata[{0}]]></tousername> <fromusername><![cdata[{1}]]></fromusername> <createtime>{2}</createtime> <msgtype><![cdata[news]]></msgtype> <articlecount>{3}</articlecount> <articles> {4} </articles> </xml> "; } } /// <summary> /// 返回图文消息项 /// </summary> public static string message_news_item { get { return @"<item> <title><![cdata[{0}]]></title> <description><![cdata[{1}]]></description> <picurl><![cdata[{2}]]></picurl> <url><![cdata[{3}]]></url> </item>"; } } /// <summary> /// 发送响应语音识别结果 /// </summary> /// <param name="requestxml"></param> private void sendvoicemsg(requestxml requestxml) { string responsecontent = formattextxml(requestxml.fromusername, requestxml.tousername, "您刚才说的语音消息识别结果为:" + requestxml.recognition.tostring()); httpcontext.current.response.contenttype = "text/xml"; httpcontext.current.response.contentencoding = encoding.utf8; httpcontext.current.response.write(responsecontent); httpcontext.current.response.end(); }
精彩专题分享:asp.net微信开发教程汇总,欢迎大家学习。
以上就是关于asp.net微信开发的第二篇,针对消息应答进行学习,之后会有更新更多关于asp.net微信开发的文章,希望大家持续关注。