.NET 搭建简单的通知服务

摘要:
构建一个简单的通知服务简介。在很多情况下,我们会遇到一些需要通知和报警的场景,例如服务器资源监控和报警,并在抢火车票后通知用户付款。完成必要的安全设置,检查我是否已阅读并同意自定义机器人服务和免责声明,然后单击完成。参数描述当前时间戳(以毫秒为单位)距离请求调用时间不能超过1小时。
搭建简单的通知服务

Intro

很多情况下,我们都会遇到一些需要进行通知报警的场景,比如说服务器资源监控报警,抢到火车票后通知用户进行付款。

原来主要是用的钉钉群里的机器人来做的通知,周末看到原来做 【Server 酱】的大佬写了一个简单的基于企业微信的微信推送,代码是 PHP 的非常简单,可以参考:https://github.com/easychen/wecomchan

于是就自己尝试了一下写了一个 C# 版的,这样就可以直接推送到微信上,对于不怎么用钉钉的小伙伴来说就更为方便了。

有的时候我会帮朋友做一些小东西会需要做通知,比如上次给朋友监控自如上的一个房子,有一个房子待解冻,朋友想要租这个房子,想要在解冻的第一时间去签约这个房子,于是就写了一个简单的定时去刷房子状态的一个小程序,当房子状态变化的时候就发一个通知给我朋友,这样就可以即时租到自己心仪的房子了。

觉得通知功能还是挺实用的所以结合之前一直在用的钉钉推送和刚学到的微信推送,写了一个小示例来分享一下我用来通知推送的代码,详细参考后面的内容

钉钉推送

有用过钉钉的小伙伴可能都知道,钉钉群可以添加机器人,通过调用机器人的 Web Hook 来发送通知,用起来非常的方便。

