DingDing.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. using System.ComponentModel;
  2. using System.Reflection;
  3. using System.Security.Cryptography;
  4. using System.Text;
  5. namespace HTEX.Complex.Service
  6. {
  7. public class DingDing
  8. {
  9. private const string url = "https://oapi.dingtalk.com/robot/send?access_token=";
  10. private readonly HttpClient _httpClient;
  11. public DingDing(HttpClient httpClient)
  12. {
  13. _httpClient = httpClient;
  14. }
  15. /// <summary>
  16. /// 發送需要加簽驗證的Bot訊息(msgtype為text)
  17. /// </summary>
  18. /// <param name="robotUrl">釘釘Robot發送Url</param>
  19. /// <param name="secret">加簽密鑰</param>
  20. /// <param name="msg">發送訊息</param>
  21. /// <returns></returns>
  22. public async Task SendBotMarkdown(string title, string text, GroupNames groupkey, List<string> mobiles = null)
  23. {
  24. // TODO 有空處理自動抓取方法名,代碼行數顯示
  25. //StackTrace st = new StackTrace(new StackFrame(1, true));
  26. //StackFrame sf = st.GetFrame(0);
  27. //var f = $"Func:{sf.GetMethod().Name},Line : {sf.GetFileLineNumber()}";
  28. List<string> atMobiles = new List<string>();
  29. if (mobiles!=null && mobiles.Count>0)
  30. {
  31. atMobiles=mobiles;
  32. }
  33. var content = new { msgtype = "markdown", markdown = new { title = title, text = text }, at = new { atMobiles } };
  34. #if DEBUG
  35. var keys = GroupNames.成都开发測試群組.GetDescriptionText().Split(',');
  36. #else
  37. var keys = groupkey.GetDescriptionText().Split(',');
  38. #endif
  39. if (keys.Length == 1) await _httpClient.PostAsJsonAsync($"{url}{keys[0]}", content);
  40. else
  41. {
  42. var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  43. await _httpClient.PostAsJsonAsync($"{url}{keys[0]}&timestamp={timestamp}&sign={BotAddSign(keys[1], timestamp)}", content);
  44. }
  45. }
  46. /// <summary>
  47. /// 發送需要加簽驗證的Bot訊息(msgtype為text)
  48. /// </summary>
  49. /// <param name="robotUrl">釘釘Robot發送Url</param>
  50. /// <param name="secret">加簽密鑰</param>
  51. /// <param name="msg">發送訊息</param>
  52. /// <returns></returns>
  53. public async Task SendBotMsg(string msg, GroupNames groupkey, List<string> mobiles = null)
  54. {
  55. // TODO 有空處理自動抓取方法名,代碼行數顯示
  56. //StackTrace st = new StackTrace(new StackFrame(1, true));
  57. //StackFrame sf = st.GetFrame(0);
  58. //var f = $"Func:{sf.GetMethod().Name},Line : {sf.GetFileLineNumber()}";
  59. List<string> atMobiles = new List<string>();
  60. if (mobiles != null && mobiles.Count > 0)
  61. {
  62. atMobiles=mobiles;
  63. }
  64. var content = new { msgtype = "text", text = new { content = msg }, at = new { atMobiles } };
  65. var keys = groupkey.GetDescriptionText().Split(',');
  66. if (keys.Length == 1) await _httpClient.PostAsJsonAsync($"{url}{keys[0]}", content);
  67. else
  68. {
  69. var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  70. await _httpClient.PostAsJsonAsync($"{url}{keys[0]}&timestamp={timestamp}&sign={BotAddSign(keys[1], timestamp)}", content);
  71. }
  72. }
  73. // <summary>
  74. /// 發送需要加簽驗證的Bot訊息(msgtype為text)
  75. /// </summary>
  76. /// <param name="robotUrl">釘釘Robot發送Url</param>
  77. /// <param name="secret">加簽密鑰</param>
  78. /// <param name="msg">發送訊息</param>
  79. /// <returns></returns>
  80. public async Task SendBotMsg(string msg, string accesstoken, string secret = null)
  81. {
  82. var content = new { msgtype = "text", text = new { content = msg } };
  83. if (string.IsNullOrWhiteSpace(secret))
  84. await _httpClient.PostAsJsonAsync($"{url}{accesstoken}", content);
  85. else
  86. {
  87. var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  88. await _httpClient.PostAsJsonAsync($"{url}{accesstoken}&timestamp={timestamp}&sign={BotAddSign(secret, timestamp)}", content);
  89. }
  90. }
  91. #region private
  92. /// <summary>
  93. /// 釘釘Bot簽名生成方法
  94. /// </summary>
  95. /// <param name="zTime"></param>
  96. /// <returns></returns>
  97. private static string BotAddSign(string secret, long zTime)
  98. {
  99. //"SEC6a6822db6567f79854a474002407cd9ac36da4d194b5fb79e073c35ef61119ed";
  100. string stringToSign = zTime + "\n" + secret;
  101. var encoding = new System.Text.ASCIIEncoding();
  102. byte[] keyByte = encoding.GetBytes(secret);
  103. byte[] messageBytes = encoding.GetBytes(stringToSign);
  104. using (var hmacsha256 = new HMACSHA256(keyByte))
  105. {
  106. byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
  107. return System.Web.HttpUtility.UrlEncode(Convert.ToBase64String(hashmessage), Encoding.UTF8);
  108. }
  109. }
  110. #endregion
  111. }
  112. public static class EnumExtensions
  113. {
  114. /// <summary>
  115. /// 取得Enum描述值
  116. /// </summary>
  117. public static string GetDescriptionText(this Enum source)
  118. {
  119. FieldInfo? fi = source.GetType().GetField(source.ToString());
  120. DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
  121. if (attributes.Length > 0) return attributes[0].Description;
  122. else return source.ToString();
  123. }
  124. }
  125. public enum GroupNames
  126. {
  127. [Description("ce63217d9c734a92fd91c7c9ceaa9b25e109cce94615a7f75288dc43865a6e20,SEC6a6822db6567f79854a474002407cd9ac36da4d194b5fb79e073c35ef61119ed")]
  128. 研發C組,
  129. [Description("2c5ced0725b592b1a96f1fb800d6d9a15727986ef75923a838a4d24e6b8c9147,SEC66ff954306c1fd98b5b160e23c253649f22205e69a16fb26e18d136f49875a9e")]
  130. 客戶回饋群組,
  131. [Description("f8bf19c9363e3b288e018856014bcbf89708f19b3aae009e203edd68af25c9fe")]
  132. BB訂單群組,
  133. [Description("a27b099b15a054374da41b9f66f72e5fc6b378e98418859f7c0ef46408941808")]
  134. 台北開發測試群組,
  135. [Description("82aba2fccfa8442c575db3ac0442fa5aea90cd7574bb9a71d5abf210ea72a3aa,SEC3f38eca87cd4fd10505d136f91071a2e8b14cd863bd6bbafb24c612fc751a59a")]
  136. 成都开发測試群組,
  137. [Description("1a316ce4edc2db88231d40d80072b00f2751d7d9e2e5871c5dc061885b01c48d,SECff60201ac9b219943b9f8fc397fda1a617d0cbc140850f5ea9cb4f131479d39a")]
  138. 醍摩豆服務運維群組,
  139. [Description("a83ea4ead63bf1b4e087723b3a7ccdf7f4c96708a22493f489bb928999f50d87,SECf1d22db7d00580dc7c0e597e31112a25ae1025500fc998b5b30961d91e115271")]
  140. 國際客戶聯繫通知群,
  141. [Description("b1293e05c6aaeece746a2e46d69164a4373bab071bfafb5d7b5141f947e493cb,SEC658c7c70204f18976fa5e02f554d4fc72e9892c9bb82c5c6b98ecfd3c4eb0531")]
  142. 大陸客戶聯繫通知群,
  143. [Description("feac70431e5b3cf68c621c5397ca62c573499275557335f0d140e05c3e2437fa,SECb365526c7d7a3fd230f8f1c8ee82b869db9a3fa81d035233b5350028d19c527b")]
  144. 醍摩豆小财神,
  145. [Description("8e3c5efdf8ad02eb44584dfd08ee66cfa9d31860af51670df69fc9d7bb55f3bb,SECb1267571406d89d2ac451a11495be417d3cbfe2b04ed7f1742d28e1a1d098c9d")]
  146. 高飛
  147. }
  148. }