C#實現(xiàn)釘釘消息推送過程
前言
想起之前有個項目需要使用釘釘消息推送報警數(shù)據(jù)到群里,提醒群里人員知道設(shè)備報警。
這篇是通過C#實現(xiàn)釘釘消息推送,因為釘釘機器人設(shè)定需設(shè)置安全設(shè)置,有三個(自定義關(guān)鍵詞、加簽、IP地址(段)),目前是設(shè)置自定義關(guān)鍵詞通過C#消息推送。
一、釘釘機器人如何設(shè)置
1、釘釘機器人設(shè)置需建群(在群里才能機器人)
2、點擊群設(shè)置,在群管理里點擊機器人管理。

3、點擊添加機器人選擇自定義機器人點擊添加。

4、在添加釘釘機器人時需要確定加密方式有以下幾種:
- 自定義關(guān)鍵字
- 加簽
- IP地址段
注:因目前所選方式為第一種,所以需輸入自定義關(guān)鍵字,如:"報警:"

5、點擊完成后,釘釘會給出一個webhook,需復(fù)制webhook在C#中使用。

6、如果自定義機器人在群里發(fā)送招呼話語,說明已建造設(shè)置成功。
二、C#實現(xiàn)釘釘消息推送
1.釘釘消息類型
釘釘消息有六種消息類型,總結(jié)如下:
| 類型 | 是否支持交互 | 關(guān)鍵特性 | 適用場景 |
|---|---|---|---|
| 文本(text) | ? | 純文本,支持@成員 | 簡單通知、報警 |
| Markdown | ? | 支持Markdown格式化 | 復(fù)雜內(nèi)容(如日志報告) |
| 鏈接(link) | ? | 標題+圖片+跳轉(zhuǎn)鏈接 | 帶縮略圖的通知 |
| ActionCard | ? | 單、多 1-2個可點擊按鈕 | 審批、任務(wù)處理 |
| FeedCard | ? | 多條鏈接列表 | 聚合通知(如新聞列表) |
2.代碼實現(xiàn)
使用C#控制臺實現(xiàn)釘釘機器人消息推送。
1)DingTalkRobot類型
釘釘機器人信息推送,代碼如下(示例):
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
public class DingTalkRobot
{
private readonly string _webhookUrl;
private readonly HttpClient _httpClient;
public DingTalkRobot(string webhookUrl)
{
_webhookUrl = webhookUrl ?? throw new ArgumentNullException(nameof(webhookUrl));
_httpClient = new HttpClient();
}
/// <summary>
/// 發(fā)送文本消息
/// </summary>
/// <param name="content">消息內(nèi)容</param>
/// <param name="atMobiles">需要@的手機號數(shù)組</param>
/// <param name="isAtAll">是否@所有人</param>
public async Task SendTextMessageAsync(string content, string[] atMobiles = null, bool isAtAll = false)
{
var message = new
{
msgtype = "text",
text = new
{
content = content
},
at = new
{
atMobiles = atMobiles ?? Array.Empty<string>(),
isAtAll = isAtAll
}
};
await SendMessageAsync(message);
}
/// <summary>
/// 發(fā)送Markdown消息
/// </summary>
/// <param name="title">標題</param>
/// <param name="text">Markdown格式內(nèi)容</param>
/// <param name="atMobiles">需要@的手機號數(shù)組</param>
/// <param name="isAtAll">是否@所有人</param>
public async Task SendMarkdownMessageAsync(string title, string text, string[] atMobiles = null, bool isAtAll = false)
{
var message = new
{
msgtype = "markdown",
markdown = new
{
title = title,
text = text
},
at = new
{
atMobiles = atMobiles ?? Array.Empty<string>(),
isAtAll = isAtAll
}
};
await SendMessageAsync(message);
}
/// <summary>
/// 發(fā)送鏈接消息
/// </summary>
/// <param name="title">標題</param>
/// <param name="text">內(nèi)容</param>
/// <param name="messageUrl">跳轉(zhuǎn)鏈接</param>
/// <param name="picUrl">圖片鏈接(可選)</param>
public async Task SendLinkMessageAsync(string title, string text, string messageUrl, string picUrl = "")
{
var message = new
{
msgtype = "link",
link = new
{
title = title,
text = text,
messageUrl = messageUrl,
picUrl = picUrl
}
};
await SendMessageAsync(message);
}
/// <summary>
/// 發(fā)送 單按鈕 ActionCard?消息
/// </summary>
/// <param name="title">消息標題,顯示在消息頂部</param>
/// <param name="text">消息內(nèi)容,支持Markdown語法</param>
/// <param name="singleTitle">單個按鈕的文本(不超過20字符)</param>
/// <param name="singleUrl">按鈕跳轉(zhuǎn)鏈接(需HTTP/HTTPS)</param>
/// <param name="atMobiles">需要@的群成員手機號數(shù)組</param>
/// <param name="isAtAll">是否@所有人(慎用)</param>
/// <returns></returns>
public async Task SendActionCardAsync(string title, string text, string singleTitle, string singleUrl, string[] atMobiles = null, bool isAtAll = false)
{
var message = new
{
msgtype = "actionCard",
actionCard = new
{
title = title,
text = text,
singleTitle = singleTitle,
singleURL = singleUrl,
btnOrientation = "0" // "0"垂直按鈕,"1"水平按鈕
},
at = new
{
atMobiles = atMobiles ?? Array.Empty<string>(),
isAtAll = isAtAll
}
};
await SendMessageAsync(message);
}
/// <summary>
/// 發(fā)送 多按鈕 ActionCard消息
/// </summary>
/// <param name="title">消息標題</param>
/// <param name="text">消息內(nèi)容</param>
/// <param name="buttons">按鈕列表(最多2個)</param>
/// <param name="btnOrientation">按鈕排列方向:“0”(垂直,默認) 或 “1”(水平)</param>
/// <param name="atMobiles">需要@的手機號數(shù)組</param>
/// <param name="isAtAll">是否@所有人</param>
/// <returns></returns>
public async Task SendMultiActionCardAsync(string title, string text, List<DingTalkButton> buttons, string btnOrientation = "0", // "0"垂直,"1"水平
string[] atMobiles = null, bool isAtAll = false)
{
var message = new
{
msgtype = "actionCard",
actionCard = new
{
title = title,
text = text,
btns = buttons.Select(b => new { title = b.Title, actionURL = b.Url }).ToArray(),
btnOrientation = btnOrientation
},
at = new
{
atMobiles = atMobiles ?? Array.Empty<string>(),
isAtAll = isAtAll
}
};
await SendMessageAsync(message);
}
/// <summary>
/// 發(fā)送FeedCard消息
/// </summary>
/// <param name="links">鏈接列表(最多5條)</param>
/// <returns></returns>
public async Task SendFeedCardAsync(List<FeedCardLink> links)
{
var message = new
{
msgtype = "feedCard",
feedCard = new
{
links = links.Select(link => new
{
title = link.Title,
messageURL = link.MessageUrl,
picURL = link.PicUrl
}).ToArray()
}
};
await SendMessageAsync(message);
}
// FeedCard 鏈接定義類
public class FeedCardLink
{
//鏈接標題(小于等于64字符)
public string Title { get; set; }
//跳轉(zhuǎn)鏈接(需HTTP/HTTPS)
public string MessageUrl { get; set; }
//圖片鏈接(可選,建議尺寸:520x275像素)
public string PicUrl { get; set; }
}
// 按鈕定義類
public class DingTalkButton
{
//按鈕文本(小于等于20字符)
public string Title { get; set; }
//跳轉(zhuǎn)鏈接(需HTTP/HTTPS)
public string Url { get; set; }
}
private async Task SendMessageAsync(object message)
{
var json = Newtonsoft.Json.JsonConvert.SerializeObject(message);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(_webhookUrl, content);
response.EnsureSuccessStatusCode();
var responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine($"釘釘機器人響應(yīng): {responseContent}");
}
}
2)Program類型
釘釘機器人發(fā)送消息實現(xiàn)類,代碼如下:
using static DingTalkRobot;
using static System.Net.Mime.MediaTypeNames;
public class Program
{
static async Task Main(string[] args)
{
// 實際Webhook URL
var webhookUrl = "https://oapi.dingtalk.com/robot/send?access_token=ea8b2fe200c23a4ec8a9569c88ca9561d4f7ebe9bb10d1146ed07e49904c0627\r\n";
var dingTalkRobot = new DingTalkRobot(webhookUrl);
try
{
//關(guān)鍵字 = “報警:” 需在title、content參數(shù)加關(guān)鍵字
//1、發(fā)送文本消息(消息長度不超過20kb)
await dingTalkRobot.SendTextMessageAsync("報警:這是一條測試消息",
atMobiles: new[] { "13812345678" },
isAtAll: false);
//2、發(fā)送Markdown消息(1、不支持HTML和復(fù)雜表格 2、總長度不超過8192字節(jié))
await dingTalkRobot.SendMarkdownMessageAsync(
"報警:項目更新通知",
"### 項目狀態(tài)更新\n" +
"> 項目進度: 80%\n\n" +
"> 剩余時間: 2天\n\n" +
"\n" +
"###### [查看詳情](https://example.com)",
atMobiles: new[] { "13812345678" });
//3、發(fā)送鏈接消息(最后兩個 跳轉(zhuǎn)鏈接 圖片鏈接)
await dingTalkRobot.SendLinkMessageAsync(
"報警:系統(tǒng)報警通知",
"生產(chǎn)環(huán)境出現(xiàn)異常,請及時處理",
"https://www.bilibili.com/video/BV1ZU4y1q7sn/?share_source=copy_web&vd_source=ad0206b6bbe094bb6fa542017f2e474b",
"https://www.bilibili.com/opus/366829175324803541?from=search&spm_id_from=333.337.0.0");
//4、發(fā)送單按鈕 ActionCard消息
await dingTalkRobot.SendActionCardAsync(
title: "報警:任務(wù)審批",
text: "**申請人**: 張三\n**內(nèi)容**: 采購申請\n請及時處理!",
singleTitle: "點擊審批",
singleUrl: "https://example.com/approve?id=123");
//5、發(fā)送多按鈕 ActionCard消息
var buttons = new List<DingTalkButton>
{
new DingTalkButton { Title = "同意", Url = "https://example.com/agree" },
new DingTalkButton { Title = "拒絕", Url = "https://example.com/reject" }
};
await dingTalkRobot.SendMultiActionCardAsync(
title: "報警:請假審批",
text: "**員工**: 李四\n**天數(shù)**: 3天",
buttons: buttons,
btnOrientation: "1" // 水平排列按鈕
);
//6、發(fā)送FeedCard消息
var links = new List<FeedCardLink>
{
new FeedCardLink
{
Title = "報警:系統(tǒng)報警",
MessageUrl = "https://example.com/alert1",
PicUrl = "https://example.com/alert.png"
},
new FeedCardLink
{
Title = "報警:新任務(wù)",
MessageUrl = "https://example.com/task1",
PicUrl = "https://example.com/task.png"
}
};
await dingTalkRobot.SendFeedCardAsync(links);
}
catch (Exception ex)
{
Console.WriteLine($"發(fā)送釘釘消息失敗: {ex.Message}");
}
}
}
3)運行結(jié)果


總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
.Net(c#)漢字和Unicode編碼互相轉(zhuǎn)換實例
下面小編就為大家?guī)硪黄?Net(c#)漢字和Unicode編碼互相轉(zhuǎn)換實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02
RSA密鑰--JAVA和C#的區(qū)別及聯(lián)系
這篇文章主要介紹了關(guān)于RSA密鑰事件JAVA和C#的區(qū)別及聯(lián)系,文章從RSA語法介紹開始展開詳細介紹了C#轉(zhuǎn)JAVA及JAVA轉(zhuǎn)C#,需要的小伙伴可以可以參考一下2021-10-10
C# 中const,readonly,static的使用小結(jié)
這篇文章主要介紹了C# 中使用const,readonly,static的示例,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下2021-01-01

