C#微信公众号开发之消息处理

前言:

回顾上一节服务器配置的内容,我们已经可以自己完成公众号服务器的配置。配置完成之后,我们就可以通过调用的方式,完成对消息管理的处理。当用户关注公众号或者发送消息的时候,我们应该启用默认回复,要不然用户得不到回应,

从而导致丢失体验。所以这一章节,我们将通过消息管理的方式,对用户的信息进行处理,完成公众号消息回复功能,实现公众号与用户之间的完整对话。

了解:

微信公众平台对信息做了比较清晰的分类,最基本的包括请求(Request)和响应(Response)两大类信息,这两类信息有分为文字、语音、图片等格式。Senparc.Weixin.MP提供了MessageHandler消息处理类,这些类型在以枚举的方式区分,

同时根据严格命名规则命名了所有类型的RequestMessage和ResponseMessage。在Senparc里也详细说明了如何这个类的

开始:

第一步:

新建一个UserMessageHandler.cs,需要继承Senparc.Weixin.MP.MessageHandlers<TC>这个抽象类,并重写所有方法:

    public class UserMessageHandler : MessageHandler<UserMessageContext>
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="inputStream">构造函数的inputStream用于接收来自微信服务器的请求流(如果需要在外部处理,这里也可以传入XDocument)</param>
        /// <param name="postModel">微信公众服务器Post过来的加密参数集合(不包括PostData)</param>
        public UserMessageHandler(Stream inputStream, PostModel postModel)
            : base(inputStream, postModel)
        {

        }
        public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
        {
            /* 所有没有被处理的消息会默认返回这里的结果
            */
            var responseMessage = this.CreateResponseMessage<ResponseMessageText>();//ResponseMessageText也可以是News等其他类型
            responseMessage.Content = "这条消息来自DefaultResponseMessage。";
            return responseMessage;
        }
    }
using Senparc.Weixin.Context;
using Senparc.Weixin.MP.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WeiXinHandler
{
    public class UserMessageContext: MessageContext<IRequestMessageBase, IResponseMessageBase>
    {
        public UserMessageContext()
        {
            /*
            * 注意:即使使用其他类实现IMessageContext,
            * 也务必在这里进行下面的初始化,尤其是设置当前时间,
            * 这个时间关系到及时从缓存中移除过期的消息,节约内存使用
            */
            base.MessageContextRemoved += UserMessageContext_MessageContextRemoved;
        }

        /// <summary>
        /// 当上下文过期,被移除时触发的时间
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void UserMessageContext_MessageContextRemoved(object sender, Senparc.Weixin.Context.WeixinContextRemovedEventArgs<IRequestMessageBase, IResponseMessageBase> e)
        {
            /* 注意,这个事件不是实时触发的(当然你也可以专门写一个线程监控)
             * 为了提高效率,根据WeixinContext中的算法,这里的过期消息会在过期后下一条请求执行之前被清除
             */
            var messageContext = e.MessageContext as CustomMessageContext;
            if (messageContext == null)
            {
                return;//如果是正常的调用,messageContext不会为null
            }
            //TODO:这里根据需要执行消息过期时候的逻辑,下面的代码仅供参考
            //Log.InfoFormat("{0}的消息上下文已过期",e.OpenId);
            //api.SendMessage(e.OpenId, "由于长时间未搭理客服,您的客服状态已退出!");
        }
    }
}

重写的方法对应了接收不同的Request类型,构造函数的inputStream用于接收来自微信服务器的请求流

第二步:

基本用户不同类型的请求,比如用户向我们发送一条信息,那么会最终会调用OnTextRequest这个方法,所以在不同的重写方法内,实现自己的方法。

比如:我们对于文字(Text)信息进行这样的处理,在UserMessageHandler中我们可以重写方法OnTextRequest:

        public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
        {
            var responseMessage = base.CreateResponseMessage<ResponseMessageText>();
            responseMessage.Content = "您刚刚发送了文字信息:" + requestMessage.Content;  //requestMessage.Content即用户发过来的文字内容
            return responseMessage;
        }

对于图片信息进行这样的处理,在UserMessageHandler中我们可以重写方法OnImageRequest

        /// <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 = "https://www.cnblogs.com/i3yuan/"
            });
            return responseMessage;
        }