步骤一:获取自定义机器人Webhook

  1. 打开机器人管理页面。以PC端为例,打开PC端钉钉,点击头像,选择机器人管理.NET 搭建简单的通知服务第1张

  2. 在机器人管理页面选择自定义机器人,输入机器人名字并选择要发送消息的群,同时可以为机器人设置机器人头像。.NET 搭建简单的通知服务第2张

  3. 完成必要的安全设置,勾选我已阅读并同意《自定义机器人服务及免责条款》,然后单击完成

    目前有3种安全设置方式,请根据需要选择一种:

  • 自定义关键词:最多可以设置10个关键词,消息中至少包含其中1个关键词才可以发送成功。

    例如添加了一个自定义关键词:监控报警,则这个机器人所发送的消息,必须包含监控报警这个词,才能发送成功。

  • 加签

  • IP地址(段):设定后,只有来自IP地址范围内的请求才会被正常处理。支持两种设置方式:IP地址和IP地址段,暂不支持IPv6地址白名单,格式如下。

    格式说明
    1.1.1.1开发者的出口公网IP地址(非局域网地址)
    1.1.1.0/24用CIDR表示的一个网段
  1. timestamp+" "+密钥当做签名字符串,使用HmacSHA256算法计算签名,然后进行Base64 encode,最后再把签名参数再进行urlEncode,得到最终的签名(需要使用UTF-8字符集)。

    参数说明
    timestamp当前时间戳,单位是毫秒,与请求调用时间误差不能超过1小时。
    secret密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串。
  2. 把 timestamp和第一步得到的签名值拼接到URL中。

    https://oapi.dingtalk.com/robot/send?access_token=XXXXXX×tamp=XXX&sign=XXX
    参数说明
    timestamp第一步使用到的时间戳。
    sign第一步得到的签名值。
  • 完成安全设置后,复制出机器人的 Webhook 地址,可用于向这个群发送消息,格式如下:

    https://oapi.dingtalk.com/robot/send?access_token=XXXXXX 

    请保管好此Webhook 地址,不要公布在外部网站上,泄露后有安全风险

  • 通常建议使用关键词就可以了(之前的版本其实可以都不设置,后来的版本添加了限制,上面的几种方式需要选一种,推荐使用关键词方式,简单暴力)

    钉钉机器人推送代码:

    // 钉钉机器人推送用的 WebHook 地址
    private const string DingBotWebHookUrl =
        "https://oapi.dingtalk.com/robot/send?access_token=";

    public static async Task MainTest()
    {
        using var httpClient = new HttpClient();
        using var response = await httpClient.PostAsync(DingBotWebHookUrl,
            new StringContent(
                new {msgtype = "text", text = new {content = $"Test... {DateTime.Now:yyyy-MM-dd HH:mm:ss}"}}
                    .ToJson(), Encoding.UTF8, "application/json"));
        var result = await response.Content.ReadAsStringAsync();
        Console.WriteLine($"发送钉钉消息通知,result:{result}");
    }

    企业微信推送

    这个是根据大佬的这个项目改的 https://github.com/easychen/wecomchan,原来项目的代码是 PHP 的,我改成了 C# 的,有需要的可以参考一下,现在的代码里比较简单没有对 access_token 做缓存,实际使用的时候建议进行缓存,token 快过期的时候再去申请新的 token。

    使用企业微信推送需要先注册一个企业微信号,不需要进行认证,用微信注册就好了,注册步骤引用大佬的介绍

    第一步,注册企业

    用电脑打开企业微信官网,注册一个企业

    第二步,创建应用

    注册成功后,点「管理企业」进入管理界面,选择「应用管理」 → 「自建」 → 「创建应用」.NET 搭建简单的通知服务第3张

    应用名称填入「Server酱」,应用logo可以到这里下载,可见范围选择公司名。.NET 搭建简单的通知服务第4张

    创建完成后进入应用详情页,可以得到应用ID( agentid )①,应用Secret( secret )②。

    注意:secret推送到手机端时,只能在企业微信客户端中查看。.NET 搭建简单的通知服务第5张

    第三步,获取企业ID

    进入「我的企业」页面,拉到最下边,可以看到企业ID③,复制并填到上方。

    推送UID直接填 @all ,推送给公司全员。

    第四步,推送消息到微信

    进入「我的企业」 → 「微信插件」,拉到下边扫描二维码,关注以后即可收到推送的消息。.NET 搭建简单的通知服务第6张

    上面的应用 id 和 logo 可以自定义,不必和上面保持一致

    钉钉的推送较为简单,直接调用一次接口就可以了,微信的稍微麻烦一些,需要先获取一下 access_token,然后再调用发消息的接口

    推送示例代码如下:

    // 企业 id
    private const string CorpId = "ww3508de6cad12eebd";
    // 应用 id
    private const string AppId = "1000003";
    // 应用 secret
    private const string AppSecret = "";
    // 要推送的用户,"@all" 表示全员推送
    private const string ToUid = "@all";

    public static async Task MainTest()
    {
        var getTokenUrl =
            $"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={CorpId.UrlEncode()}&corpsecret={AppSecret.UrlEncode()}";

        using var httpClient = new HttpClient();
        var responseStr = await httpClient.GetStringAsync(getTokenUrl);
        Console.WriteLine(responseStr);
        var accessToken = JsonNode.Parse(responseStr)["access_token"].GetValue<string>();

        var sendMessageUrl =
            $"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={accessToken.UrlEncode()}";

        using var response = await httpClient.PostAsJsonAsync(sendMessageUrl,
            new
            {
                touser = ToUid,
                msgtype = "text",
                agentid = AppId,
                text = new {content = $"Test {DateTime.Now:yyyy-MM-dd HH:mm:ss}"}
            });
        responseStr = await response.Content.ReadAsStringAsync();
        Console.WriteLine(responseStr);
    }

    推送示例输出结果如下:.NET 搭建简单的通知服务第7张

    More

    感觉还是钉钉的推送更简单一些,直接调用一次就好了,access_token 是固定的

    使用微信推送的时候最好考虑缓存 access_token ,不能频繁调用 gettoken 接口,否则会受到频率拦截

    上面的示例代码可以从 Github 获取

    免责声明:文章转载自《.NET 搭建简单的通知服务》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

    上篇每天一个Linux命令(9)mv命令layUI中layDate控件兼容性问题(手机端没有效果,不显示)下篇

    宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

    相关文章

    vue后台管理系统项目

    项目介绍1.项目根目录文件 2.源码子目录结构 3.api目录 4.assets目录 5.components目录 6.mixins目录 7.permission目录 8.router目录 9.store目录 10.styles目录 11.utils目录 项目文件介绍1.安装element-ui组件实现按需加载 // 1.1.npm...

    ROS系统玩转自主移动机器人(4)-- 嵌入式硬件平台

    一、概述    所谓嵌入式,其实就是专用的微型计算机系统,包括嵌入式硬件和嵌入式软件两个部分。嵌入式硬件通常是由32位(或以下)的微处理器及其相关外设组成;嵌入式软件则是写入嵌入式硬件的用于实现特定功能的程序。笔者总结了一下,嵌入式具有以下几个方面的特点: 专用性。(一般是面对特定应用场景进行专门开发) 实时性。(虽然嵌入式微处理器一般计算能力不高,但是因...

    DNSPod DDNS 动态域名设置

    所谓动态域名,就是当你的服务器 IP 地址发生变化的时候,自动地修改你在「域名解析服务商」那里的域名记录值 怎么操作?看官方文档DNSPod用户API文档 首先需要创建 Token 完整的 API Token 是由 ID,Token 组合而成的,用英文的逗号分割 用刚创建的 API Token 测试一下: $curl -X POST https://dn...

    PHP-Windows下搭建PHP-MSF环境【原创】

    环境:Windows7 64位php-7.0.19php-swoole-1.9.15php-yac-2.0.2php-redis-3.1.2php-mongodb-1.2.10 遇坑: Cygwin: 不能默认使用 Windows 自带的 mingw git,否则报"fatal: Unable to create temporary file: Resul...

    Spring Boot 对日期转换时间戳或字符串

    一、在Spring Boot 项目application.properties文件中添加 # 日期类型转换成时间戳返回 spring.jackson.serialization.write-dates-as-timestamps=true # 日期类型转换成字符串返回 #spring.jackson.date-format=yyyy-mm-dd HH:m...

    python基础学习4-函数、内置函数、os模块、time模块

      1       函数 1.1     字符串格式化方法 Python中字符串格式化输出的几种方法: https://www.cnblogs.com/hongzejun/p/7670923.html 字符串格式化另外一种方式format方式 #字符串format()方法 #第一种import datetime msg = '欢迎光临{name},今天的日...