zoukankan      html  css  js  c++  java
  • AI(三):微信与luis结合(上)

    目录

    • 基本原理
    • 公众号申请及配置
    • 验证服务器有效性
    • 微信请求消息类型

    基本原理


    • 基本原理如上图:腾讯微信服务器就相当于一个转发服务器,终端(手机、Pad等)发起请求至微信服务器,微信服务器然后将请求转发给我们的开发者服务器,在开发者服务器端可加入我们的业务处理逻辑(如:调用luis API 获取luis定义的Intent和Entity,接入业务处理逻辑),开发者服务器(应用服务器)处理完毕后,将响应数据回发给微信服务器,微信服务器再将具体响应信息回复到微信App终端
    • 通信协议为:HTTP
    • 数据传输格式为:XML

    公众号申请及配置


    • 申请地址: https://mp.weixin.qq.com/
    • 登陆系统,在开发->基本配置界面,设置服务器配置信息,包含服务器地址(URL)、Token和EncodingAESKey,如下图
    • 服务器地址即公众号后台提供业务逻辑的入口地址,包括接入验证以及任何其它操作的请求(例如消息的发送、菜单管理、素材管理等)都要从这个地址进入。
    • 接入验证和其它请求的区别就是,接入验证时是get请求,其它时候是post请求
    • Token: 用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)
    • EncodingAESKey: 将用作消息体加解密密钥

    验证服务器有效性


    • 录入服务器配置信息,点击“提交”按钮后,微信服务器将发送一个http的get请求到刚刚填写的服务器地址,并且携带四个参数
    • 接到请求后,需要做如下三步,若确认此次GET请求来自微信服务器,原样返回echostr参数内容,则接入生效,否则接入失败。

      1.  将token、timestamp、nonce三个参数进行字典序排序   

      2. 将三个参数字符串拼接成一个字符串进行sha1加密   

      3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

    • c#代码实现:1、创建空的web工程  2、添加wx.ashx文件  3、wx.ashx代码如下
      using System;
      using System.Collections.Generic;
      using System.IO;
      using System.Linq;
      using System.Web;
      using System.Web.Security;
      using System.Xml;
      
      namespace WXHandler
      {
          /// <summary>
          /// wx 的摘要说明
          /// </summary>
          public class wx : IHttpHandler
          {
              /// <summary>
              /// 
              /// </summary>
              /// <param name="context"></param>
              public void ProcessRequest(HttpContext context)
              {            
                  WXContext wxContext = new WXContext(context);
      
                  if (wxContext.IsHttpGet)  //校验签名,在公众平台填入服务器端配置信息提交之后检验使用
                  {               
                      ValidateUrl(wxContext);
                  }
                  else
                  {
                      HandleMsg(wxContext);
                  }
              }
      
              /// <summary>
              /// 
              /// </summary>
              /// <param name="wxContext"></param>
              private void ValidateUrl(WXContext wxContext)
              {
                  string echostr = string.Empty;
                  bool success = BasicAPI.CheckSignature(wxContext, out echostr);
                  if (success)
                  {
                      HttpContext context = HttpContext.Current;
                      context.Response.ContentType = "text/plain";
                      context.Response.Write(echostr);
                  }
              }
      
              /// <summary>
              /// 
              /// </summary>
              /// <param name="wxContext"></param>
              public void HandleMsg(WXContext wxContext)
              {
                  string msg = WeixinExecutor.Default.Execute(wxContext.WxMsg);
                  HttpContext context = HttpContext.Current;
                  context.Response.ContentType = "text/plain";
                  context.Response.Write(msg);
              }
             
              public bool IsReusable
              {
                  get
                  {
                      return false;
                  }
              }
          }
      }
      View Code
    •  检测代码:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Net.Http;
      using System.IO;
      
      namespace WXHandler
      {
          /// <summary>
          /// 对应微信API的 "基础支持"
          /// </summary>
          public class BasicAPI
          {
              /// <summary>
              /// 检查签名是否正确:
              /// </summary>
              /// <param name="wxContext"></param>
              /// <param name="echostr"></param>
              /// <returns></returns>
              public static bool CheckSignature(WXContext wxContext, out string echostr)
              {
                  var arr = new[] {wxContext.Token,wxContext.Timetamp,wxContext.Nonce}.OrderBy(z => z).ToArray();
                  var arrString = string.Join("", arr);
                  var sha1 = System.Security.Cryptography.SHA1.Create();
                  var sha1Arr = sha1.ComputeHash(Encoding.UTF8.GetBytes(arrString));
                  StringBuilder enText = new StringBuilder();
                  foreach (var b in sha1Arr)
                  {
                      enText.AppendFormat("{0:x2}", b);
                  }
                  echostr = enText.ToString();
                  return wxContext.Signature == enText.ToString();
              }
      
          }
      }
      View Code

    微信请求消息类型


    • 微信开发文档参见: https://mp.weixin.qq.com/wiki
    • 参见如下代码:包含有文本、语音、图片、位置等信息类型
    • 注意:开通语音识别后,用户每次发送语音给公众号时,微信会在推送的语音消息XML数据包中,增加一个Recongnition字段(注:由于客户端缓存,开发者开启或者关闭语音识别功能,对新关注者立刻生效,对已关注用户需要24小时生效。开发者可以重新关注此帐号进行测试)。
    • 在处理这些消息时,先可查看当前帐号已经获取的权限,位置:开发-->接口权限,默认情况,接收消息中的“接收语音识别结果”选项是关闭的
    • 实现代码如下:
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Web;
      using System.Text;
      using System.Text.RegularExpressions;
      using System.Threading.Tasks;
      using System.Runtime.Serialization;
      using System.IO;
      
      namespace WXHandler
      {
          /// <summary>
          /// 
          /// </summary>
          public class WeixinExecutor : IWeixinExecutor
          {
              /// <summary>
              /// 
              /// </summary>
              public static WeixinExecutor Default
              {
                  get { return new WeixinExecutor(); }
              }
      
              /// <summary>
              /// 
              /// </summary>
              /// <param name="message"></param>
              /// <returns>已经打包成xml的用于回复用户的消息包</returns>
              public string Execute(WeixinMessage message)
              {
                  string result = string.Empty;
                  var openId = message.Body.FromUserName.Value;
                  var myUserName = message.Body.ToUserName.Value;
                  switch (message.Type)
                  {
                      case WeixinMessageType.Text://文字消息
                          {
                              string userMessage = message.Body.Content.Value;
                              var BotMessage = LuisService.Default.PostMessage(userMessage);
                              result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, BotMessage);
                          }
                          break;
                      case WeixinMessageType.Image://图片消息
                          {
                              string imageUrl = message.Body.PicUrl.Value;//图片地址
      
                              var msg = ImageService.Default.PostMessage(imageUrl);
                              result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, msg);
                          }
                          break;
                      case WeixinMessageType.Voice://语音消息
                          {                        
                              var recognition = Convert.ToString(message.Body.Recognition.Value);
                              var BotMessage = LuisService.Default.PostMessage(recognition);
                              if (BotMessage == LuisInfos.DEFAULT_LUIS)
                                  BotMessage += string.Format(" 您输入的内容为:{0}", recognition);
                              result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, BotMessage);
                          }
                          break;
                      case WeixinMessageType.Location://地理位置消息
                          {
                              var location_X = message.Body.Location_X.Value.ToString();
                              var location_Y = message.Body.Location_Y.Value.ToString();
      
                              var BotMessage = LocationService.Default.PostMessage(location_Y, location_X);
                              result = ReplayPassiveMessageAPI.RepayText(openId, myUserName, BotMessage);
                          }
                          break;
                      case WeixinMessageType.Link://链接消息
                          {
                              var title = message.Body.Title.Value.ToString();
                              var description = message.Body.Description.Value.ToString();
                              var url = message.Body.Url.Value.ToString();
                              var msgId = message.Body.MsgId.Value.ToString();
                          }
                          break;
                      default:
                          result = ReplayPassiveMessageAPI.RepayText(openId, myUserName,"xxxxxx......");
                          break;
                  }
                  return result;
              }
          }
      }
      View Code
  • 相关阅读:
    过河卒 NOIp 2002 dp
    [POI2014]KUR-Couriers BZOJ3524 主席树
    【模板】可持久化线段树 1(主席树)
    EXPEDI
    取石子游戏 BZOJ1874 博弈
    【模板】文艺平衡树(Splay) 区间翻转 BZOJ 3223
    关于表白
    POJ 1951
    Codeforces 1032F Vasya and Maximum Matching dp
    Codeforces 1016F Road Projects
  • 原文地址:https://www.cnblogs.com/tgzhu/p/6219600.html
Copyright © 2011-2022 走看看