对于语音信息进行这样的处理,在UserMessageHandler中我们可以重写方法OnVoiceRequest

        /// <summary>
        /// 处理语音请求
        /// </summary>
        /// <param name="requestMessage"></param>
        /// <returns></returns>
        public override IResponseMessageBase OnVoiceRequest(RequestMessageVoice requestMessage)
        {

            //获取公众号
            AccessTokenResult account = Senparc.Weixin.MP.CommonAPIs.CommonApi.GetToken(AppId, AppSecret);

            var responseMessage = CreateResponseMessage<ResponseMessageMusic>();
            //上传缩略图
            var uploadResult = Senparc.Weixin.MP.AdvancedAPIs.MediaApi.UploadTemporaryMedia(account.access_token, UploadMediaFileType.image,
                                                         Server.GetMapPath("~/Images/Logo.jpg"));

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

对于视频信息进行这样的处理,在UserMessageHandler中我们可以重写方法OnVideoRequest

        /// <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;
        }

对于地理信息进行这样的处理,在UserMessageHandler中我们可以重写方法OnLocationRequest

        /// <summary>
        /// 处理位置请求
        /// </summary>
        /// <param name="requestMessage"></param>
        /// <returns></returns>
        public override IResponseMessageBase OnLocationRequest(RequestMessageLocation requestMessage)
        {
            var locationService = new LocationService();
            var responseMessage = locationService.GetResponseMessage(requestMessage as RequestMessageLocation);
            return responseMessage;
        }

对于链接信息进行这样的处理,在UserMessageHandler中我们可以重写方法OnLinkRequest

        /// <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;
        }

第三步:

在Action中使用MessageHandler,返回对用户的处理,在上一节中我们已经新建了WXController.cs,在其中通过Post的方式处理用户的请求

        [HttpPost]
        [ActionName("Index")]
        public Task<ActionResult> Post(PostModel postModel)
        {
            return Task.Factory.StartNew<ActionResult>(() =>
            {
                if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token))
                {
                    return new WeixinResult("参数错误!");
                }
                var messageHandler = new UserMessageHandler(Request.InputStream);
                messageHandler.Execute(); //执行微信处理过程
                return new FixWeixinBugWeixinResult(messageHandler);
            }).ContinueWith<ActionResult>(task => task.Result);
        }

messageHandler.Execute();用于执行整个信息处理过程,其中会调用重写的OnxxRequest方法

效果:

测试发送文本

通过测试公众号,我们可以发现,当我们发送文本的时候,系统会对用户的信息进行处理,完成公众号消息回复功能,实现公众号与用户之间的完整对话。

测试发送图文消息

        public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
        {
            var responseMessage = CreateResponseMessage<ResponseMessageNews>();
            responseMessage.Articles.Add(new Article()
            {
                Title = "灌篮高手",
                Description = "灌篮高手",
                PicUrl = "http://images.cnblogs.com/cnblogs_com/i3yuan/1462639/o_timg%20(1).jpg",
                Url = "https://www.cnblogs.com/i3yuan/"
            });
            return responseMessage;

        }

总结:

1.通过MessageHandler的简单处理,我们就可以进行对用户文本消息的处理,完成公众号与用户的会话

2.发送不同的消息,处理不同的回复,实现更多类型的消息回复

3.参考了如何使用MessageHandler简化消息处理流程

