钉钉消息机器人.Net通用C#Unity实现钉钉消息通知一个工具类(无需SDK,无其他引用)

简介: 钉钉消息机器人.Net通用C#Unity实现钉钉消息通知一个工具类(无需SDK,无其他引用)Chinar —— 心分享、心创新!助力快速完成 .Net 通用的钉钉Post机器人消息通知为初学者节省宝贵的时间,避免采坑!官方文档详细,但实现方式上没有过多的说明。本质上就是一个 POST 消息请求所以我们只要, 完成正常发送POST 使得钉钉方从中可获取对应格式的数据 即可!

Chinar blog www.chinar.xin

.Net通用钉钉自定义机器人


本文提供全流程,中文翻译
Chinar的初衷是将一种简单的生活方式带给世人
使有限时间 具备无限可能

Chinar 教程效果:
Text格式.png
Link 格式.png
ActionCard格式.png


全文高清图片,点击即可放大观看 (很多人竟然不知道)


1

Presentation —— 介绍


疫情原因,居家办公,移动办公或将成为未来世界的主流。

一、实现钉钉自己定义消息通知?

项目需求:需要直接通知消息或相关资料分享到钉钉里。

看了下钉钉官方文档,搜索了下发现网络上教程接入这块不够详细,初学者入门较难。各种失败案例!

官方文档详细,但实现方式上没有过多的说明。

举个例子
二、钉钉消息通知,本质

本质上就是一个 POST 消息请求
所以我们只要, 完成正常发送POST 使得钉钉方从中可获取对应格式的数据 即可!


ps:最近有人吐槽我说:粉丝文章真恶心,不开放阅读不如不看。

我想说:辛苦总结的资料,基本都是经过多次测试,拿来即用。

您不点赞也就算了,关注一下都不愿意,也是醉了。

我的时间和经验也不是大风刮来的。


2

Utility Class —— 工具类

Chinar 为您节约宝贵时间,所有函数都已封装完毕。
无任何数据类,无需序列化。
只此一个工具脚本!.Net通用!

您只需

1. Webhook地址和关键字改用自己机器人
2. 调用对应方法即可发送消息。
举个例子
在这里插入图片描述

工具类代码


using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;


public class ChinarDing
{
    /// <summary>
    /// Webhook 地址
    /// </summary>
    public static string WebHookUrl = "https://oapi.dingtalk.com/robot/send?access_token=b6592dff2c2d2f";


    /// <summary>
    /// 关键字 1
    /// 机器人设置的关键字
    /// </summary>
    private const string keyWord = "【提示】";


    /// <summary>
    /// 缓存 Json 
    /// </summary>
    private static readonly StringBuilder jsonStringBuilder = new StringBuilder(512);


    /// <summary>
    /// 发送 Post 数据
    /// </summary>
    /// <param name="data">数据</param>
    /// <returns>Json</returns>
    public static String Post(string data)
    {
        var httpWebRequest = (HttpWebRequest) WebRequest.Create(WebHookUrl);
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Method      = WebRequestMethods.Http.Post;
        if (data != null)
        {
            byte[] dataBytes = Encoding.UTF8.GetBytes(data);
            httpWebRequest.ContentLength = dataBytes.Length;
            using (var reqStream = httpWebRequest.GetRequestStream())
            {
                reqStream.Write(dataBytes, 0, dataBytes.Length);
                httpWebRequest.GetRequestStream().Write(dataBytes, 0, dataBytes.Length);
            }
        }

        using (var httpWebResponse = (HttpWebResponse) httpWebRequest.GetResponse())
        {
            var responseStream = httpWebResponse.GetResponseStream();
            return responseStream == null ? null : new StreamReader(responseStream, Encoding.UTF8).ReadToEnd();
        }
    }


