首页 > 编程语言 >微信公众号开发C#系列-6、消息管理-普通消息接受处理

微信公众号开发C#系列-6、消息管理-普通消息接受处理

时间:2023-06-13 16:05:46浏览次数:68  
标签:C# 微信 responseMessage 回复 requestMessage id 消息


1、概述

通过前面章节的学习,我们已经对微信的开发有了基本的掌握与熟悉,基本可以上手做复杂的应用了。本篇我们将详细讲解微信消息管理中普通消息的接收与处理。当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。接收普通消息微信官方文档参考:接收普通消息文档API 消息接收后,就有一个处理或回复的过程,单单发送消息了没有响应也是不人性化的,下面我们就对接收到微信各类型消息分别讲解处理的方法。

2、消息接收

微信公众号开发C#系列-6、消息管理-普通消息接受处理_C#快速开发框架


当普通微信用户向公众账号发消息时,微信服务器会先接收到用户发送的消息,然后将用户消息按照指定的XML格式组装好数据,最后POST消息的XML数据包到开发者填写的URL上。

接收到的普通消息的消息类型目前有以下几种:

  1. 文本消息
  2. 图片消息
  3. 语音消息
  4. 视频消息
  5. 小视频消息
  6. 地理位置消息
  7. 链接消息

每一种消息类型都有其指定的XML数据格式,这7种消息的xml格式请到官方文档查看,有具体的格式定义和属性说明。格式很简单,基本共有属性包括ToUserName、FromUserName、CreateTime、MsgType、MsgId,并且每种类型有自己特殊的属性。

接收消息的过程其实就是获取post请求的这个xml,然后对这个xml进行分析的过程。post请求的入口还是之前提到的微信公众号接入的那个地址,整个公众号的所有请求都会走这个入口,只是接入时是get请求,其它情况下是post请求。

3、消息回复

微信服务器在将用户的消息发给公众号的开发者服务器地址后,会等待开发者服务器回复响应消息。微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。

假如服务器无法保证在五秒内处理并回复,必须做出下述回复,这样微信服务器才不会对此作任何处理,并且不会发起重试(这种情况下,可以使用客服消息接口进行异步回复),否则,将出现严重的错误提示。详见下面说明:

1、(推荐方式)直接回复success

2、直接回复空串(指字节长度为0的空字符串,而不是XML结构体中content字段的内容为空)

一旦遇到以下情况,微信都会在公众号会话中,向用户下发系统提示“该公众号暂时无法提供服务,请稍后再试”

1、开发者在5秒内未回复任何内容

2、开发者回复了异常数据,比如JSON数据等

另外,请注意,回复图片等多媒体消息时需要预先通过素材管理接口上传临时素材到微信服务器,可以使用素材管理中的临时素材,也可以使用永久素材。

消息回复目前支持回复文本、图片、图文、语音、视频、音乐,每一种类型的消息都有特定的XML数据格式。这几种回复消息的xml数据格式请参考官方文档,有具体的格式定义和属性说明。格式很简单,基本共有属性包括ToUserName、FromUserName、CreateTime、MsgType,并且每种类型有自己特殊的属性。

4、各类型消息的接收与回复

使用Senparc.Weixin框架来快速处理各种接收的普通消息,实现非常简单,自定义一个继承MessageHandler的类,重写这7种类型的方法即可。注意:DefaultResponseMessage必须重写,用于返回没有处理过的消息类型(也可以用于默认消息,如帮助信息等);其中所有原OnXX的抽象方法已经都改为虚方法,可以不必每个都重写。若不重写,默认返回DefaultResponseMessage方法中的结果。
CustomMessageHandle.cs需要继承Senparc.Weixin.MP.MessageHandlers这个抽象类,并实现部分方法。最初步的CustomMessageHandle.cs代码
可能如下:

public class CustomMessageHandler : MessageHandler<CustomMessageContext>
{
    public CustomMessageHandler(Stream inputStream, PostModel postModel)
        : base(inputStream, postModel)
    {

    }

    public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
    {
        var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); //ResponseMessageText也可以是News等其他类型
        responseMessage.Content = "这条消息来自DefaultResponseMessage。";
        return responseMessage;
    }
}

