Asp.Net Core對接釘釘群機器人
釘釘作為企業辦公越來越常用的軟體,對於企業內部自研系統提供介面支援,以此來打通多平臺下的資料,本次先使用最簡單的釘釘群機器人完成多種形式的訊息推送,參考釘釘開發文件中 自定義機器人環節 ,此次嘗試所花的時間不多,但有幾個地方是需要注意的。
一、釘釘群中建立機器人獲取WebHook地址
首先得有一個釘釘群,如果沒有得自行建立一個了,通過群內右上角選單中找到群機器人然後新增一個自定義機器人
並設定訊息推送開啟(預設是開啟),複製下一行的webhook地址,該地址將作為後面訊息推送的地址
完成即可,如果不確定該地址是否有效可以用命令測試一下,比如在Linux平臺下,通過該命令並將自己的webhook_token替換
curl 'https://oapi.dingtalk.com/robot/send?access_token=cd1eb120c459ced6a65491af7b1eebbc84790fb672077a969bae8bb203aa1c52' \ -H 'Content-Type: application/json' \ -d ' {"msgtype": "text", "text": { "content": "我就是我, 是不一樣的煙火" } }'
然後回車進行測試,即刻收到群機器人推送的訊息
二、參考文件完成基礎類的封裝並處理相關欄位
接下來開始在程式碼中完成對WebHook地址的呼叫,可以先分析一下 群機器人的文件 ,可以獲悉有五種訊息型別: 文字 (text)、連線 (link)、markdown ( markdown)、ActionCard、FeedCard訊息型別 ,其中的actionCard分整體和獨立兩類。針對這些型別及給出的引數要求完成基礎類的設計和封裝, 以text型別為例:
其中的msgtype是五種訊息型別的字串,因此針對該部分設計一個列舉,作為訊息型別的區分。
/// <summary> /// 釘釘群機器人訊息型別列舉 /// </summary> public enum MsgTypeEnum { text, link, markdown, actionCard, feedCard }
設計一個text類並給定一個屬性Content,在設計時我們喜歡使用帕斯卡命名法,但是釘釘介面卻不允許,如果不做一些處理,直接使用Content屬性將會呼叫不通介面, 這點需要注意 ,使用Newtonjson提供的打包成json時用指定的名稱替換來滿足釘釘介面需求。
/// <summary> /// 文字型別 /// </summary> public class Text { /// <summary> /// 文字內容 /// </summary> [JsonProperty(PropertyName = "content")] public string Content { get; set; } }
其次對指定人群做一個類的封裝,同樣需要處理其中的屬性在序列化時的替換名稱。
/// <summary> /// @指定人 /// </summary> public class At { /// <summary> /// @的聯絡人 /// </summary> [JsonProperty(PropertyName = "atMobiles")] public List<string> AtMobiles { set; get; } /// <summary> /// 是否@所有人 /// </summary> [JsonProperty(PropertyName = "isAtAll")] public bool IsAtAll { set; get; } }
通過分析五種訊息型別,其中的一些引數可以完成共用,對自定義釘釘機器人文件的一系列挖掘後,確定了這幾個類和列舉
接下來可以完成對機器人呼叫了並使用不同訊息型別推送到釘釘群中。
三、完成對釘釘群機器人的呼叫
首先在ConfigureService方法中完成對HttpClientFactory的注入
本次直接在Asp.Net Core WebApi下完成機器人的呼叫,新建一個DingTalk的控制器,然後完成對IHttpClientFactory的注入工作,便開始接下來的服務呼叫了,對於釘釘的WebHook_Token的存放可以選擇配置檔案或是如果只是嘗試,可以直接用一個變數儲存即可。
/// <summary> /// 傳送釘釘訊息介面 /// </summary> [Route("api/[controller]")] [ApiController] public class DingTalkController : ControllerBase { private readonly string WebHook_Token = "https://oapi.dingtalk.com/robot/send?access_token=cd1eb120c459ced6a65491af7b1eebbc84790fb672077a969bae8bb203aa1c52"; private readonly IHttpClientFactory _httpClientFactory; public DingTalkController(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; } }
再次以text文字為例並完成文字訊息的推送,建立一個action,用來發送文字訊息,在其中完成對釘釘介面需要引數的組裝工作,最終使用統一的傳送方法完成訊息推送。
/// <summary> /// 呼叫釘釘機器人傳送文字內容 /// </summary> /// <returns></returns> [HttpGet] [Route(nameof(TextContent))] public async Task<ActionResult> TextContent() { //訊息型別 var msgtype = MsgTypeEnum.text.ToString(); //文字內容 var text = new Text { Content = "看萬山紅遍,層林盡染;漫江碧透,百舸爭流@15675120617" }; //指定目標人群 var at = new At() { AtMobiles = new List<string>() { "15675120617" }, IsAtAll = false }; var response = await SendDingTalkMessage(new { msgtype, text, at }); return Ok(response); }
對於傳送方法內需要根據釘釘文件的一些要求完成設計,如文件指明需要使用 Post提交請求 並使用 UTF8編碼, 我直接在控制器內新建了一個方法(儘管不太合理),首先對內容進行序列化並封裝,然後通過HttpClientFactory新建client並完成傳送訊息。
/// <summary> /// 執行傳送訊息 /// </summary> /// <param name="sendMessage"></param> /// <returns></returns> private async Task<HttpResponseMessage> SendDingTalkMessage(object value) { var sendMessage = JsonConvert.SerializeObject(value); var request = new HttpRequestMessage(HttpMethod.Post, WebHook_Token) { //釘釘文件需指定UTF8編碼 Content = new StringContent(sendMessage, Encoding.UTF8, "application/json") }; var client = _httpClientFactory.CreateClient(); var response = await client.SendAsync(request); return response; }
啟動程式並通過url訪問控制器內的相應方法完成訊息推送,注意各屬性的命名方式或通過特性轉換後的命名方式需要滿足釘釘介面文件(文件中FeedCard型別後兩個引數不太標準)。
倉庫地址: https://gitee.com/530521314/koInstance/tree/master/src/koInstance.WebApi
歡迎關注微信訂閱號,有新的文章將同步到訂閱號中
2019-03-02,望技術有成後能回來看見自己的腳步