回覆關鍵詞的無限擴展機制

引言

在微信公衆號的開發中,自動回覆關鍵詞主要可回覆的內容爲文本消息、圖文消息(目前僅支持一個鏈接)。爲了讓關鍵詞支持“帶參數” 和 無限擴展,本文引入一個對接關鍵詞的接口規範,使得關鍵詞可以攜參數一起交由第三方處理,並返回用戶文本消息或圖文消息。

基本原理:爲關鍵詞配置回調地址,關鍵詞與參數使用空格分隔,第一個空格後邊的均爲參數,公衆號在接收到用戶文本消息後,解析關鍵詞與參數,並根據配置將其發送請求給回調地址,獲取返回的處理結果。

本文主要介紹接口的定義,並提供一個具體的接口實現。

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 效果

在公衆號“時間維度”中,回覆關鍵詞提取,空格帶上內容,如下:

提取 各種格式的郵箱入下所示:[email protected][email protected] 3. [email protected] 4. [email protected] 5. [email protected] 6. [email protected] 7. [email protected] 8. [email protected] 9. [email protected]

會得到以下結果:

郵箱
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

回覆:

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

會得到:

郵箱
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
手機號
15758523729
18101710555
18300405945
身份證號
560087183004059455

3 招募關鍵詞

給定一個關鍵詞,一個接收關鍵詞及參數的 URL 地址,按約定的格式返回 JSON,就有可能成爲“時間維度”公衆號裏的實用工具供大家使用。如有興趣歡迎在“時間維度”留言。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章