我们可以看到必须要重写实现的抽象方法名为DefaultResponseMessage(),这一条信息用于返回一条的消息,假如对应类型(如语音)的微信消息没有被代码处理,那么默认会返回这里的结果。在DefaultResponseMessage()方法中,我们看到这样一句:

var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); //ResponseMessageText也可以是News等其他类型

这里的CreateResponseMessage方法即创建一个返回对象,T可以为以下类型的任意一个,分别对应了不同的返回类型:

  • ResponseMessageText - 对应文本消息
  • ResponseMessageNews - 对应图文消息
  • ResponseMessageMusic - 对应音乐消息
  • ResponseMessageXXX - 其他类型以此类推

各种类型的消息我们可以根据我们自己的业务要求进行重写回复,如果没重写就会返回默认的消息(重写默认响应的基础上)。

4.1、文本消息的接收与回复

文本消息对应的数据包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		开发者微信号(直接把它当做你的公众号的微信号即可)
FromUserName	发送方帐号(一个OpenID)
CreateTime		消息创建时间 (整型)
MsgType			消息类型,文本为text
Content			文本消息内容
MsgId			消息id,64位整型

处理文本消息参考代码:

/// <summary>
/// 处理文字请求
/// </summary>
/// <returns></returns>
public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
{
    //注意:下面泛型ResponseMessageText即返回给客户端的类型,可以根据自己的需要填写ResponseMessageNews等不同类型。
    var responseMessage = CreateResponseMessage<ResponseMessageText>();
 
    var result = new StringBuilder();
    result.AppendFormat("您刚发送了文本信息:{0}\r\n\r\n", requestMessage.Content);
 
    if (CurrentMessageContext.RequestMessages.Count > 1)
    {
        result.AppendFormat("您刚还发送了如下消息({0}/{1}):\r\n", CurrentMessageContext.RequestMessages.Count, CurrentMessageContext.StorageData);
        for (int i = CurrentMessageContext.RequestMessages.Count - 2; i >= 0; i--)
        {
            var historyMessage = CurrentMessageContext.RequestMessages[i];
            result.AppendFormat("{0} 【{1}】{2}\r\n",
                                historyMessage.CreateTime.ToShortTimeString(),
                                historyMessage.MsgType.ToString(),
                                (historyMessage is RequestMessageText)
                                    ? (historyMessage as RequestMessageText).Content
                                    : "[非文字类型]"
                );
        }
        result.AppendLine("\r\n");
    }
    result.AppendFormat("如果您在{0}分钟内连续发送消息,记录将被自动保留(当前设置:最多记录{1}条)。过期后记录将会自动清除。\r\n", WeixinContext.ExpireMinutes, WeixinContext.MaxRecordCount);
    result.AppendLine("\r\n");
    result.AppendLine("您还可以发送【位置】【图片】【语音】【视频】等类型的信息(注意是这几种类型,不是这几个文字),查看不同格式的回复。");
    responseMessage.Content = result.ToString();
    return responseMessage;
}

微信公众号开发C#系列-6、消息管理-普通消息接受处理_C#快速开发框架_02


微信公众号开发C#系列-6、消息管理-普通消息接受处理_C#_03

4.2、图片消息的接收与回复

图片消息对应的数据包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>

参数说明:

参数				描述

ToUserName		开发者微信号
FromUserName	发送方帐号(一个OpenID)
CreateTime		消息创建时间 (整型)
MsgType			消息类型,图片为image
PicUrl			图片链接(由系统生成)
MediaId			图片消息媒体id,可以调用获取临时素材接口拉取数据。
MsgId			消息id,64位整型

处理图片消息参考代码:

/// <summary>
/// 处理图片请求
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnImageRequest(RequestMessageImage requestMessage)
{
    var responseMessage = CreateResponseMessage<ResponseMessageNews>();
    responseMessage.Articles.Add(new Article()
    {
        Title = "您刚才发送了图片信息",
        Description = "您发送的图片将会显示在边上",
        PicUrl = requestMessage.PicUrl,
        Url = "http://blog.rdiframework.net/"
    });
    responseMessage.Articles.Add(new Article()
    {
        Title = "第二条",
        Description = "第二条带连接的内容",
        PicUrl = requestMessage.PicUrl,
        Url = "http://blog.rdiframework.net/"
    });

    return responseMessage;
}