    /// <summary>
    /// 发送 text 类型
    /// </summary>
    /// <param name="content">内容</param>
    /// <param name="phoneNumbers">@谁?支持多人</param>
    /// <param name="isAtAll">@所有人</param>
    public static void SendText(string content, List<string> phoneNumbers, bool isAtAll)
    {
        //var addColon     = mobileList.Select(_ => $"\"{_}\""); //有时特殊需要,对电话号码每一项加上 “132XXX43210”
        jsonStringBuilder.Clear();
        var listToString = string.Join(",", phoneNumbers);
        jsonStringBuilder.Append($"{{\"msgtype\":\"text\",\"text\":{{\"content\":\"{keyWord + content}\"}},\"at\":{{\"atMobiles\":[{listToString}],\"isAtAll\":{isAtAll.ToString().ToLower()}}}}}");
        string ReturnJson = Post(jsonStringBuilder.ToString());
        Console.Write(ReturnJson);
    }


    /// <summary>
    /// 发送 Link 类型
    /// </summary>
    /// <param name="title">标题</param>
    /// <param name="text">内容</param>
    /// <param name="imageUrl">图片链接</param>
    /// <param name="contentUrl">消息跳转链接</param>
    public static void SendLink(string title, string text, string imageUrl, string contentUrl)
    {
        jsonStringBuilder.Clear();
        jsonStringBuilder.Append("{\"msgtype\":\"link\",\"link\":{"  +
                                 $"\"title\":\"{keyWord + title}\"," +
                                 $"\"text\":\"{text}\","             +
                                 $"\"picUrl\":\"{imageUrl}\","       +
                                 $"\"messageUrl\":\"{contentUrl}\"}}}}");
        string ReturnJson = Post(jsonStringBuilder.ToString());
        Console.Write(ReturnJson);
    }


    /// <summary>
    /// 发送markdown类消息
    /// </summary>
    /// <param name="title">标题</param>
    /// <param name="text">消息主体</param>
    /// <param name="atMobiles">@人员电话</param>
    /// <param name="isAtAll">是否@群所有成员</param>
    public static void SendMarkdown(string title, string text, string imageUrl, List<string> phoneNumbers, bool isAtAll)
    {
        var listToString = string.Join(",", phoneNumbers);
        jsonStringBuilder.Clear();
        jsonStringBuilder.Append($"{{\"msgtype\":\"markdown\",\"" +
                                 $"markdown\":{{\"title\":\"{keyWord + title}\"," +
                                 $"\"text\":\"{text} " +
                                 $"![screenshot]({imageUrl})\\n> [Chinar](https://www.chinar.com) \\n\"}}," +
                                 $"\"at\":{{\"atMobiles\":[\"{listToString}\"]," +
                                 $"\"isAtAll\":{isAtAll.ToString().ToLower()}}}}}");
        string ReturnJson = Post(jsonStringBuilder.ToString());
        Console.Write(ReturnJson);
    }


    /// <summary>
    /// 整体发送ActionCard类型消息
    /// </summary>
    /// <param name="title">标题</param>
    /// <param name="imageUrl">图片Url</param>
    /// <param name="texttitle">文本标题</param>
    /// <param name="text">文本</param>
    /// <param name="btnTitle">按钮标题</param>
    /// <param name="buttonUrl">按钮Url</param>
    /// <param name="btnOrientation">按钮排列     0-按钮竖直排列,1-按钮横向排列</param>
    public static void SendActionCard(string title, string imageUrl, string texttitle, string text, string btnTitle, string buttonUrl, string btnOrientation)
    {
        jsonStringBuilder.Clear();
        jsonStringBuilder.Append($"{{\"actionCard\":{{\"title\":\"{keyWord + title}\"," +
                                 $"\"text\":\"![screenshot]({imageUrl}) \\r\\n ### {texttitle} \\r\\n {text}\"," +
                                 $"\"btnOrientation\":\"{btnOrientation}\"," +
                                 $"\"singleTitle\":\"{btnTitle}\"," +
                                 $"\"singleURL\":\"{buttonUrl}\"}}," +
                                 $"\"msgtype\":\"actionCard\"}}");
        string ReturnJson = Post(jsonStringBuilder.ToString());
        //Console.Write(ReturnJson); 
    }

