目录
一、消息处理说明
1.1、接受消息—验证消息真实性
1.2、接受消息—接收普通消息
1.2.1、代码下载
1.3、接收消息—接收事件推送
1.4、接收消息—接收语音识别结果
一、消息处理说明
场景说明,例如,你给一个微信公众号发了一个消息(如图),对于微信而言,这就是最基本的文本消息。
当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上(就是上一篇中的URL)。所以本片文章将说明微信公众号的消息处理。目前微信官方上将普通消息分为了7类,分类信息如下图所示:
虽然官网上的消息共有7类,但一般的订阅号不能获取全部接口。因此,我们只能在测试公众号下进行开发学习。测试公众号中关于消息处理的接口明细如下:
本片文章,将会对测试公众号中的接口进行开发及测试,并实现相关功能。
1.1、接受消息—验证消息真实性
这个就是C#开发微信公众号(1)中提交的服务器验证。具体可以参考这篇文章。
1.2、接受消息—接收普通消息
微信官网服务器收到用户发送的本文消息时,会将消息组织成一个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>
其中,各个参数的含义如下:
参数 | 具体含义 |
---|---|
ToUserName | 开发者的公众号 |
fromUser | 用户的唯一标识 |
CreateTime | 消息的创建时间 |
MsgType | 消息类型(此处是:text) |
Content | 用户发送的内容 |
MsgId | 消息的ID,唯一标识 |
当用户将文本消息发送给微信服务器时,微信服务器会将此消息,以上面规定的消息格式,以POST方式转发到开发者服务器上(指定的URL)。开发者服务器需要在5秒内回复,若未回复,微信官网服务器会将消息再次发给开发者服务器。共计3次。
开发者需要完成的就是:根据规则,回复官网服务器相关内容。若接口未实现,则可以回复“success”字符串,这样官网服务器就不会多次问询了。
具体实现代码如下:
//微信服务方法(方法仍然是验证服务器的那个方法,只不过把验证的代码删除了/隐藏了)
public ActionResult BTCHWeChat()
{
string resultStr = "";
string postString = string.Empty;
if (HttpContext.Request.HttpMethod.ToUpper() == "POST")
{
using (Stream stream = HttpContext.Request.InputStream)
{
//将Request中的数据读取出来,存放到byte数组中
Byte[] postBytes = new Byte[stream.Length];
stream.Read(postBytes, 0, (Int32)stream.Length);
postString = Encoding.Default.GetString(postBytes);
//调用相关业务方法(具体的处理方法)
resultStr = HandleMsg(postString);
}
}
else
{
//若有异常,或未实现接口,可回复success
resultStr = "success";
}
//返回处理结果
return Content(resultStr);
}
上面的方法中,使用的仍是 BTCHWeChat。只不过将验证服务器的那段代码删除了,即,方法体没有发生变化,只是方法的内部发生了变化(实际上再不删除旧代码的情况下,通过方法的GET/POST类别,实现方法的区分,不过为了演示代码,所以就删除了)。方法将请求中的数据存储在byte数组中,然后将数组作为参数,传到具体的处理方法中。
//将参数进行进一步处理的方法
private string HandleMsg(string input_content)
{
//将微信服务器发送的内容,转换为XML
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(new System.IO.MemoryStream(System.Text.Encoding.Default.GetBytes(input_content)));
return TextHandle(xmldoc);
}
本方法,只是将参数进行了进一步的处理,将byte数组转为XMLDocument,并将XMLDocument作为参数,传至具体的方法中,具体方法如下:
//接受文本消息,并处理文本消息
public string TextHandle(XmlDocument xmldoc)
{
string responseContent = "";
XmlNode ToUserName = xmldoc.SelectSingleNode("/xml/ToUserName");
XmlNode FromUserName = xmldoc.SelectSingleNode("/xml/FromUserName");
XmlNode Content = xmldoc.SelectSingleNode("/xml/Content");
if (Content != null)
{
responseContent = string.Format(ReplyType.Message_Text,FromUserName.InnerText,
ToUserName.InnerText,DateTime.Now.Ticks,
"欢迎使用微信公共账号,您输入的内容为:" + Content.InnerText + "");
}
return responseContent;
}
这个是具体的处理方法,实现的功能是将用户输入的内容再返回给微信服务器。
上面的代码实现了微信公众号的文本消息的处理,然后再说一下文本消息的回复,就是上面方法的返回结果。文本消息的回复内容格式如下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>
返回的数据参数与传入的参数相差不大,只有一处的区别。传入参数有MsgId,返回的参数没有该内容。所以按照以上的内容,将内容进行返回。在上面的方法中用到了ReplyType枚举类。具体的定义如下:
//回复类型
public class ReplyType
{
/// <summary>
/// 普通文本消息
/// </summary>
public static string Message_Text
{
get { return @"<xml>
<ToUserName><![CDATA[{0}]]></ToUserName>
<FromUserName><![CDATA[{1}]]></FromUserName>
<CreateTime>{2}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[{3}]]></Content>
</xml>"; }
}
}
所以将上面的代码发布到开发者服务器后,微信公众号的将拥有自动回复的功能,如下图所示
1.2.1、代码下载
以上的代码下载地址:代码下载
至此,完成了:验证消息真实性、接收普通消息、自动回复,三项功能。
下面会逐一将测试账号中消息处理的接口功能一一实现
1.3、接收消息—接收事件推送
目前微信官网上事件分为4类:
本质上1.3中接收事件推送与1.2中是相同的,可以在Controller方法中通过MsgType进行分类处理。例如,已关注/取消关注为例,Controller中的方法可以用如下的方式处理:
private string HandleMsg(string input_content)
{
string responseContent = "success";
//将微信服务器发送的内容,转换为XML
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(new System.IO.MemoryStream(System.Text.Encoding.Default.GetBytes(input_content)));
//解析XML,并根据消息类型进行不同的处理
XmlNode MsgType = xmldoc.SelectSingleNode("/xml/MsgType");
if (MsgType != null)
{
switch (MsgType.InnerText)
{
case "event":
responseContent = EventHandle(xmldoc);//事件处理
break;
case "text":
responseContent = TextHandle(xmldoc);//接受文本消息处理
break;
default:
break;
}
}
return responseContent;
}
可以比照TextHandle方法,创建EventHandle方法。举例如下:
//事件处理方法
public string EventHandle(XmlDocument xmldoc)
{
string responseContent = "";
XmlNode Event = xmldoc.SelectSingleNode("/xml/Event");
XmlNode EventKey = xmldoc.SelectSingleNode("/xml/EventKey");
XmlNode ToUserName = xmldoc.SelectSingleNode("/xml/ToUserName");
XmlNode FromUserName = xmldoc.SelectSingleNode("/xml/FromUserName");
if (Event != null)
{
//菜单单击事件
if (Event.InnerText.Equals("CLICK"))
{
//完成菜单单击的事件
}
//用户关注时的事件
if (Event.InnerText.Equals("subscribe"))
{
//完成事件的处理
}
//这儿还可以写其他的事情
}
return responseContent;
}
1.4、接收消息—接收语音识别结果
接收语音识别结果的操作,和上面的雷同,所以就不具体实现了。
本片主要阐述开发者服务器再收到微信官网的数据时的处理。微信公众平台的一个重要的功能是向用户发送消息!我会在下一篇文章中讲述,如何向指定的用户发送消息。
以上