微信公共号回复关键词的无限扩展机制


微信公共号回复关键词的无限扩展机制

文章插图

引言
在微信公众号的开发中,自动回复关键词主要可回复的内容为文本消息、图文消息(目前仅支持一个链接) 。为了让关键词支持“带参数” 和 无限扩展,本文引入一个对接关键词的接口规范,使得关键词可以携参数一起交由第三方处理,并返回用户文本消息或图文消息 。
基本原理:为关键词配置回调地址,关键词与参数使用空格分隔,第一个空格后边的均为参数,公众号在接收到用户文本消息后,解析关键词与参数,并根据配置将其发送请求给回调地址,获取返回的处理结果 。
本文主要介绍接口的定义,并提供一个具体的接口实现 。
1 接口约定
1.1 传入参数
作为 Request.Body 请求体 POST 给回调地址 。
{ "keyword" : "Keyword", "parameter" : "Parameters string", "user" : "useropenid"}1.2 返回格式
返回结果为 JSON 形式,要求必须有 err_code 与 err_msg 属性,其中 err_code 为状态码,状态码为 200 时,表示成功,其它表示失败 。err_msg 表示消息描述 。如:
{ "err_code" : 101, "err_msg" : "操作失败!"}当成功时,支持返回“文字”与“链接”两种类型的消息 。
使用 key_type 属性表示,可取值“文字”或"链接" 。
当 key_type 为“文字”的时候,data 为相应的文本内容 。
当 key_type 为“链接”的时候,data 为链接信息的数组,只是目前只支持一个链接 。
链接的属性包括:
title : 标题
icon : 图标
note_desc : 描述
url : 链接地址
1.3 文字类型示例
{ "err_code" : 101, "err_msg" : "操作失败!", "key_type" : "文字", "data" : "回复的内容"}1.4 链接类型示例
{ "err_code" : 101, "err_msg" : "操作失败!", "key_type" : "链接", "data" : [ { "title" : "一个数学公式", "icon" : "http://****/formula.png", "note_desc" : "一个神寄的数学公式", "url" : "http://****" } ]}2 关键词接口示例
以下为一个完整的接口实现示例 。
2.1 功能需求描述
关键词:提取
参数:一段文本或仅是一个 url
功能描述:从文本中提取出邮箱、手机号、身份证号、IPv4 地址(可进一步补充与完善) 。如果参数仅是一个 url,则进行提取的文本为请求该 url 所得的内容 。
2.2 实现过程
流程:是否仅为url -> 是则请求url 得到内容 -> 根据正则表达式提取匹配数据 -> 根据长度返回文本消息 或是 返回一个可操作界面的链接 。
 
微信公共号回复关键词的无限扩展机制

文章插图
 
 
2.2.1%20准备好匹配的正则表达式
private%20static%20Dictionary<string,%20string>%20_RegexDict;public%20static%20Dictionary<string,%20string>%20RegexDict{%20get%20{%20if%20(_RegexDict%20==%20null)%20{%20_RegexDict%20=%20new%20Dictionary<string,%20string>();%20//%20_RegexDict.Add("链接",%20@"((ht)tps?)://[w-]+(.[w-]+)+([w-.,@?^=%&:/~+#]*[w-@?^=%&/~+#])?");%20%20_RegexDict.Add("邮箱",%20@"[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+");%20_RegexDict.Add("手机号",%20@"(((13[0-9]{1})|(14[0-9]{1})|(15[0-9]{1})|(17[0-9]{1})|(18[0-9]{1})|(19[0-9]{1}))+d{8})");%20_RegexDict.Add("身份证号",%20@"[1-9]d{5}(18|19|20)d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)d{3}[0-9Xx]");%20_RegexDict.Add("IPv4地址",%20@"(d|[1-9]d|1d{2}|2[0-4]d|25[0-5]).(d|[1-9]d|1d{2}|2[0-4]d|25[0-5]).(d|[1-9]d|1d{2}|2[0-4]d|25[0-5]).(d|[1-9]d|1d{2}|2[0-4]d|25[0-5])");%20}%20return%20_RegexDict;%20}}2.2.2%20处理过程
一个工具方法,请求%20url%20获取内容 。
public%20static%20string%20GetUrlContent(string%20url){%20System.Net.WebClient%20webClientObj%20=%20new%20System.Net.WebClient();%20webClientObj.Encoding%20=%20Encoding.UTF8;%20string%20respInfo%20=%20webClientObj.DownloadString(url);%20return%20respInfo;}处理流程实现,建立一个%20WebApi,代码如是说 。
public%20JObject%20Index([FromBody]%20JObject%20body){%20string%20keyword%20=%20body.Value<string>("keyword");%20string%20parameter%20=%20body.Value<string>("parameter");%20string%20user%20=%20body.Value<string>("user");%20JObject%20result%20=%20new%20JObject();%20if%20(!"提取".Equals(keyword))%20{%20result["err_code"]%20=%20101;%20result["err_msg"]%20=%20"关键词未找到";%20return%20result;%20}%20////%20处理过程%20%20var%20content%20=%20parameter;%20var%20regUrl%20=%20@"^((ht)tps?)://[w-]+(.[w-]+)+([w-.,@?^=%&:/~+#]*[w-@?^=%&/~+#])?$";%20%20//%20(1)%20为网址吗%20if%20(Regex.IsMatch(content,%20regUrl))%20{%20try%20{%20content%20=%20GetUrlContent(content);%20}%20catch%20(Exception%20ue)%20{%20result["err_code"]%20=%20101;%20result["err_msg"]%20=%20"站点无法连接!";%20return%20result;%20}%20}%20%20//(2)根据正则表达式提取%20Dictionary<string,%20List<string>>%20typeMatches%20=%20new%20Dictionary<string,%20List<string>>();%20foreach%20(var%20kv%20in%20RegexDict)%20{%20List<string>%20list%20=%20new%20List<string>();%20var%20mc%20=%20Regex.Matches(content,%20kv.Value,%20RegexOptions.IgnoreCase);%20foreach%20(Match%20c%20in%20mc)%20{%20list.Add(c.Value);%20}%20if%20(list.Count%20>%200)%20{%20typeMatches.Add(kv.Key,%20list);%20}%20}%20//(3)拼成字符串%20StringBuilder%20sb%20=%20new%20StringBuilder(1024);%20foreach%20(var%20kv%20in%20typeMatches)%20{%20sb.Append(kv.Key%20+%20"n"%20+%20String.Join("n",%20kv.Value)%20+%20"n");%20%20}%20//(4)长度<1020%20文本消息%20if%20(sb.Length%20<%201020)%20{%20result["err_code"]%20=%20200;%20result["err_msg"]%20=%20"success";%20result["key_type"]%20=%20"文字";%20result["data"]%20=%20sb.Length%20==%200%20?%20"无匹配内容!"%20:%20sb.ToString();%20return%20result;%20}%20//(5)长度较大,返回工具链接%20JObject%20link%20=%20new%20JObject();%20link["title"]%20=%20"提取内容中的格式化数据信息";%20link["icon"]%20=%20"http://www.timeddd.com/Content/images/logo_bar.png"; link["note_desc"] = "指定链接地址或文本内容,从中提取一些常格式数据,如邮箱、手机号、链接、身份证号等信息!"; link["url"] = "http://www.timeddd.com/Tool/Fetch"; JArray links = new JArray(); links.Add(link); result["err_code"] = 200; result["err_msg"] = "success"; result["key_type"] = "链接"; result["data"] = links; return result; }


推荐阅读