在上面代码中我们返回了用户发送的图片消息,同时加上了链接地址,用户单击消息会自动跳转到指定的URL地址。

微信公众号开发C#系列-6、消息管理-普通消息接受处理_C#快速开发框架_04


微信公众号开发C#系列-6、消息管理-普通消息接受处理_C#快速开发框架_05

4.3、语音消息的接收与回复

语音消息对应的数据包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>

参数				描述
ToUserName		开发者微信号
FromUserName	发送方帐号(一个OpenID)
CreateTime		消息创建时间 (整型)
MsgType			语音为voice
MediaId			语音消息媒体id,可以调用获取临时素材接口拉取数据。
Format			语音格式,如amr,speex等
MsgID			消息id,64位整型

参数说明:

处理语音消息参考代码:

/// <summary>
/// 处理语音请求
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnVoiceRequest(RequestMessageVoice requestMessage)
{
    //获得当前公众号
    WeixinOfficialAccountEntity account = RDIFrameworkService.Instance.WeixinBasicService.GetOfficialAccountEntity(Id);
    
    var responseMessage = CreateResponseMessage<ResponseMessageMusic>();
    //上传缩略图
    var uploadResult = Senparc.Weixin.MP.AdvancedAPIs.MediaApi.UploadTemporaryMedia(account.AccessToken, UploadMediaFileType.image,Server.GetMapPath("~/Content/Images/weixing-ma.png"));

    //设置音乐信息
    responseMessage.Music.Title = "天籁之音";
    responseMessage.Music.Description = "播放您上传的语音";
    responseMessage.Music.MusicUrl = "http://www.rdiframework.net/resource/25375532.mp3";
    responseMessage.Music.HQMusicUrl = "http://www.rdiframework.net/Media/GetVoice?mediaId=" + requestMessage.MediaId;
    responseMessage.Music.ThumbMediaId = uploadResult.media_id;
    return responseMessage;
}

微信公众号开发C#系列-6、消息管理-普通消息接受处理_微信开发_06


微信公众号开发C#系列-6、消息管理-普通消息接受处理_快速开发框架_07

4.4、视频消息的接收与回复

视频消息对应的数据包XML格式如下:

<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>

参数说明:

参数				描述
ToUserName		开发者微信号
FromUserName	发送方帐号(一个OpenID)
CreateTime		消息创建时间 (整型)
MsgType			视频为video
MediaId			视频消息媒体id,可以调用获取临时素材接口拉取数据。
ThumbMediaId	视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
MsgId			消息id,64位整型

处理视频消息参考代码:

/// <summary>
/// 处理视频请求
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnVideoRequest(RequestMessageVideo requestMessage)
{
    var responseMessage = CreateResponseMessage<ResponseMessageText>();
    responseMessage.Content = "您发送了一条视频信息,ID:" + requestMessage.MediaId;
    return responseMessage;
}

微信公众号开发C#系列-6、消息管理-普通消息接受处理_快速开发框架_08


微信公众号开发C#系列-6、消息管理-普通消息接受处理_C#快速开发框架_09

4.5、小视频消息的接收与回复

视频与小视频主要区别是在MsgType上,其他的都一样。

小视频消息对应的数据包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>

参数说明:

参数				描述
ToUserName		开发者微信号
FromUserName	发送方帐号(一个OpenID)
CreateTime		消息创建时间 (整型)
MsgType			小视频为shortvideo
MediaId			视频消息媒体id,可以调用获取临时素材接口拉取数据。
ThumbMediaId	视频消息缩略图的媒体id,可以调用获取临时素材接口拉取数据。
MsgId			消息id,64位整型

处理小视频消息参考代码:

public override IResponseMessageBase OnShortVideoRequest(RequestMessageShortVideo requestMessage)
{
    var responseMessage = this.CreateResponseMessage<ResponseMessageText>();
    responseMessage.Content = "您刚才发送的是小视频";
    return responseMessage;
}

