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