1. 程式人生 > >釘釘自定義機器人&傳送釘釘訊息(C#版)

釘釘自定義機器人&傳送釘釘訊息(C#版)

開發文件: 釘釘 自定義機器人 一、建立、設定釘釘機器人

  1. 建立機器人:釘釘群 ->群設定 -> 群機器人 如下圖所示 在這裡插入圖片描述

在這裡插入圖片描述

  1. 設定釘釘機器人資訊 在這裡插入圖片描述

二、傳送釘釘訊息 根據釘釘開發文件,當前釘釘機器人支援的訊息型別主要有三種:文字型別、link型別、markdown型別。本文主要介紹傳送“markdown型別”訊息。 事實上,釘釘機器人傳送訊息,就是傳送一次HTTP Post請求給webhook,資料最終都是json格式的,所以在通過機器人傳送訊息未成功時,可以檢查自己的webhook是否正確,json資料是否符合開發文件要求。 在這裡插入圖片描述 廢話不多說,直接開始。

  1. 編寫訊息型別類Model MarkDown:MarkDown型別 At:At DingDingMessage:釘釘訊息 DingDingResponse:訊息響應

   /// <summary>
    /// 訊息型別
    /// </summary>
    public class MarkDown
    {
        public MarkDown() { }
        public string title { set; get; }//標題
        public string text { set; get; }//文字訊息
    }
    
 /// <summary>
    /// At
    /// </summary>
    public  class At
    {
        public At() 
        {
            atMobiles = new List<string>();
        }
        private List<string> _atMobiles;//@的手機號
        private bool _isAtAll;//是否@所有人

        /// <summary>
        /// @的聯絡人
        /// </summary>
        public List<string> atMobiles
        {
            set { _atMobiles = value; }
            get { return _atMobiles; }
        }         

        /// <summary>
        /// 是否@所有人
        /// </summary>
        public bool isAtAll
        {
            set { _isAtAll = value; }
            get { return _isAtAll; }
        }
    }

 /// <summary>
    /// 釘釘訊息
    /// </summary>
    public class DingDingMessage
    {
        public DingDingMessage()
        {
            this.at = new At();
            this.text = new Text();
            this.markdown = new MarkDown();
        }
        public string msgtype { set; get; }//訊息型別
        public Model.Text text { set; get; }//text型別
        public Model.MarkDown markdown { set; get; }//markdown型別
        public Model.At at { set; get; }//@
    }
/// <summary>
    /// 訊息響應
    /// </summary>
    public class DingDingResponse
    {
        private string _msg;
        private string _code;

        /// <summary>
        /// 錯誤資訊
        /// </summary>
        public string ErrMsg
        {
            set { _msg = value; }
            get { return _msg; }
        }

        /// <summary>
        /// 錯誤碼
        /// </summary>
        public string ErrCode
        {
            set { _code = value; }
            get { return _code; }
        }

    }    

  1. 編寫傳送釘釘訊息的方法
 /// <summary>
        /// 建立測試任務、修改測試任務
        /// 向釘釘群傳送訊息
        /// </summary>
        /// <param name="task"></param>
        /// <param name="type"></param>
        public static Model.DingDingResponse Send_TestTaskMessageToDingDing(Model.Task task, string type)
        {
            StringBuilder msg = new StringBuilder();         
            Model.DingDingResponse response = new Model.DingDingResponse();
            List<string> phoneList = new List<string>();
            Model.DingDingMessage message = new Model.DingDingMessage();
            message.msgtype = "markdown";
            if (type.Equals("新建"))
            {
                message.markdown.title = "【測試任務分配】建立人:" + Utility.UserInfo.UserName;
                msg.Append("### 【測試任務分配】專案負責人:" + task.Project_Leader_Name + "\n");
            }
            else if (type.Equals("修改"))
            {
                message.markdown.title = "【測試任務分配】修改人:" + Utility.UserInfo.UserName;
                msg.Append("### 【測試任務分配】專案負責人:" + task.Project_Leader_Name + "\n");

            }
            else if (type.Equals("刪除"))
            {
                message.markdown.title = "【測試任務刪除】刪除人:" + Utility.UserInfo.UserName;
                msg.Append("### 【測試任務刪除】專案負責人:" + task.Project_Leader_Name + "\n");
                msg.Append("* 任務名:" + task.TaskName + "\n");
                msg.Append("* 刪除人:" + Utility.UserInfo.UserName + "\n");
                msg.Append("* 建立時間:" + task.PublishTime.ToString() + "\n");
                msg.Append("* 刪除時間:" + Utility.Common.GetSysTime().ToString() + "\n");
                msg.Append("* 所屬機型專案:" + task.Project_Id.ToUpper() + "\n");
                msg.Append("\n");
                msg.Append("@所有人");
            }

            if (type.Equals("新建") || type.Equals("修改"))
            {
                //@所有人與@某些人不能一起使用           
                message.at.isAtAll = false;
            }
            else if(type.Equals("刪除"))
            {
                message.at.isAtAll = true;
            }

            if (type.Equals("新建") || type.Equals("修改"))
            {
                msg.Append("* 任務名:" + task.TaskName + "\n");
                msg.Append("* 測試機型:" + task.Project_Id.ToUpper() + "(" + task.PhoneType + ")\n");
                msg.Append("* 測試周期:" + task.TestCycle + "天\n");
                msg.Append("* 測試時間:" + task.StartTime.ToString("yyyy/MM/dd HH:mm") + " 至 " + task.EndTime.ToString("yyyy/MM/dd HH:mm") + "\n");
                msg.Append("* 其他:請檢視OverseaPMS系統->個人任務\n");
                //msg.Append("* 備註:" + task.BZ + "\n");
                msg.Append("------\n");
                msg.Append("------\n");

                DataTable dt_allChildTasks = BLL.TestTask.ChildTask.Que_AllChildTasksByTaskId(task.TaskId).Tables[0];            
                if (dt_allChildTasks != null && dt_allChildTasks.Rows.Count > 0)
                {
                    msg.Append("#### 測試模組安排如下:\n");
                    string phone = "";
                   
                    for (int i = 0; i < dt_allChildTasks.Rows.Count; i++)
                    {
                        phone = dt_allChildTasks.Rows[i]["phone"].ToString();
                        //去除重複手機號
                        if (!phoneList.Contains("@" + phone))
                        {
                            phoneList.Add("@" + phone);
                        }
                        msg.Append(" \n > (" + (i + 1) + ") " + dt_allChildTasks.Rows[i]["module_name"] + "," + dt_allChildTasks.Rows[i]["tester_name"] +
                           ",測試要求:" + dt_allChildTasks.Rows[i]["requirement"]);
                        //msg.Append("\n @" + phone);
                        msg.Append("\n");                       

                    }
                    msg.Append("\n");

                    if (phoneList.Count > 20)
                    {
                        for (int i = 0; i < 20; i++)
                        {
                            msg.Append(phoneList[i] + " ");

                            phone = phoneList[i].Trim().Substring(1);
                            message.at.atMobiles.Add(phone);                           
                            
                        }
                        //刪除
                        phoneList.RemoveRange(0, 20);
                    }
                    else
                    {
                        for (int i = 0; i < phoneList.Count; i++)
                        {
                            msg.Append(phoneList[i] + " ");

                            phone = phoneList[i].Trim().Substring(1);
                            message.at.atMobiles.Add(phone);
                        }
                        //刪除
                        phoneList.Clear();                      
                    }

                    
                    msg.Append("\n");                
                }


            }
           
            //message.text.content = msg.ToString();
            message.markdown.text = msg.ToString();

            String textMsg = Utility.JsonHelper.SerializeObject(message);//Json將物件序列化

            string webhook = Get_TestTaskWebhook();
            //返回響應
            string result = Utility.Common.PostDingDing(textMsg, webhook);
            response = Utility.JsonHelper.DeserializeJsonToObject<Model.DingDingResponse>(result);

            if (response.ErrCode.Equals("0"))
            {
                if (phoneList.Count > 0)
                {
                    //將剩餘手機號分組,併發送訊息
                    response = Send_SplitOtherPhoneToDingDing(phoneList, task);
                }
               
            }
           
            //if (!response.ErrCode.Equals("0"))
            //{
            //    MessageBox.Show("釘釘請求異常!\n錯誤碼:" + response.ErrCode + ",錯誤資訊:" + response.ErrMsg, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            //}

            return response;

        }
        
  /// <summary>
        /// 手機號列表分組,併發送到釘釘群
        /// </summary>
        /// <param name="phoneList"></param>
        /// <returns></returns>
        public static Model.DingDingResponse Send_SplitOtherPhoneToDingDing(List<string> phoneList, Model.Task task=null)
        {
            Model.DingDingResponse response = new Model.DingDingResponse();
            List<string> temp = new List<string>();
            if (phoneList.Count > 20)
            {
                int count = Convert.ToInt32(Math.Ceiling(phoneList.Count / 20.0));
                for (int i = 0; i < count; i++)
                {
                    temp = phoneList.GetRange(1+(20*i), 20);
                    response = Send_OtherPhoneToDingDing(temp,task);
                    if (!response.ErrCode.Equals("0"))
                    {
                        return response;                      
                    }
                }
            }
            else
            {
                response = Send_OtherPhoneToDingDing(phoneList,task);
            }

            return response;
        }

  /// <summary>
        /// 傳送手機號到釘釘群
        /// </summary>
        /// <param name="phoneList"></param>
        /// <returns></returns>
        public static Model.DingDingResponse Send_OtherPhoneToDingDing(List<string> phoneList, Model.Task task=null)
        {
            StringBuilder msg = new StringBuilder();
            Model.DingDingResponse response = new Model.DingDingResponse();
            Model.DingDingMessage message = new Model.DingDingMessage();
            message.msgtype = "markdown";
            message.markdown.title = "【測試任務分配】任務名:" + task.TaskName;
            string phone = "";

            for (int i = 0; i < phoneList.Count; i++)
            {
                msg.Append(phoneList[i] + " ");

                phone = phoneList[i].Trim().Substring(1);
                message.at.atMobiles.Add(phone);
            }
          
            message.markdown.text = msg.ToString();

            String textMsg = Utility.JsonHelper.SerializeObject(message);//Json將物件序列化

            string webhook = Get_TestTaskWebhook();
            //返回響應
            string result = Utility.Common.PostDingDing(textMsg, webhook);
            response = Utility.JsonHelper.DeserializeJsonToObject<Model.DingDingResponse>(result);

            return response;

        }

    /// <summary>
        /// 以Post方式傳送請求
        /// </summary>
        /// <param name="apiurl">請求的URL</param>
        /// <param name="jsonString">請求的json引數</param>
        /// <param name="headers">請求頭的key-value字典</param>
        public static String PostDingDing(string jsonString, string apiurl = null, Dictionary<String, String> headers = null)
        {
            if (apiurl == null)
            {
                apiurl = WEB_HOOK;//機器人的webhook
            }
           
            WebRequest request = WebRequest.Create(@apiurl);
            request.Method = "POST";
            request.ContentType = "application/json";
            if (headers != null)
            {
                foreach (var keyValue in headers)
                {
                    if (keyValue.Key == "Content-Type")
                    {
                        request.ContentType = keyValue.Value;
                        continue;
                    }
                    request.Headers.Add(keyValue.Key, keyValue.Value);
                }
            }

            if (String.IsNullOrEmpty(jsonString))
            {
                request.ContentLength = 0;
            }
            else
            {
                byte[] bs = Encoding.UTF8.GetBytes(jsonString);
                request.ContentLength = bs.Length;
                Stream newStream = request.GetRequestStream();
                newStream.Write(bs, 0, bs.Length);
                newStream.Close();
            }


            WebResponse response = request.GetResponse();
            Stream stream = response.GetResponseStream();
            Encoding encode = Encoding.UTF8;
            StreamReader reader = new StreamReader(stream, encode);
            string resultJson = reader.ReadToEnd();
            return resultJson;
        }


效果圖: 在這裡插入圖片描述