引言 在微信公眾號的開發中,自動回覆關鍵詞主要可回覆的內容為文本消息、圖文消息(目前僅支持一個鏈接)。為了讓關鍵詞支持“ 帶參數 ” 和 無限擴展 ,本文引入一個對接關鍵詞的介面規範,使得關鍵詞可以攜參數一起交由第三方處理,並返回用戶文本消息或圖文消息。 基本原理:為關鍵詞配置回調地址,關鍵詞與參數 ...
引言
在微信公眾號的開發中,自動回覆關鍵詞主要可回覆的內容為文本消息、圖文消息(目前僅支持一個鏈接)。為了讓關鍵詞支持“帶參數” 和 無限擴展,本文引入一個對接關鍵詞的介面規範,使得關鍵詞可以攜參數一起交由第三方處理,並返回用戶文本消息或圖文消息。
基本原理:為關鍵詞配置回調地址,關鍵詞與參數使用空格分隔,第一個空格後邊的均為參數,公眾號在接收到用戶文本消息後,解析關鍵詞與參數,並根據配置將其發送請求給回調地址,獲取返回的處理結果。
本文主要介紹介面的定義,並提供一個具體的介面實現。
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,就有可能成為“時間維度”公眾號里的實用工具供大家使用。如有興趣歡迎在“時間維度”留言。