到此这篇关于C#微信公众号开发之消息处理的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#微信公众号与订阅号接口开发示例代码

    本文实例讲述了C#微信公众号与订阅号接口开发示例代码.分享给大家供大家参考,具体如下: using System; using System.Web; using System.IO; using System.Text; using System.Web.Security; using weixin_api; public class wxgz_api : IHttpHandler { public void ProcessRequest(HttpContext context) { cont

  • C#微信公众号开发之接收事件推送与消息排重的方法

    本文实例讲述了C#微信公众号开发之接收事件推送与消息排重的方法.分享给大家供大家参考.具体分析如下: 微信服务器在5秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次.这样的话,问题就来了.有这样一个场景:当用户关注微信账号时,获取当前用户信息,然后将信息写到数据库中.类似于pc端网站的注册.可能由于这个关注事件中,我们需要处理的业务逻辑比较复杂.如送积分啊,写用户日志啊,分配用户组啊.等等--一系列的逻辑需要执行,或者网络环境比较复杂,无法保证5秒内响应当前用户的操作,那如果当操作尚未完

  • C#微信开发之微信公众号标签管理功能

    微信公众号,仿照企业号的思路,增加了标签管理的功能,对关注的粉丝可以设置标签管理,实现更加方便的分组管理功能.开发者可以使用用户标签管理的相关接口,实现对公众号的标签进行创建.查询.修改.删除等操作,也可以对用户进行打标签.取消标签等操作.本篇随笔主要介绍如何利用C#对公众号这个较新的特性进行封装,实现对标签的管理功能. 1.标签功能介绍 1)标签功能替代分组功能,支持多维度定义用户属性 运营者可登录公众平台后台,点击左侧菜单"用户管理"后管理已关注用户,点击其中一个用户右侧的&quo

  • C#微信公众号开发之服务器配置

    前言: 如果让大家说出一款国内比较热门的社交软件,那无疑就是QQ和微信了,说到微信,无不例外的会想到微信公众号和小程序,所以现在它们已经是很多企业流量及品牌推广的主要途径, 而作为一个开发者而言呢,如果想要开发打造一款属于自己或企业的公众号,就是需要对微信公众号平台API文档的熟悉. 你可以花上半天的时间大致阅读一下文档微信公众号开发文档 资源: 当你大致了解了微信公众号开发文档之后,就可以开始入手了 1.需要登录微信公众号平台https://mp.weixin.qq.com/ 2.注册公众号账

  • C#微信公众号开发 微信事件交互

    前言 一切准备工作就绪时就先实现一个关注公众号后向客户端推送一条消息.关注后推送消息需要一个get请求.一个post请求,get请求主要是为了向微信服务器验证,post请求主要就是处理微信消息了. 调接口时传递的appid和appsecret请传递自己公众号对应的参数. 微信事件交互 微信事件交互主要是向微信服务器推送XML数据包 看效果 看代码 [HttpGet] [ActionName("Index")] public ActionResult Get(string signatu

  • C#开发微信公众号接口开发

    具体实现方式不多说了,请看下文 一.前言 当下微信公众号几乎已经是每个公司必备的,但是大部分微信公众账号用户体验都欠佳,特别是涉及到用户绑定等,需要用户进行复杂的操作才可以和网站绑定,或者很多公司直接不绑定,而是每次都让用户填写账号密码.作为微信接口开发人员我们知道网页授权可以用作微信网页用作安全登录,带参数二维码的使用用作记录用户来源,模板消息用作购物消费等消息的通知,但是很少看到有综合利用这些高级接口做出体验比较好的公众账号,这里分享一些我开发的用户绑定和验证码的一些心得.所需要的接口有基础

  • C#微信公众号开发之消息处理

    前言: 回顾上一节服务器配置的内容,我们已经可以自己完成公众号服务器的配置.配置完成之后,我们就可以通过调用的方式,完成对消息管理的处理.当用户关注公众号或者发送消息的时候,我们应该启用默认回复,要不然用户得不到回应, 从而导致丢失体验.所以这一章节,我们将通过消息管理的方式,对用户的信息进行处理,完成公众号消息回复功能,实现公众号与用户之间的完整对话. 了解: 微信公众平台对信息做了比较清晰的分类,最基本的包括请求(Request)和响应(Response)两大类信息,这两类信息有分为文字.语

  • java微信公众号开发案例

    微信公众号开发一般是针对企业和组织的,个人一般只能申请订阅号,并且调用的接口有限,下面我们就来简单的描述下接入公众号的步骤: 1.首先你需要一个邮箱在微信公众号平台进行注册:      注册的方式有订阅号.公众号.小程序和企业号,个人我们这里只能选择订阅号 2.注册完后,我们登录到公众号平台--->开发--->基本配置,这里需要填写URL和token,URL就是我们使用服务器的接口: 3.Java Web服务器程序编译好且在服务器上部署可以运行的话,可在微信公众号进行在线接口调试: 1).选择

  • C#微信公众号开发之自定义菜单

    前言: 回顾之前的微信公众号配置和消息处理的内容,我们已经掌握了如何配置服务器与微信公众号建立连接,也掌握了通过消息管理的方式,对用户的信息进行处理,完成公众号消息回复功能,实现公众号与用户之间的完整对话.而在本文将针对自定义菜单做简单的开发应用,微信公众平台具有自定义菜单的功能.开发者可利用该功能为公众账号的会话界面底部增加自定义菜单,用户点击菜单中的选项,可以调出相应的回复信息或网页链接.自定义菜单接口将为公众账号的信息展示空间提供更多可能性. 说明: 1.自定义菜单最多包括3个一级菜单,每

  • java微信公众号开发(搭建本地测试环境)

    俗话说,工欲善其事,必先利其器.要做微信公众号开发,两样东西不可少,那就是要有一个用来测试的公众号,还有一个用来调式代码的开发环境. 测试公众号 微信公众号有订阅号.服务号.企业号,在注册的时候看到这样的信息,只有订阅号可以个人申请,服务号和企业号要有企业资质才可以.这里所说的微信公众号开发指的是订阅号和服务号. 另外,未认证的个人订阅号有一些接口是没有权限的,并且目前个人订阅号已不支持微信认证,也就是说个人订阅号无法调用一些高级的权限接口,下图就是一个未认证的个人订阅号所具备权限列表,像生成二

  • php微信公众号开发模式详解

    学习步骤:分四章来讲述这部分内容,下面是每章的大致内容. 1.了解开发模式与编辑模式,开发前的一些准备. 2.开发模式用户.微信服务器.个人服务器是如何交互的.什么是接口. 3.各种接口功能的调用与实现. 4.js-SDK的调用 微信公众号开发两种模式:编辑模式和开发模式.编辑模式比较简单,你不需要操作任何的代码,只需要借助微信提供的功能来管理自己的微信公众号.这种方式开发的页面比较简单,主要用来实现文章的推送等功能.开发者模式则能通过自己的后台服务器与微信关注用户实现更多的交互作用,调用微信的

  • PHP微信公众号开发之微信红包实现方法分析

    本文实例讲述了PHP微信公众号开发之微信红包实现方法.分享给大家供大家参考,具体如下: 这几天遇到了一个客户 要给他们的微信公众平台上添加微信现金红包功能,是个二次开发的功能,顺手百度一下,原来不复杂.就着手开发功能了.现将开发的过程和需求贴出来分享一下: 一.需求: 粉丝通过在客户的公众平台点击他们公司的订单,然后给这个订单返现五元,发到订单的这个微信号上. 二.开发想法: 1:先拿到关注这个粉丝的openid,openid是关注某个公众号的微信标识,这样就可以定位到这个人是订单的操作者了.

  • 微信公众号开发之微信公共平台消息回复类实例

    本文实例讲述了微信公众号开发之微信公共平台消息回复类.分享给大家供大家参考.具体如下: 微信公众号开发代码我在网上看到了有不少,其实都是大同小义了都是参考官方给出的demo文件进行修改的,这里就给各位分享一个. 复制代码 代码如下: <?php /**  * 微信公共平台消息回复类  *  *  */ class BBCweixin{    private $APPID="******";  private $APPSECRET="******";  /*  

  • 详解nodejs微信公众号开发——2.自动回复

    上一篇文章:nodejs微信公众号开发(1)接入微信公众号,本篇文章将在此基础上实现简单的回复功能. 1. 接入代码的优化 之前我们简单粗暴的实现了微信公众号的接入,接入的代码直接写在了app.js文件里面,从项目开发的角度而言,不便于日后代码的维护,所以将这部分代码独立出来,按照koa的风格,写成一个中间件. 在根目录下新建wechat文件夹,新建generator.js文件, var sha1 = require('sha1'); module.exports = function(opts

  • 详解nodejs微信公众号开发——6.自定义菜单

    上一篇文章:nodejs微信公众号开发--5.素材管理接口,我们实现了新增临时素材.管理永久素材的接口,这些接口的实现,使我们能够推送多样的消息给用户.本节介绍的内容是关于自定义菜单 1. 自定义菜单的介绍 自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的功能.关于自定义菜单需要掌握以下几点内容: 自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单. 一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以"..."代替. 创建自定义菜单后,由于微信客

随机推荐