    /// <summary>
    /// 独立发送 ActionCard类型消息
    /// </summary>
    /// <param name="title">标题</param>
    /// <param name="imageUrl">图片Url</param>
    /// <param name="texttitle">文本标题</param>
    /// <param name="text">文本</param>
    /// <param name="buttonUrl1">按钮1Url</param>
    /// <param name="buttonUrl2">按钮2Url</param>
    /// <param name="singleURL1">按钮1访问Url</param>
    /// <param name="singleURL2">按钮2访问Url</param>
    /// <param name="btnOrientation"></param>
    public static void SendActionCard(string title, string imageUrl, string texttitle, string text, string buttonUrl1, string buttonUrl2, string singleURL1, string singleURL2, string btnOrientation)
    {
        jsonStringBuilder.Clear();
        jsonStringBuilder.Append($"{{\"actionCard\":{{\"title\":\"{keyWord + title}\"," +
                                 $"\"text\":\"![screenshot]({imageUrl}) \\r\\n ### {texttitle} \\r\\n {text}\"," +
                                 $"\"btnOrientation\":\"{btnOrientation}\"," +
                                 $"\"btns\":[{{\"title\":\"{buttonUrl1}\"," +
                                 $"\"actionURL\":\"{singleURL1}\"}}," +
                                 $"{{\"title\":\"{buttonUrl2}\"," +
                                 $"\"actionURL\":\"{singleURL2}\"}}]}}," +
                                 $"\"msgtype\":\"actionCard\"}}");
        string ReturnJson = Post(jsonStringBuilder.ToString());
        //Console.Write(ReturnJson); 
    }


    /// <summary>
    /// 发送 FeedCard类型消息
    /// </summary>
    /// <param name="title1">标题 单条信息文本</param>
    /// <param name="messageUrl1">点击单条信息到跳转链接</param>
    /// <param name="imageUrl1">单条信息后面图片的URL</param>
    /// <param name="title2"></param>
    /// <param name="messageUrl2"></param>
    /// <param name="imageUrl2"></param>
    public static void SendFeedCard(string title1, string messageUrl1, string imageUrl1, string title2, string messageUrl2, string imageUrl2)
    {
        jsonStringBuilder.Clear();
        jsonStringBuilder.Append($"{{\"feedCard\":{{\"links\":[{{\"title\":\"{keyWord + title1}\"," +
                                 $"\"messageURL\":\"{messageUrl1}\"," +
                                 $"\"picURL\":\"{imageUrl1}\"}}," +
                                 $"{{\"title\":\"{title2}\"," +
                                 $"\"messageURL\":\"{messageUrl2}\"," +
                                 $"\"picURL\":\"{imageUrl2}\"}}]}}," +
                                 $"\"msgtype\":\"feedCard\"}}");
        string ReturnJson = Post(jsonStringBuilder.ToString());
    }
}

3

Use —— 使用方法


疫情原因,居家办公,移动办公或将成为未来世界的主流。

静态函数,直接调用即可

 // 1- Text 类型
            ChinarDing.SendText("Hello World!", new List<string>(), false);
            //2- Link 类型
            ChinarDing.SendLink("Link", "测试 Post Link 请求", "http://qiniu.chinar.xin/DingChinar-3.png", "http://www.chinar.xin");
            // 3- Markdown 类型
            ChinarDing.SendMarkdown("Markdown", "测试 MD 请求", "http://qiniu.chinar.xin/DingChinar-3.png", new List<string> {"135XXX53210"}, false);

            // 4- Markdown 类型
            ChinarDing.SendActionCard("Card",        "http://qiniu.chinar.xin/DingChinar-3.png",                          "Text 标题",            "测试 MD 请求",                        "内容不错", "不感兴趣", "https://www.dingtalk.com/", "https://www.dingtalk.com/", "0");
            ChinarDing.SendActionCard("乔布斯 20 年前想打", "https://gw.alicdn.com/tfs/TB1ut3xxbsrBKNjSZFpXXcXhFXa-846-786.png", "乔布斯 20 年前想打造的苹果咖啡厅", "Apple Store 的设计正从原来满满的科技感走向生活化,", "内容不错", "不感兴趣", "https://www.dingtalk.com/", "https://www.dingtalk.com/", "0");
            ChinarDing.SendFeedCard("时代的火车向前开", "https://www.dingtalk.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", "https://gw.alicdn.com/tfs/TB1ayl9mpYqK1RjSZLeXXbXppXa-170-62.png", "时代的火车向前开", "https://www.dingtalk.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", "https://gw.alicdn.com/tfs/TB1ayl9mpYqK1RjSZLeXXbXppXa-170-62.png");
            ChinarDing.SendActionCard("乔布斯 20 年前想打", "https://gw.alicdn.com/tfs/TB1ut3xxbsrBKNjSZFpXXcXhFXa-846-786.png", "乔布斯 20 年前想打造的苹果咖啡厅", "Apple Store 的设计正从原来满满的科技感走向生活化,", "内容不错", "https://www.dingtalk.com/", "0");
            Console.ReadKey();

