using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/*****************************
* 接口开发文档地址:https://open-doc.dingtalk.com/docs/doc.htm?spm=a219a.7629140.0.0.ABt1ET&treeId=257&articleId=105735&docType=1
* 概要:阿里巴巴钉钉自定义机器人
* 设计者:DuanXuWen
* 设计时间:20180523
* 版本:0.1
* 修改者:
* 修改时间:
* ***************************/
namespace Common
{
public class DinDinHelper
{
/// <summary>
/// 调用自定义机器人发Txt消息
/// </summary>
/// <param name="webhook">机器人管理-自定义-webhook</param>
/// <param name="content">消息内容</param>
/// <param name="atMobiles">被@人的手机号</param>
/// <param name="isAtAll">@所有人时:true,否则为:false</param>
/// <param name="exception">返回内部异常</param>
/// <returns>钉钉返回JObject</returns>
public static JObject SendTxtMessage(string webhook, string content, string[] atMobiles, bool isAtAll, ref Exception exception)
{
try
{
string mobiles = GetAtMobiles(atMobiles);
object message = new
{
msgtype = "text",
text = new
{
content = (mobiles + content).Trim(),
},
at = new
{
atMobiles = atMobiles,
isAtAll = isAtAll
}
};
return SendMessage(webhook, message, ref exception);
}
catch (Exception ex)
{
exception = ex;
throw;
}
}
/// <summary>
/// 调用自定义机器人发Link[分享]消息
/// </summary>
/// <param name="webhook">机器人管理-自定义-webhook</param>
/// <param name="text">消息内容(注:如果太长只会部分展示)</param>
/// <param name="title">消息标题</param>
/// <param name="picUrl">图片URL</param>
/// <param name="messageUrl">点击消息跳转的URL</param>
/// <param name="exception">返回内部异常</param>
/// <returns>钉钉返回JObject</returns>
public static JObject SendLinkMessage(string webhook, string text, string title, string picUrl, string messageUrl, ref Exception exception)
{
try
{
object message = new
{
msgtype = "link",
link = new
{
text = text,
title = title,
picUrl = picUrl,
messageUrl = messageUrl
},
};
return SendMessage(webhook, message, ref exception);
}
catch (Exception ex)
{
exception = ex;
throw;
}
}
/// <summary>
/// 调用自定义机器人发Markdown消息
/// </summary>
/// <param name="webhook">机器人管理-自定义-webhook</param>
/// <param name="title">消息标题</param>
/// <param name="titleType">标题类型等级</param>
/// <param name="markdownMessageList">消息内容</param>
/// <param name="atMobiles">被@手机号</param>
/// <param name="isAtAll">@所有人时:true,否则为:false</param>
/// <param name="exception">返回内部异常</param>
/// <returns>钉钉返回JObject</returns>
public static JObject SendMarkdownMessage(string webhook, string title, TitleType titleType, List<MarkdownMessage> markdownMessageList, string[] atMobiles, bool isAtAll, ref Exception exception)
{
try
{
//@手机号
string mobiles = GetAtMobiles(atMobiles);
//消息内容头部(标题+被@的人;注:自动换行)
string textTop = GetContentGrade(titleType, title) + "\n >" + mobiles + "\n >";
//消息内容
string text = textTop + GetNewMessage(markdownMessageList);
object message = new
{
msgtype = "markdown",
markdown = new
{
title = title,
text = text,
},
at = new
{
atMobiles = atMobiles,
isAtAll = isAtAll,
}
};
return SendMessage(webhook, message, ref exception);
}
catch (Exception ex)
{
exception = ex;
throw;
}
}
/// <summary>
/// 调用自定义机器人发ActionCards消息
/// </summary>
/// <param name="webhook">机器人管理-自定义-webhook</param>
/// <param name="markdownMessageList">消息内容</param>
/// <param name="hideAvatar">0-正常发消息者头像,1-隐藏发消息者头像</param>
/// <param name="btnOrientation">0-按钮竖直排列,1-按钮横向排列</param>
/// <param name="singleTitle">单个按钮的方案。(设置此项和singleURL后btns无效。)</param>
/// <param name="singleURL">点击singleTitle按钮触发的URL</param>
/// <param name="exception">返回内部异常</param>
/// <returns>钉钉返回JObject</returns>
public static JObject SendActionCardsMessage(string webhook, List<MarkdownMessage> markdownMessageList, int hideAvatar, int btnOrientation, string singleTitle, string singleURL, ref Exception exception)
{
try
{
object message = new
{
msgtype = "actionCard",
actionCard = new
{
text = GetNewMessage(markdownMessageList),
hideAvatar = hideAvatar,
btnOrientation = btnOrientation,
singleTitle = singleTitle,
singleURL = singleURL
},
};
return SendMessage(webhook, message, ref exception);
}
catch (Exception ex)
{
exception = ex;
throw;
}
}
/// <summary>
/// 调用自定义机器人发ActionCard消息
/// </summary>
/// <param name="webhook">机器人管理-自定义-webhook</param>
/// <param name="markdownMessageList">消息内容</param>
/// <param name="hideAvatar">0-正常发消息者头像,1-隐藏发消息者头像</param>
/// <param name="btnOrientation">0-按钮竖直排列,1-按钮横向排列</param>
/// <param name="btns">按钮集合</param>
/// <param name="exception">返回内部异常</param>
/// <returns>钉钉返回JObject</returns>
public static JObject SendActionCardMessage(string webhook, List<MarkdownMessage> markdownMessageList, int hideAvatar, int btnOrientation, Btns[] btns, ref Exception exception)
{
try
{
object message = new
{
actionCard = new
{
text = GetNewMessage(markdownMessageList),
hideAvatar = hideAvatar,
btnOrientation = btnOrientation,
btns = btns
},
msgtype = "actionCard",
};
return SendMessage(webhook, message, ref exception);
}
catch (Exception ex)
{
exception = ex;
throw;
}
}
/// <summary>
/// 调用自定义机器人发ActionCard消息
/// </summary>
/// <param name="webhook">机器人管理-自定义-webhook</param>
/// <param name="links">图片按钮集合</param>
/// <param name="exception">返回内部异常</param>
/// <returns>钉钉返回JObject</returns>
public static JObject SendFeedCardMessage(string webhook, Links[] links, ref Exception exception)
{
try
{
object message = new
{
feedCard = new
{
links = links,
},
msgtype = "feedCard"
};
return SendMessage(webhook, message, ref exception);
}
catch (Exception ex)
{
exception = ex;
throw;
}
}
/// <summary>
/// 调用自定义机器人发消息
/// </summary>
/// <param name="webhook">机器人管理-自定义-webhook</param>
/// <param name="message">消息信息</param>
/// <param name="exception">返回内部异常</param>
/// <returns>钉钉返回JObject</returns>
public static JObject SendMessage(string webhook, object message, ref Exception exception)
{
try
{
JObject jsons = null;
System.Net.WebClient webclient = new System.Net.WebClient();
string s = JsonConvert.SerializeObject(message);
webclient.Headers.Add("Content-Type", "application/json; charset=utf-8");
byte[] bytes = Encoding.UTF8.GetBytes(s);
var arr = webclient.UploadData(webhook, "POST", bytes);
string str = Encoding.UTF8.GetString(arr).ToString();
webclient.Dispose();
return jsons = (JObject)JsonConvert.DeserializeObject(str);
}
catch (Exception ex)
{
exception = ex;
throw;
}
}
/// <summary>
/// 获取消息内容
/// </summary>
/// <param name="markdownMessageList">消息内容</param>
/// <returns>string</returns>
private static string GetNewMessage(List<MarkdownMessage> markdownMessageList)
{
string text = "";
foreach (var item in markdownMessageList.OrderBy(x => x.index))
{
if (item.markdownType == MarkdownType.文本)
{
if (item.Text.contentType == ContentType.加粗)
{
item.Text.content = "**" + item.Text.content + "**";
}
if (item.Text.contentType == ContentType.斜体)
{
item.Text.content = "*" + item.Text.content + "*";
}
//文本等级赋值
item.Text.content = GetContentGrade(item.Text.contentGrade, item.Text.content);
//判断是否换行
text += (item.isLineFeed) ? item.Text.content + "\n >" : item.Text.content;
}
if (item.markdownType == MarkdownType.图片)
{
text += (item.isLineFeed) ? "![screenshot](" + item.Text.imgurl + ")\n >" : "![screenshot](" + item.Text.imgurl + ")";
}
if (item.markdownType == MarkdownType.链接)
{
text += (item.isLineFeed) ? "[" + item.Text.content + "](" + item.Text.url + ")\n >" : "[" + item.Text.content + "](" + item.Text.url + ")";
}
}
return text;
}
/// <summary>
/// 获取被@人的手机号
/// </summary>
/// <param name="atMobiles">被@人的手机号</param>
/// <returns>string</returns>
private static string GetAtMobiles(string[] atMobiles)
{
string mobiles = "";
if (atMobiles != null && atMobiles.ToList().Count() != 0)
{
foreach (var item in atMobiles)
{
mobiles += "@" + item;
}
}
return mobiles;
}
/// <summary>
/// 获取等级文本
/// </summary>
/// <param name="titleType">文本类型</param>
/// <param name="title">文本</param>
/// <returns>string</returns>
private static string GetContentGrade(TitleType titleType, string title)
{
switch (titleType)
{
case TitleType.一级:
title = "# " + title;
break;
case TitleType.二级:
title = "## " + title;
break;
case TitleType.三级:
title = "### " + title;
break;
case TitleType.四级:
title = "#### " + title;
break;
case TitleType.五级:
title = "##### " + title;
break;
case TitleType.六级:
title = "###### " + title;
break;
default:
break;
}
return title;
}
}
#region Class
/// <summary>
/// Markdown消息内容类
/// </summary>
public class MarkdownMessage
{
/// <summary>
/// 内容坐标
/// </summary>
public int index { get; set; }
/// <summary>
/// 内容类型(文字、图片、链接)
/// </summary>
public MarkdownType markdownType { get; set; }
/// <summary>
/// 内容(注:文字类型的内容中禁止字符["#"、"*"、"["、"]"、"!"];
/// 图片类型和链接类型的内容传可访问的http地址即可)
/// </summary>
public Text Text { get; set; }
/// <summary>
/// 是否换行
/// </summary>
public bool isLineFeed { get; set; }
}
/// <summary>
/// 内容
/// </summary>
public class Text
{
/// <summary>
/// 文本或链接显示文字
/// </summary>
public string content { get; set; }
/// <summary>
/// 图片链接
/// </summary>
public string imgurl { get; set; }
/// <summary>
/// 超链接地址
/// </summary>
public string url { get; set; }
/// <summary>
/// 文本类型
/// </summary>
public ContentType contentType { get; set; }
/// <summary>
/// 文本等级
/// </summary>
public TitleType contentGrade { get; set; }
}
/// <summary>
/// 超链接按钮
/// </summary>
public class Btns
{
/// <summary>
/// 标题
/// </summary>
public string title { get; set; }
/// <summary>
/// 标题对应的超链接
/// </summary>
public string actionURL { get; set; }
}
/// <summary>
/// 超链接按钮带图片
/// </summary>
public class Links
{
/// <summary>
/// 标题
/// </summary>
public string title { get; set; }
/// <summary>
/// 超链接
/// </summary>
public string messageURL { get; set; }
/// <summary>
/// 图片超链接
/// </summary>
public string picURL { get; set; }
}
#endregion
#region Enum
/// <summary>
/// 文本类型
/// </summary>
public enum ContentType
{
加粗 = 1,
斜体 = 2,
}
/// <summary>
/// Markdown消息内容类型
/// </summary>
public enum MarkdownType
{
文本 = 1,
图片 = 2,
链接 = 3,
}
/// <summary>
/// 标题(文本)类型等级
/// </summary>
public enum TitleType
{
一级 = 1,
二级 = 2,
三级 = 3,
四级 = 4,
五级 = 5,
六级 = 6,
}
#endregion
}