使用 Senparc 完成自动回复功能
通讯流程理解
通过自动回复功能,可以理解微信服务器与网站之间的通讯过程:
- 用户在微信客户端向公众号发送消息
- 微信服务器将消息以 POST 请求转发到开发者配置的 URL
- 网站接收请求,验证签名,处理消息内容,返回响应
Post 接口实现
在 Controller 中添加 Post 类型的 Action,同样通过 http://weixin.foxdevelop.com/ 访问(与 Get 验证共用同一路由,通过 HTTP 方法区分)。
处理流程:
- 接收
PostModel参数(微信服务器传入的签名、时间戳、随机数等) - 调用
CheckSignature.Check()验证请求来源 - 为
PostModel补充敏感信息(Token、EncodingAESKey、AppId),这些信息不会在网络上传播 - 创建自定义
MessageHandler实例,传入请求流、PostModel 和最大记录数 - 调用
Execute()执行处理过程 - 返回响应内容
Post 方法完整代码:
/// <summary>
/// 处理和微信服务器交互的接口,Post 方式
/// </summary>
[HttpPost]
[ActionName("Index")]
public ActionResult Post(PostModel postModel)
{
if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, token))
{
Writelog("参数错误");
return Content("参数错误!");
}
//以下保密信息不会(不应该)在网络上传播,请注意
postModel.Token = token;
postModel.EncodingAESKey = encodingAESKey;
postModel.AppId = appId;
//v4.2.2之后的版本,可以设置每个人上下文消息储存的最大数量,防止内存占用过多,如果该参数小于等于0,则不限制
var maxRecordCount = 10;
var messageHandler = new CustomMessageHandler(Request.InputStream, postModel, maxRecordCount);
messageHandler.OmitRepeatedMessage = true; //默认已开启,也可设为false停用
try
{
//执行微信处理过程
messageHandler.Execute();
Writelog("执行微信处理过程");
if (messageHandler.ResponseMessage != null)
{
Writelog(messageHandler.ResponseDocument.ToString());
return Content(messageHandler.ResponseDocument.ToString());
}
return Content("");
}
catch (Exception ex)
{
Writelog(ex.Message);
return Content("");
}
}Code language: PHP (php)
自定义 MessageHandler
创建 CustomMessageHandler 类,继承 MessageHandler<CustomMessageContext>,重写对应请求类型的处理方法。
核心逻辑:
- 构造函数中设置上下文过期时间(如 3 分钟)
OnExecuting()/OnExecuted()可处理请求前后逻辑OnTextRequest()处理文字消息,调用GetReponse()生成回复GetReponse()根据消息类型创建对应的ResponseMessage
文字消息处理示例:
public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
{
IResponseMessageBase responseMessage = null;
if (requestMessage != null)
{
responseMessage = GetReponse(requestMessage);
}
return responseMessage;
}
protected IResponseMessageBase GetReponse(IRequestMessageBase requestMessage)
{
switch ((ResponseMsgType)requestMessage.MsgType)
{
case ResponseMsgType.Text:
{
RequestMessageText requestMessageText = requestMessage as RequestMessageText;
var strongResponseMessage = CreateResponseMessage<ResponseMessageText>();
strongResponseMessage.Content = "您发的内容是:" + requestMessageText.Content;
return strongResponseMessage;
}
}
return null;
}Code language: PHP (php)
其他消息类型(图片、语音、视频、位置、链接等)均有对应的重写方法,未重写时默认返回 null,即不回复。
默认回复:
DefaultResponseMessage() 处理所有未被覆盖的消息类型,返回兜底回复内容。
消息上下文(CustomMessageContext)
继承 MessageContext<IRequestMessageBase, IResponseMessageBase>,用于管理用户会话状态。
可订阅 MessageContextRemoved 事件,在上下文过期时执行清理逻辑(如通知用户会话已超时)。
public class CustomMessageContext : MessageContext<IRequestMessageBase, IResponseMessageBase>
{
public CustomMessageContext()
{
base.MessageContextRemoved += CustomMessageContext_MessageContextRemoved;
}
void CustomMessageContext_MessageContextRemoved(object sender, WeixinContextRemovedEventArgs<IRequestMessageBase, IResponseMessageBase> e)
{
//TODO: 执行消息过期时的逻辑,如发送退出提示
}
}Code language: HTML, XML (xml)
注意:上下文过期清除并非实时触发,而是在下一条请求到达前由算法统一清理,以提高效率。


Previous: 使用公众平台测试账号来完成验证
Next: 使用 Senparc 实现接收图片消息并回复