本文属于个人原创作品、个人总结,谢绝转载、抄袭。如果您有疑问或者希望沟通交流,可以联系QQ:865562060。
一、钉钉自定义机器人
钉钉自定义机器人是在钉钉群中部署的机器人之一,可以通过自定义聊天内容实时通知群内用户。在开发工作中可以起到服务器安全提醒、部署提醒、操作提醒等作用。
获取自定义机器人webhook:
- 在机器人管理页面选择“自定义”机器人,输入机器人名字并选择要发送消息的群。如果需要的话,可以为机器人设置一个头像。点击“完成添加”。
- 点击“复制”按钮,即可获得这个机器人对应的Webhook地址,其格式如下
1 |
|
使用自定义机器人:
获取到Webhook地址后,用户可以使用任何方式向这个地址发起HTTP POST 请求,即可实现给该群组发送消息。注意,发起POST请求时,必须将字符集编码设置成UTF-8。
当前自定义机器人支持文本(text)、连接(link)、markdown(markdown)三种消息类型,大家可以根据自己的使用场景选择合适的消息类型,达到最好的展示样式。具体的消息类型参考下一节内容。
自定义机器人发送消息时,可以通过手机号码指定“被@人列表”。在“被@人列表”里面的人员,在收到该消息时,会有@消息提醒(免打扰会话仍然通知提醒,首屏出现“有人@你”)
二、C#实现钉钉自定义机器人的开发
以下代码源码地址为:https://github.com/Menyoupingxiaoguo/DDRobot。自定义类都在项目中,请自行下载。
如果我的代码对您有帮助,请给博主的github项目一个star,谢谢!
1、需要额外引入的dll
using Newtonsoft.Json;
using System.Configuration;2、定义方法类,主要包含各种消息体的发送
public class OapiRobot
{
public static string dd_host = ConfigurationManager.AppSettings["DDHost"];
public static string RobotSendUrl = ConfigurationManager.AppSettings["RobotSendUrl"];
/// <summary>
/// 发送文本消息
/// </summary>
/// <param name="content">文本内容</param>
/// <param name="atMobiles">@人员电话</param>
/// <param name="isAtAll">是否@群所有成员</param>
public static void OapiRobotText(string content, List<string> atMobiles, bool isAtAll)
{
TextModel tModel = new TextModel();
tModel.at = new atText();
tModel.text = new text();
tModel.at.atMobiles = new List<string>();
tModel.text.content = content;
tModel.at.atMobiles.AddRange(atMobiles);
tModel.at.isAtAll = isAtAll;
tModel.msgtype = "text";
string data = JsonConvert.SerializeObject(tModel);
string json = Request(RobotSendUrl, data, "POST");
}
/// <summary>
/// 发送Link消息
/// </summary>
/// <param name="title">消息标题</param>
/// <param name="text">消息内容。如果太长只会部分展示</param>
/// <param name="messageUrl">点击消息跳转的URL</param>
/// <param name="picUrl">图片URL</param>
public static void OapiRobotLink(string title, string text, string messageUrl, string picUrl)
{
LinkModel lModel = new LinkModel();
lModel.link = new link();
lModel.msgtype = "link";
lModel.link.title = title;
lModel.link.text = text;
lModel.link.messageUrl = messageUrl;
lModel.link.picUrl = picUrl;
string data = JsonConvert.SerializeObject(lModel);
string json = Request(RobotSendUrl, data, "POST");
}
/// <summary>
/// 发送markdown类消息
/// </summary>
/// <param name="title">标题</param>
/// <param name="text">消息主体</param>
/// <param name="atMobiles">@人员电话</param>
/// <param name="isAtAll">是否@群所有成员</param>
public static void OapiRobotMarkDown(string title, string text, List<string> atMobiles, bool isAtAll)
{
MarkDownModel mdModel = new MarkDownModel();
mdModel.at = new atMarkdown();
mdModel.markdown = new markdown();
mdModel.at.atMobiles = new List<string>();
mdModel.markdown.title = title;
mdModel.markdown.text = text;
mdModel.at.atMobiles.AddRange(atMobiles);
mdModel.at.isAtAll = isAtAll;
mdModel.msgtype = "markdown";
string data = JsonConvert.SerializeObject(mdModel);
string json = Request(RobotSendUrl, data, "POST");
}
/// <summary>
/// 发送整体跳转ActionCard类型
/// </summary>
/// <param name="title">首屏会话透出的展示内容</param>
/// <param name="text">markdown格式的消息</param>
/// <param name="singleTitle">单个按钮的方案。(设置此项和singleURL后btns无效。)</param>
/// <param name="singleURL">点击singleTitle按钮触发的URL</param>
/// <param name="btnOrientation">0-按钮竖直排列,1-按钮横向排列</param>
/// <param name="hideAvatar">0-正常发消息者头像,1-隐藏发消息者头像</param>
public static void OapiRobotActionCardOverall(string title, string text, string singleTitle, string singleURL, string btnOrientation, string hideAvatar)
{
ActionCardOverallModel acModel = new ActionCardOverallModel();
acModel.actionCard = new actionCard();
acModel.msgtype = "actionCard";
acModel.actionCard.title = title;
acModel.actionCard.text = text;
acModel.actionCard.singleTitle = singleTitle;
acModel.actionCard.singleURL = singleURL;
if (!string.IsNullOrEmpty(btnOrientation))
acModel.actionCard.btnOrientation = btnOrientation;
else
acModel.actionCard.btnOrientation = "0";
if (!string.IsNullOrEmpty(hideAvatar))
acModel.actionCard.hideAvatar = hideAvatar;
else
acModel.actionCard.hideAvatar = "0";
string data = JsonConvert.SerializeObject(acModel);
string json = Request(RobotSendUrl, data, "POST");
}
/// <summary>
/// 发送独立跳转ActionCard类型
/// </summary>
/// <param name="title"></param>
/// <param name="text"></param>
/// <param name="btns"></param>
/// <param name="btnOrientation"></param>
/// <param name="hideAvatar"></param>
public static void OapiRobotActionCardSingle(string title, string text, string btns, string btnOrientation, string hideAvatar)
{
ActionCardSingleModel acModel = new ActionCardSingleModel();
acModel.actionCard = new actionCardSingle();
acModel.actionCard.btns = JsonConvert.DeserializeObject<List<btns>>(btns);
acModel.msgtype = "actionCard";
acModel.actionCard.title = title;
acModel.actionCard.text = text;
if (!string.IsNullOrEmpty(btnOrientation))
acModel.actionCard.btnOrientation = btnOrientation;
else
acModel.actionCard.btnOrientation = "0";
if (!string.IsNullOrEmpty(hideAvatar))
acModel.actionCard.hideAvatar = hideAvatar;
else
acModel.actionCard.hideAvatar = "0";
string data = JsonConvert.SerializeObject(acModel);
string json = Request(RobotSendUrl, data, "POST");
}
/// <summary>
/// 发送FeedCard类型
/// </summary>
public static void OapiRobotFeedCard()
{
FeedCardModel fcModel = new FeedCardModel();
fcModel.msgtype = "feedCard";
fcModel.feedCard = new feedCard();
fcModel.feedCard.links = new List<links>();
links model1 = new links();
model1.title = "时代的火车向前开";
model1.messageURL = "https://mp.weixin.qq.com/s?__biz=MzA4NjMwMTA2Ng==&mid=2650316842&idx=1&sn=60da3ea2b29f1dcc43a7c8e4a7c97a16&scene=2&srcid=09189AnRJEdIiWVaKltFzNTw&from=timeline&isappinstalled=0&key=&ascene=2&uin=&devicetype=android-23&version=26031933&nettype=WIFI";
model1.picURL = "https://www.dingtalk.com/";
fcModel.feedCard.links.Add(model1);
links model2 = new links();
model2.title = "时代的火车向前开2";
model2.messageURL = "https://mp.weixin.qq.com/s?__biz=MzA4NjMwMTA2Ng==&mid=2650316842&idx=1&sn=60da3ea2b29f1dcc43a7c8e4a7c97a16&scene=2&srcid=09189AnRJEdIiWVaKltFzNTw&from=timeline&isappinstalled=0&key=&ascene=2&uin=&devicetype=android-23&version=26031933&nettype=WIFI";
model2.picURL = "https://www.dingtalk.com/";
fcModel.feedCard.links.Add(model2);
string data = JsonConvert.SerializeObject(fcModel);
string json = Request(RobotSendUrl, data, "POST");
}
}3、发送消息测试
static void Main(string[] args)
{
#region 1、发送Text消息
OapiRobot.OapiRobotText("啦啦啦测试", new List<string> { "180********" }, false);
#endregion
#region 2、发送Link消息
OapiRobot.OapiRobotLink("自定义机器人协议", "群机器人是钉钉群的高级扩展功能。群机器人可以将第三方服务的信息聚合到群聊中,实现自动化的信息同步。例如:通过聚合GitHub,GitLab等源码管理服务,实现源码更新同步;通过聚合Trello,JIRA等项目协调服务,实现项目信息同步。不仅如此,群机器人支持Webhook协议的自定义接入,支持更多可能性,例如:你可将运维报警提醒通过自定义机器人聚合到钉钉群。",
"https://open-doc.dingtalk.com/docs/doc.htm?spm=a219a.7629140.0.0.Rqyvqo&treeId=257&articleId=105735&docType=1","");
#endregion
#region 3、发送MarkDown消息
//MarkDown语法学习可参照以下地址:https://www.jianshu.com/p/191d1e21f7ed
//图片地址必须写钉钉可以访问的外链地址
OapiRobot.OapiRobotMarkDown("杭州天气", "#### 杭州天气 \n > 9度,@1825718XXXX 西北风1级,空气良89,相对温度73%\n\n > \n > ###### 10点20分发布 [天气](http://www.thinkpage.cn/)", new List<string> { "180********" }, false);
#endregion;
#region 4、发送整体跳转ActionCard类型
OapiRobot.OapiRobotActionCardOverall("乔布斯 20 年前想打造一间苹果咖啡厅,而它正是 Apple Store 的前身",
" \n #### 乔布斯 20 年前想打造的苹果咖啡厅 \n\n Apple Store 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划",
"阅读全文",
"https://www.dingtalk.com/",
"0",
"0");
#endregion
#region 5、独立跳转ActionCard类型
OapiRobot.OapiRobotActionCardSingle("乔布斯 20 年前想打造一间苹果咖啡厅,而它正是 Apple Store 的前身",
" \n\n #### 乔布斯 20 年前想打造的苹果咖啡厅 \n\n Apple Store 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划",
"[{\"title\": \"内容不错\", \"actionURL\": \"https://www.dingtalk.com/\"}, {\"title\": \"不感兴趣\", \"actionURL\": \"https://www.dingtalk.com/\"}]",
"0",
"0");
#endregion
#region 6、FeedCard类型
OapiRobot.OapiRobotFeedCard();
#endregion
}4、实现效果
文本类型:
link类型:
markdown类型:
整体跳转ActionCard类型
独立跳转ActionCard类型:
FeedCard类型:
版权声明:本文为qq_23009105原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。