回复关键词的无限扩展机制

引言

在微信公众号的开发中,自动回复关键词主要可回复的内容为文本消息、图文消息(目前仅支持一个链接)。为了让关键词支持“带参数” 和 无限扩展,本文引入一个对接关键词的接口规范,使得关键词可以携参数一起交由第三方处理,并返回用户文本消息或图文消息。

基本原理:为关键词配置回调地址,关键词与参数使用空格分隔,第一个空格后边的均为参数,公众号在接收到用户文本消息后,解析关键词与参数,并根据配置将其发送请求给回调地址,获取返回的处理结果。

本文主要介绍接口的定义,并提供一个具体的接口实现。

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 准备好匹配的正则表达式
private static Dictionary<string, string> _RegexDict;
public static Dictionary<string, string> RegexDict
{
    get
    {
        if (_RegexDict == null)
        {
            _RegexDict = new Dictionary<string, string>();
            // _RegexDict.Add("链接", @"((ht)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?"); 
            _RegexDict.Add("邮箱", @"[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+");
            _RegexDict.Add("手机号", @"(((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})");
            _RegexDict.Add("身份证号", @"[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]");
            _RegexDict.Add("IPv4地址", @"(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])");
        }
        return _RegexDict;
    }
}
2.2.2 处理过程

一个工具方法,请求 url 获取内容。

public static string GetUrlContent(string url)
{
    System.Net.WebClient webClientObj = new System.Net.WebClient();
    webClientObj.Encoding = Encoding.UTF8;
    string respInfo = webClientObj.DownloadString(url);
    return respInfo;
}

处理流程实现,建立一个 WebApi,代码如是说。

public JObject Index([FromBody] JObject body)
{
    string keyword = body.Value<string>("keyword");
    string parameter = body.Value<string>("parameter");
    string user = body.Value<string>("user");
    JObject result = new JObject();
    if (!"提取".Equals(keyword))
    {
        result["err_code"] = 101;
        result["err_msg"] = "关键词未找到";
        return result;
    }

    //// 处理过程 
    var content = parameter;
    var regUrl = @"^((ht)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$";
  
    // (1) 为网址吗
    if (Regex.IsMatch(content, regUrl))
    {
        try
        {
            content = GetUrlContent(content);
        }
        catch (Exception ue)
        {
            result["err_code"] = 101;
            result["err_msg"] = "站点无法连接!";
            return result;
        }
    }
             
    //(2)根据正则表达式提取
    Dictionary<string, List<string>> typeMatches = new Dictionary<string, List<string>>();
    foreach (var kv in RegexDict)
    {
        List<string> list = new List<string>();
        var mc = Regex.Matches(content, kv.Value, RegexOptions.IgnoreCase);
        foreach (Match c in mc)
        {
            list.Add(c.Value);
        }

        if (list.Count > 0)
        {
            typeMatches.Add(kv.Key, list);
        }
    }


    //(3)拼成字符串
    StringBuilder sb = new StringBuilder(1024);
    foreach (var kv in typeMatches)
    {
        sb.Append(kv.Key + "\n" + String.Join("\n", kv.Value) + "\n"); 
    }

    //(4)长度<1020 文本消息
    if (sb.Length < 1020)
    {
        result["err_code"] = 200;
        result["err_msg"] = "success";
        result["key_type"] = "文字";
        result["data"] = sb.Length == 0 ? "无匹配内容!" : sb.ToString();
        return result;
    }

    //(5)长度较大,返回工具链接
    JObject link = new JObject();
    link["title"] = "提取内容中的格式化数据信息";
    link["icon"] = "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;              
}

3 效果

在公众号“时间维度”中,回复关键词提取,空格带上内容,如下:

提取 各种格式的邮箱入下所示:kevintian126@126.com1136667341@qq.com 3. meiya@cn-meiya.com 4. wq901200@hotmail.com 5. meiyahr@163.com 6. meiyuan@0757info.com 7. chingpeplo@sina.com 8. tony@erene.com.com 9. melodylu@buynow.com

会得到以下结果:

邮箱
kevintian126@126.com
1136667341@qq.com
meiya@cn-meiya.com
wq901200@hotmail.com
meiyahr@163.com
meiyuan@0757info.com
chingpeplo@sina.com
tony@erene.com.com
melodylu@buynow.com

回复:

提取 https://www.nhxz.com/doc/181017fc325d4b598aaede18.html

会得到:

邮箱
kevintian126@126.com
1136667341@qq.com
meiya@cn-meiya.com
wq901200@hotmail.com
meiyahr@163.com
meiyuan@0757info.com
chingpeplo@sina.com
tony@erene.com.com
melodylu@buynow.com
xxxxxx@163.com
123321@126.com
手机号
15758523729
18101710555
18300405945
身份证号
560087183004059455

3 招募关键词

给定一个关键词,一个接收关键词及参数的 URL 地址,按约定的格式返回 JSON,就有可能成为“时间维度”公众号里的实用工具供大家使用。如有兴趣欢迎在“时间维度”留言。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,662评论 0 15
  • Getting Started Burp Suite 是用于攻击web 应用程序的集成平台。它包含了许多工具,并为...
    Eva_chenx阅读 28,623评论 0 14
  • width: 65%;border: 1px solid #ddd;outline: 1300px solid #...
    邵胜奥阅读 4,764评论 0 1
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,365评论 0 5
  • 作者:12月发布于6月15日 晚12:03分 正文: 昨夜下过雨,空气湿湿凉凉很清新。一条宽广的细石子路伸向远处,...
    我们遇见的书阅读 873评论 1 8