• 微信公众号开发之回复图文消息(被动)


    目录

    (一)微信公众号开发之VS远程调试
    (二)微信公众号开发之基础梳理
    (三)微信公众号开发之自动消息回复和自定义菜单
    (四)微信公众号开发之网页授权获取用户基本信息
    (五)微信公众号开发之网页中及时获取当前用户Openid及注意事项
    (六)微信公众号开发之扫码支付
    (七)微信公众号开发之公众号支付
    (八)微信公众号开发之现金红包
    (九)微信公众号开发之回复图文消息(被动)

    题记:

      .NET Core 经过几年的发展,已经可以说是遍地开花了,现在如果还不展开.NET Core探索之路,那未免也太有点落后于.NET的时代潮流了.

    前几篇已经提及到了关注和回复消息事件,但此前都局限于回复文本消息。那么,如果有个需求是,用户发送特定字符,如何回复特定的图文消息给用户呢?

    首先我们来看看实现后的效果如下:

    实现过程

    回复图片消息

    我们先看一下 回复图文消息的XML字符格式

    <xml>
      <
    ToUserName><![CDATA[toUser] ]></ToUserName>
      <
    FromUserName>< ![CDATA[fromUser] ]></FromUserName>
      <
    CreateTime>12345678</CreateTime>
      <
    MsgType><![CDATA[image] ]></MsgType>
      <
    Image><MediaId><![CDATA[media_id] ]></MediaId></Image>
    </
    xml>

    根据这个XML格式,我们很清楚已经知道这个地方需要用到几个必要的参数,包括:OpenID,微信号、创建时间、封面图片以及Mediald这些。

    我们这个是在.NET Core2.1上实现的,这里稍微说明下,此前我们在.NET 4.5中使用的一般处理程序是这样写的:

    public void ProcessRequest(HttpContext context)
    {
          //TODO      
    }

    ASP.NET Core中提供了一个IHttpContextAccessor接口,HttpContextAccessor 默认实现了它简化了访问HttpContext。

    它必须在程序启动时在ConfigureServices中注册,这样在程序中就能获取到HttpContextAccessor,并用来访问HttpContext。

    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

    然后我们在控制器中注入进来

            private readonly IHttpContextAccessor _accessor;
            public HandlerController(IHttpContextAccessor accessor)
            {
                _accessor = accessor;
            }
            [Route("ProcessRequest")]
            public void ProcessRequest()
            {
                var context = _accessor.HttpContext;
                context.Response.ContentType = "text/plain";
                string responseMsg = Response(context.Request);
                context.Response.Clear();
                context.Response.ContentType = "UTF-8";
                context.Response.WriteAsync(responseMsg);
            }

    好了,前面是一些铺垫,代码部分和之前.NET 相差无几,玩.NET Core 记住一句话:无处不在的依赖注入。

    这里,我们提前将一些用到的关键词以及上面提到的必要参数放到appsetting.json配置中,方面后面修改。

     "new_images_messages": {
        "keyword": "触发的关键字",
        "validTime": "2018-12-28",
        "title": "文章标题",
        "description": "描述",
        "picUrl": "图片url",
        "url": "图文消息的url"
      }

    另外,我这里采用读取配置的方式封装了一层,在Startup中DI进IConfiguration 接口

    注:需要引入

    using Microsoft.Extensions.Configuration;
          public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }

     然后新建一个ConfigurationKeys 类,专门存放配置文件中不同类型的数据值:

            public static string NEW_IMAGES_MESSAGES_TITLE = "new_images_messages:title";
    
            public static string NEW_IMAGES_MESSAGES_DES = "new_images_messages:description";
    
            public static string NEW_IMAGES_MESSAGES_PIC = "new_images_messages:picUrl";
    
            public static string NEW_IMAGES_MESSAGES_URL = "new_images_messages:url";
    
            public static string NEW_IMAGES_MESSAGES_KEYWORD = "new_images_messages:keyword";
    
            public static string NEW_IMAGES_MESSAGES_VALIDTIME = "new_images_messages:validTime";

    使用时首先在控制器中注入配置接口

    private readonly IConfiguration _config;
    public EventHandler(IConfiguration config)
    {
      _config = config;
    }

    与发过来消息做对比

    //判断接收到的文本消息是否是配置文件中的触发关键词  
    if (content == _config[ConfigurationKeys.NEW_IMAGES_MESSAGES_KEYWORD])
    {
          _logger.LogInformation("答复图文消息");
          response =ReArticle(tm.FromUserName, tm.ToUserName);
    }
      public string ReArticle(string fromUserName, string toUserName)
      {
          var title = _config[ConfigurationKeys.NEW_IMAGES_MESSAGES_TITLE];
          var description = _config[ConfigurationKeys.NEW_IMAGES_MESSAGES_DES];
          var picUrl = _config[ConfigurationKeys.NEW_IMAGES_MESSAGES_PIC];
          var url = _config[ConfigurationKeys.NEW_IMAGES_MESSAGES_URL];
          return new NewsMessage().Template(fromUserName, toUserName, title, description, picUrl, url);
      }

    这里需要将模板提前配置好,所以这里新建了一个Template方法

    public string Template(string fromUserName, string toUserName, string title, string description, string picUrl, string url)
    {
                string xml = "<xml><ToUserName><![CDATA[" + fromUserName + "]]></ToUserName><FromUserName><![CDATA[" + toUserName + "]]></FromUserName>";
                xml += "<CreateTime>" + FileUtility.DateTimeToUnixTimestamp(DateTime.Now) + "</CreateTime>";
                xml +="<MsgType><![CDATA[news]]></MsgType><Content><![CDATA[]]></Content><ArticleCount>1</ArticleCount><Articles>";
                xml += "<item><Title><![CDATA[" + title + "]]></Title><Description><![CDATA[" + description +"]]></Description><PicUrl><![CDATA[" + picUrl + "]]></PicUrl><Url><![CDATA[" + url +"]]></Url></item>";
                xml += "</Articles><FuncFlag>0</FuncFlag></xml>";
                return xml;
    }

     上述的时间转换方法

    public static long DateTimeToUnixTimestamp(DateTime dateTime)
    {
        var start = new DateTime(1970, 1, 1, 0, 0, 0, dateTime.Kind);
        return Convert.ToInt64((dateTime - start).TotalSeconds);
    }

     至此,已经全部实现,那如果项目已经上线,需要增加这个功能项,但是又不能破坏现有服务器,如何进行调试呢,可以借助微信的测试号,用于在线调试公众号。

     地址:微信测试号

    进入测试号里面,有appID,appsecret我们需要将这两个信息替换本地的TokenContext中的值。然后URL可以借助花生壳等内网穿透的工具 映射到本地 进行开发调试。

    整体做完就可以实现开始的展示图的效果了。

           End

  • 相关阅读:
    URL解析模式(伪静态)
    PHP各环境下的伪静态配置
    亚马逊-购书(电子)
    前端路由-JS实现
    SpringBoot 2.3.0.RELEASE版本后自定义404页面,SpringBoot 404错误兼容Ajax请求
    不设置DIV宽度水平居中,div不设置宽度居中
    js 保留两位小数,Js四舍五入,JavaScript Math四舍五入
    Laravel 自定义公共函数的引入
    EF Core3.1 CodeFirst动态自动添加表和字段的描述信息
    Android 高德地图API INVALID_USER_SCODE 错误
  • 原文地址:https://www.cnblogs.com/zhangxiaoyong/p/10161188.html
Copyright © 2020-2023  润新知