4.6、地理位置消息的接收与回复

地理位置消息对应的数据包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>

参数说明:

参数				描述
ToUserName		开发者微信号
FromUserName	发送方帐号(一个OpenID)
CreateTime		消息创建时间 (整型)
MsgType			消息类型,地理位置为location
Location_X		地理位置维度
Location_Y		地理位置经度
Scale			地图缩放大小
Label			地理位置信息
MsgId			消息id,64位整型

处理地理位置消息参考代码:

/// <summary>
/// 处理位置请求
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnLocationRequest(RequestMessageLocation requestMessage)
{
    //返回的是图文消息,是关于地址的图文消息。
    var responseLocation = base.CreateResponseMessage<ResponseMessageNews>();

    var markersList = new List<BaiduMarkers>();
    markersList.Add(new BaiduMarkers()
    {
        Size = BaiduMarkerSize.m,
        Color = "red",
        Label = "A",
        Latitude = requestMessage.Location_X,
        Longitude = requestMessage.Location_Y,
    });
    var mapUrl = BaiduMapHelper.GetBaiduStaticMap(requestMessage.Location_Y, requestMessage.Location_X, 1, 13, markersList);
    responseLocation.Articles.Add(new Article()
    {
        Description = string.Format("您刚才发送了地理位置信息。Location_X:{0},Location_Y:{1},Scale:{2},标签:{3}", requestMessage.Location_X, requestMessage.Location_Y, requestMessage.Scale, requestMessage.Label),
        PicUrl = SystemInfo.WeChatSiteUrl +"/Content/Images/toplogo.png",
        Title = "国思软件快速开发框架-地图返回",
        Url = mapUrl
    });
    return responseLocation;
}

微信公众号开发C#系列-6、消息管理-普通消息接受处理_C#_10


微信公众号开发C#系列-6、消息管理-普通消息接受处理_C#_11


对于回复的消息,我们还可以单击弹出百度地图返回的位置详情,具体应用可据此扩展。

微信公众号开发C#系列-6、消息管理-普通消息接受处理_快速开发框架_12

4.7、链接消息的接收与回复

链接消息对应的数据包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>

参数说明:

参数	描述
ToUserName		接收方微信号
FromUserName	发送方微信号,若为普通用户,则是一个OpenID
CreateTime		消息创建时间
MsgType			消息类型,链接为link
Title			消息标题
Description		消息描述
Url				消息链接
MsgId			消息id,64位整型

链接位置消息参考代码:

/// <summary>
/// 处理链接消息请求
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnLinkRequest(RequestMessageLink requestMessage)
{
    var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(requestMessage);
    responseMessage.Content = string.Format(@"您发送了一条连接信息:
	Title:{0}
	Description:{1}
	Url:{2}", requestMessage.Title, requestMessage.Description, requestMessage.Url);
    return responseMessage;
}

参考文章

微信公众平台技术文档-官方

Senparc.Weixin SDK + 官网示例源代码

RDIFramework.NET — 基于.NET的快速信息化系统开发框架 — 系列目录

RDIFramework.NET ━ .NET快速信息化系统开发框架 ━ 工作流程组件介绍

RDIFramework.NET框架SOA解决方案(集Windows服务、WinForm形式与IIS形式发布)-分布式应用

RDIFramework.NET代码生成器全新V3.5版本发布-重大升级


一路走来数个年头,感谢RDIFramework.NET框架的支持者与使用者,大家可以通过下面的地址了解详情。

RDIFramework.NET官方网站:http://www.rdiframework.net/

RDIFramework.NET官方博客:http://blog.rdiframework.net/

同时需要说明的,以后的所有技术文章以官方网站为准,欢迎大家收藏!

RDIFramework.NET框架由专业团队长期打造、一直在更新、一直在升级,请放心使用!

欢迎关注RDIFramework.net框架官方公众微信(微信号:guosisoft),及时了解最新动态。

扫描二维码立即关注

微信公众号开发C#系列-6、消息管理-普通消息接受处理_微信开发_13


标签:C#,微信,responseMessage,回复,requestMessage,id,消息
From: https://blog.51cto.com/guosisoft/6470951

相关文章

  • 微信公众号开发C#系列-5、用户和用户组管理-支持同步
    本文目录1、概述2、本地存放微信粉丝与分组的表结构3、主要接口实现方式3.1、同步指定用户到本地3.2、一键同步所有用户到本地4、关注与取消关注时自动同步本地用户情况4.1、订阅(关注)时的处理4.2、取消关注时的处理5、用户分组管理5.1、创建分组5.2、修改分组5.3、删除分组5.4、查......
  • 微信公众号开发C#系列-4、获取接口调用凭证
    本文目录概述怎么获取access_token?实现方式参考文章概述获取接口调用凭证实质就是获取access_token。在微信接口开发中,许多服务的使用都离不开AccessToken,AccessToken相当于打开这些服务的钥匙,正常情况下会在7200秒内失效,重复获取将导致上次获取的Token失效,本文将首先介绍如何......
  • C#如何进行多线程编程
    C#如何进行多线程编程由于多线程编程非常复杂,这个小例子只能算是一个入门线的知识点吧首先建一个应用程序项目,命名为ThreadExample,在窗体上放一个文本框(textBox1) ,一个标签(lblResult),再放两个按钮,分别命名为btnStart、btnStop。窗体代码:namespaceThreadExample{......
  • C++ Builder 初学问与答(二)
     2.文本输入组件11)问:如果要实现文本输入,在C++Builder中应该怎么办? 答:C++Builder常用文本输入组件来实现,常用的文本输入组件有Edit、MaskEdit、Memo和RichEdit。他们的主要不同在于Edit和MaskEdit用于输入单行文本,而Memo和RichEdit可以输入多行文本。此外Label组件也可用来进行......
  • C#连接MySql数据库的方法
     用MySQLDriverCS连接MySQL数据库   先下载和安装MySQLDriverCS,地址:   http://sourceforge.net/projects/mysqldrivercs/   在安装文件夹下面找到MySQLDriver.dll,然后将MySQLDriver.dll添加引用到项目中   注:我下载的是版本是MySQLDriverCS-n-EasyQueryTools-4.0......
  • C++ Builder 初学问与答(一)
    一直以来都想写一点为BCB初学者快速入门的东西,前不久写了几篇《闲谈BCB》想把自己学习BCB中如何来解决难点的方法说给大家,没想到被骂得不成样子。本想不写了,但觉得这些东西留下来能做什么呢?还是用另一种方法来重新演译我的思维吧,最近有些忙,那几篇没有写完的文章,我也会尽快写完的,至......
  • WinForm下DataGridView导出Excel的实现
    WinForm下DataGridView导出Excel的实现 1.说明:导出的效率说不上很高,但至少是可以接收的.参考网上很多高效导出Excel的方法,实现到时能够实现的,导出速度也很快,不过缺陷在与不能很好的进行单元格的格式化,比如上图中的"拼音码"字段中的值"000000000012120",在导出后就显示"1212......
  • 使用C#的WebService实现客户端软件的更新
    由于项目原因,要实施的客户离作者太远,考虑提供软件的在线升级功能.我们如何实现呢!先讲下思路.思路:先实现WEB端的开发,主要考虑使用WEBService技术,提供远程服务的调用函数,返回一个文件的字节内容,然后写一个升级程序客户端,分发给客户使用的机器中,(可以随客户的软件一起安装).......
  • 基于.NET的Web Service技术的分布式异构数据库的集成
    摘要:本文分析了WebService的特点,提出了一种基于Microsoft.NET的WebService技术访问分布异构数据库的体系结构,并采用.NET技术实现了原型系统。在原型系统中,使用WebService将分布于Internet上的不同的数据库系统中的数据集成,向访问数据库的应用程序提供统一的数据操作接口,实现......
  • Apache Http Server 路径穿越漏洞复现(CVE-2021-41773)
    ApacheHttpServer路径穿越漏洞复现ApacheHttpServer路径穿越漏洞概述ApacheHttpServer简介ApacheHTTPServer(简称Apache)是Apache软件基金会的一个开放源码的网页服务器软件,可以在大多数电脑操作系统中运行。由于其跨平台和安全性,被广泛使用,是最流行的Web服务器......