举个例子
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


支持

May Be —— 开发者,总有一天要做的事!


拥有自己的服务器,无需再找攻略

Chinar 提供一站式《零》基础教程

使有限时间 具备无限可能!

Chinar 免费服务器、建站教程全攻略!( Chinar Blog )


Chinar

END

本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究

对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com

对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址

相关文章
|
2月前
|
Java 开发工具 Maven
springboot项目打包为sdk供其他项目引用
springboot项目打包为sdk供其他项目引用
|
3月前
|
机器人 关系型数据库 MySQL
shell脚本实现文件自动清理并推送钉钉机器人告警
shell脚本实现文件自动清理并推送钉钉机器人告警
48 1
|
3月前
|
运维 监控 安全
调用钉钉机器人API接口将堡垒机安全运维告警单发给运维人员
调用钉钉机器人API接口将堡垒机安全运维告警单发给运维人员
83 0
|
1月前
|
数据采集 DataWorks 监控
DataWorks常见问题之监控规则是数据质量配置好钉钉机器人不报警如何解决
DataWorks是阿里云提供的一站式大数据开发与管理平台,支持数据集成、数据开发、数据治理等功能;在本汇总中,我们梳理了DataWorks产品在使用过程中经常遇到的问题及解答,以助用户在数据处理和分析工作中提高效率,降低难度。
32 5
|
1月前
|
SQL DataWorks 机器人
DataWorks常见问题之导致钉钉群的机器人发报警消息如何解决
DataWorks是阿里云提供的一站式大数据开发与管理平台,支持数据集成、数据开发、数据治理等功能;在本汇总中,我们梳理了DataWorks产品在使用过程中经常遇到的问题及解答,以助用户在数据处理和分析工作中提高效率,降低难度。
46 7
|
1月前
|
安全 机器人 API
简单几步,钉钉机器人秒变通义千问对话机器人
大模型不知不觉已经火了快一年了,拥有一个能够随时对话使用的大模型已经成为不少人的刚需。然而,最大的问题可能是如何访问和调用对话模型。如果,我是说如果,能在您的即时通讯软件钉钉中直接与通义千问对话,是不是会让这一切更方便快捷?! 按照传统方案,我们要实现上述场景可能需要非常繁琐的接入步骤,甚至还需要自行开发很多代码,这样的准入门槛实在,太!高!啦! 而今天,我要向各位隆重介绍一个新的解决方案——阿里云计算巢AppFlow应用与数据集成平台,无需任何代码开发,简单快捷,自动连接企业内部应用与外部应用或数据,搭建企业的自动化服务流程,帮助个人、企业降低了集成实施的周期和成本。
859 1
|
3月前
|
安全 机器人 Shell
shell脚本实现Linux磁盘空间超过阈值自动钉钉机器人告警
shell脚本实现Linux磁盘空间超过阈值自动钉钉机器人告警
46 0
|
3月前
|
运维 监控 安全
【优化篇】调用钉钉机器人API接口将堡垒机安全运维告警单发给运维人员
【优化篇】调用钉钉机器人API接口将堡垒机安全运维告警单发给运维人员
71 0
|
4月前
|
C# 图形学
【Unity 3D】元宇宙案例之虚拟地球信息射线实战(附源码、演示视频和步骤 超详细)
【Unity 3D】元宇宙案例之虚拟地球信息射线实战(附源码、演示视频和步骤 超详细)
49 0
|
4月前
|
人工智能 自然语言处理 区块链
【Unity 3D】元宇宙概念、应用前景、价值链等概述
【Unity 3D】元宇宙概念、应用前景、价值链等概述
52 0