.NET 搭建简单的通知服务
搭建简单的通知服务
Intro
很多情况下,我们都会遇到一些需要进行通知报警的场景,比如说服务器资源监控报警,抢到火车票后通知用户进行付款。
原来主要是用的钉钉群里的机器人来做的通知,周末看到原来做 【Server 酱】的大佬写了一个简单的基于企业微信的微信推送,代码是 PHP 的非常简单,可以参考:https://github.com/easychen/wecomchan
于是就自己尝试了一下写了一个 C# 版的,这样就可以直接推送到微信上,对于不怎么用钉钉的小伙伴来说就更为方便了。
有的时候我会帮朋友做一些小东西会需要做通知,比如上次给朋友监控自如上的一个房子,有一个房子待解冻,朋友想要租这个房子,想要在解冻的第一时间去签约这个房子,于是就写了一个简单的定时去刷房子状态的一个小程序,当房子状态变化的时候就发一个通知给我朋友,这样就可以即时租到自己心仪的房子了。
觉得通知功能还是挺实用的所以结合之前一直在用的钉钉推送和刚学到的微信推送,写了一个小示例来分享一下我用来通知推送的代码,详细参考后面的内容
钉钉推送
有用过钉钉的小伙伴可能都知道,钉钉群可以添加机器人,通过调用机器人的 Web Hook 来发送通知,用起来非常的方便。
步骤一:获取自定义机器人Webhook
打开机器人管理页面。以PC端为例,打开PC端钉钉,点击头像,选择机器人管理。
在机器人管理页面选择自定义机器人,输入机器人名字并选择要发送消息的群,同时可以为机器人设置机器人头像。
完成必要的安全设置,勾选我已阅读并同意《自定义机器人服务及免责条款》,然后单击完成。
目前有3种安全设置方式,请根据需要选择一种:
自定义关键词:最多可以设置10个关键词,消息中至少包含其中1个关键词才可以发送成功。
例如添加了一个自定义关键词:监控报警,则这个机器人所发送的消息,必须包含监控报警这个词,才能发送成功。
加签:
IP地址(段):设定后,只有来自IP地址范围内的请求才会被正常处理。支持两种设置方式:IP地址和IP地址段,暂不支持IPv6地址白名单,格式如下。
格式 说明 1.1.1.1 开发者的出口公网IP地址(非局域网地址) 1.1.1.0/24 用CIDR表示的一个网段
把
timestamp+"\n"+
密钥当做签名字符串,使用HmacSHA256算法计算签名,然后进行Base64 encode,最后再把签名参数再进行urlEncode,得到最终的签名(需要使用UTF-8字符集)。参数 说明 timestamp 当前时间戳,单位是毫秒,与请求调用时间误差不能超过1小时。 secret 密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串。 把 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。
使用企业微信推送需要先注册一个企业微信号,不需要进行认证,用微信注册就好了,注册步骤引用大佬的介绍
第一步,注册企业
用电脑打开企业微信官网,注册一个企业
第二步,创建应用
注册成功后,点「管理企业」进入管理界面,选择「应用管理」 → 「自建」 → 「创建应用」
应用名称填入「Server酱」,应用logo可以到这里下载,可见范围选择公司名。
创建完成后进入应用详情页,可以得到应用ID(
agentid
)①,应用Secret(secret
)②。注意:
secret
推送到手机端时,只能在企业微信客户端
中查看。第三步,获取企业ID
进入「我的企业」页面,拉到最下边,可以看到企业ID③,复制并填到上方。
推送UID直接填
@all
,推送给公司全员。第四步,推送消息到微信
进入「我的企业」 → 「微信插件」,拉到下边扫描二维码,关注以后即可收到推送的消息。
上面的应用 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); }
推送示例输出结果如下:
More
感觉还是钉钉的推送更简单一些,直接调用一次就好了,access_token 是固定的
使用微信推送的时候最好考虑缓存 access_token ,不能频繁调用 gettoken 接口,否则会受到频率拦截
上面的示例代码可以从 Github 获取
References
https://github.com/WeihanLi/SamplesInPractice/tree/master/notificationSample
https://developers.dingtalk.com/document/app/custom-robot-access
https://github.com/easychen/wecomchan
https://work.weixin.qq.com/api/doc/90000/90003/90487
https://work.weixin.qq.com/api/doc/90000/90135/90236
.NET 搭建简单的通知服务相关推荐
- 树莓派(Raspberry Pi)搭建简单的lamp服务
树莓派(Raspberry Pi)搭建简单的lamp服务: 1. LAMP 的安装 sudo apt-get install apache2 mysql-server mysql-client php ...
- 按步搭建简单IoT微服务(2)
整体架构 这章节我们将为系统建立一个简单的前端界面.首先安装一些依赖环境并运行起来,按照下面的步骤开始: 如果还没有准备好,可以先在获取的代码仓库 micro-services-tutorial-io ...
- 按步搭建简单IoT微服务(3)
尝试目标4 现在序列化服务已经运行,可以添加模拟传感器和MQTT代理.模拟传感器的代码位于step4/services/sensor,代理程序代码位于step4/services/broker. 新的 ...
- 使用Easyswoole 搭建简单的Websoket服务
步骤1 修改配置文件MAIN_SERVER.SERVER_TYPE为EASYSWOOLE_WEB_SOCKET_SERVER 如dev.php <?php use EasySwoole\ ...
- 【超简单】之基于PaddleSpeech搭建个人语音听写服务
一.[超简单]之基于PaddleSpeech搭建个人语音听写服务 1.需求分析 亲们,你们要写会议纪要嘛? 亲们,你们要写会议纪要嘛? 亲们,你们要写会议纪要嘛? 当您面对成吨的会议录音,着急写会议纪 ...
- 使用SpringBoot搭建一个简单的webSocket服务
前言 个人地址:使用SpringBoot搭建一个简单的webSocket服务 什么是WebSocket? WebSocket是一个HTML5新增的协议,它的目的在浏览器和服务器之间建立一个不受限的双向 ...
- 搭建简单Django服务并通过HttpRequester实现GET/POST http请求提交表单
调试Django框架写的服务时,需要模拟客户端发送POST请求,然而浏览器只能模拟简单的GET请求(将参数写在url内),网上搜索得到了HttpRequester这一firefox插件,完美的实现了模 ...
- SpringBoot + Dubbo + Zookeeper搭建一个简单的分布式服务
本文使用SpringBoot + Dubbo + Zookeeper 来搭建一个简单的分布式服务 文章目录 dubbo-spring-boot-starter 如何发布 Dubbo 服务 如何消费 D ...
- 利用SpringCloud搭建一个最简单的微服务框架
利用SpringCloud搭建一个最简单的微服务框架 https://blog.csdn.net/caicongyang/article/details/52974406 1.微服务 微服务主要包含服 ...
最新文章
- 熟悉常用的HBase操作,编写MapReduce作业
- Spring boot的@Conditional派生注解
- 文件名利用RLO技术欺骗(学习)
- SAP CRM呼叫中心里confirm按钮的实现逻辑
- js 运算符 语句
- c#操作access,update语句不执行的解决办法
- c语言 pdf支持库,解决支持库版本兼容问题:引入包时候support包有红色下划线
- CBoard项目学习
- itunes备份文件夹更换
- 2022年湖南省基金从业资格(私募股权投资基金基础知识)练习题及答案
- 我的精神家园——陈皓专访
- 2023牛寒5--小沙の赌气
- Java之于Javascript就好比Car(汽车)之于Carpet(地毯)。
- 【转载】【原帖名】如何通过紧急刷机模式dump几乎任何高通机型的存储设备
- 5个炫酷登录页面,拿去就能用(附源码)
- MAC OS X 问题库
- 计算机学院杨洋,杨洋-湖北大学计算机与信息工程学院
- 精伦r210的使用的源码
- Logitech G27 程序读取数据
- CE标志有何重要意义(转载)
热门文章
- oracle io lost,磁盘IO故障
- 高质量的期货研究报告去哪里找?
- 深度优先搜索(DFS)----------------Tju_Oj_3517The longest athletic track
- 洛谷——P1033 自由落体
- 数据可视化(9)--数据可视化6步法
- Mac OS使用技巧之十二:解决APP Store更新、下载出错的问题
- dvd vlc 复制_如何使用VLC翻录DVD
- facebook 邀请好友_如何在Facebook上与某人解除好友
- 固件中启用的虚拟化否_哪些固件或硬件机制可启用强制关机?
- Animate与transform的使用