Date (UTC) | User | Event |
---|---|---|
2025-06-17 05:59 | xiaoandx | Annotated tag refs/tags/1.0.1 created (7f538f3d28e3f5dddf3b6d32fafebeb5db6b0a5d) |
2025-06-17 05:59 | xiaoandx | Reference refs/heads/main created (e7a799b0f447466ba16b13cc6e7237cbfc2bfe39) |
2025-06-17 05:55 | xiaoandx | Repository has been created |
项目名称: Common.Notzice (net472 || net48 || netstandard2.0)
版本: 1.0.1
作者: WEI.ZHOU (Willis)
描述: .Net统一消息通知组件,包含了邮件通知、钉钉群机器人、飞书群机器人、企业微信群机器人通知,帮助我们更容易地发送程序异常通知
版权: © WEI.ZHOU (Willis). All rights reserved.
开源协议: MIT License
> 项目接入提供了以下发送方式的Demo:邮件通知、钉钉通知、飞书、企业微信通知
> 邮件通知支持同时发送给多个收件人 ### Step 1 : 添加组件库Dll (已有的部分不需要安装)
Copy dll Common.Notice.dll ==> bin
Install-Package MailKit -version 2.11.1
Install-Package Newtonsoft.Json
Install-Package Microsoft.Extensions.Dependencyinjection -version 3.1.23
Install-Package Microsoft.Extensions.Configuration -version 3.1.23
public class Startup
{[Feishu](Common.Notice/Feishu)
//...
public void ConfigureServices(IServiceCollection services)
{
//configuration
.AddCommonNotice(config =>
services{
.IntervalSeconds = 10;//同一标题的消息,10秒内只能发一条,避免短时间内大量发送重复消息
config.UseEmail(option =>
config{
.Host = "smtp.163.com";//SMTP地址
option.Port = 465;//SMTP端口
option.FromName = "WEI.ZHOU";//发送人名字(自定义)
option.FromAddress = "xandxiao@163.com";//发送邮箱
option.Password = "LM4im32sPe5WillisYhvUK";//秘钥
option.ToAddress = new List<string>()//收件人集合
option{
"12345@qq.com"
};
});
});
}
}
[ApiController]
[Route("[controller]/[action]")]
public class CommonNoticeController : ControllerBase
{
private readonly IEmailProvider _mailProvider;
public CommonNoticeController(IEmailProvider provider)
{
= provider;
_mailProvider }
[HttpGet]
public async Task SendMail([FromQuery] string str)
{
.SendAsync(str, new Exception(str));
await _mailProvider}
}
public class CommonService
{
private readonly ICommonNotice? _emailNotice;
public CommonService()
{
= new NoticeFactory().UseEmailNotice(
_emailNotice new EmailOptions()
{
= "smtp.163.com",
Host = 465,
Port = "WEI.ZHOU",
FromName = "xandxiao@163.com",
FromAddress = "LM4im32sPe5WillisYhvUK",
Password = new List<string>()
ToAddress {
"12345@qq.com"
}
},
new NoticeOptions()
{
= 1
IntervalSeconds });
}
// 异步调用
public async Task SendMail()
{
string str = "测试邮件内容";
.SendAsync(str, new Exception(str));
await _emailNotice}
// 同步调用
public void SendMail()
{
string str = "测试邮件内容";
.Send(str, new Exception(str));
_emailNotice}
}
// 异步发送邮件方法测试
[Fact]
public async Task Email_Send_Should_Be_SucceedByAsync()
{
// 支持Exception对象
//var response = await _emailProvider!.SendAsync("Common.Notice email Async test", new Exception("custom exception"));
// 支持Message文本
var response = await _emailProvider!.SendAsync("Common.Notice email Async test", "custom exception");
.True(response.IsSuccess);
Assert}
// 同步发送邮件方法测试
[Fact]
public void Email_Send_Should_Be_Succeed()
{
// 支持Exception对象
//var response = _emailProvider!.Send("Common.Notice email test", new Exception("custom exception"));
// 支持Message文本
var response = _emailProvider!.Send("Common.Notice email test", "custom exception");
.True(response.IsSuccess);
Assert}
// 邮件收件人传入,发送邮件测试
[Fact]
public void Email_Send_Should_Be_SucceedByAt()
{
// 邮件收件人作为参数传入,发送邮件
//var response = _emailProvider!.Send("Common.Notice email test", new Exception("custom exception"), new CommonNoticeAtUser(){IsAtAll = false, UserId = new[]{"wei.zhou@ccssttcn.com"}});
// 邮件收件人作为参数传入,发送邮件
var response = _emailProvider!.Send("Common.Notice email test", "custom exception", new CommonNoticeAtUser(){IsAtAll = false, UserId = new[]{"wei.zhou@ccssttcn.com"}});
.True(response.IsSuccess);
Assert}
Copy dll Common.Notice.dll ==> bin
Install-Package Newtonsoft.Json
Install-Package Microsoft.Extensions.Dependencyinjection -version 3.1.23
Install-Package Microsoft.Extensions.Configuration -version 3.1.23
public class Startup
{
//...
public void ConfigureServices(IServiceCollection services)
{
//configuration
.AddCommonNotice(config =>
services{
.IntervalSeconds = 10;//同一标题的消息,10秒内只能发一条,避免短时间内大量发送重复消息
config.UseDingTalk(option =>
config{
.WebHook = "https://oapi.dingtalk.com/robot/send?access_token=xxxxx";//通知地址
option.Secret = "secret";//签名校验
option});
});
}
}
[ApiController]
[Route("[controller]/[action]")]
public class CommonNoticeController : ControllerBase
{
private readonly IDingtalkProvider _dingtalkProvider;
public CommonNoticeController(IDingtalkProvider dingtalkProvider)
{
= dingtalkProvider;
_dingtalkProvider }
[HttpGet]
public async Task SendDingTalk([FromQuery] string str)
{
.SendAsync(str, new Exception(str));
await _dingtalkProvider}
}
public class CommonService
{
private readonly ICommonNotice? _dingtalkNotice;
public CommonService()
{
= new NoticeFactory().UseDingtalkNotice(
_dingtalkNotice new DingtalkOptions()
{
= "https://oapi.dingtalk.com/robot/send?access_token=xxxxx", //通知地址
WebHook = "secret"
Secret },
new NoticeOptions()
{
= 1
IntervalSeconds });
}
// 异步调用
public async Task SendDingTalk()
{
string str = "测试钉钉群机器人消息";
.SendAsync(str, new Exception(str));
await _dingtalkNotice}
// 同步调用
public void SendDingTalk()
{
string str = "测试钉钉群机器人消息";
.Send(str, new Exception(str));
_dingtalkNotice}
}
// 异步发送钉钉群机器人消息测试
[Fact]
public async Task DingTalk_Send_Should_Be_SucceedByAsync()
{
// 支持Exception对象
//var response = await _dingtalkNotice!.SendAsync("通知标题", new Exception("custom exception"));
// 支持Message文本
var response = await _dingtalkNotice!.SendAsync("通知标题", "custom exception");
.True(response.IsSuccess);
Assert}
// 同步发送钉钉群机器人消息测试
[Fact]
public void DingTalk_Send_Should_Be_Succeed()
{
// 支持Exception对象
//var response = _dingtalkNotice!.Send("通知标题", new Exception("同步消息"));
// 支持Message文本
var response = _dingtalkNotice!.Send("通知标题", "同步消息");
.True(response.IsSuccess);
Assert}
// 钉钉群机器人支持@用户消息
[Fact]
public void DingTalk_Send_Should_Be_SucceedByAt()
{
// 钉钉群机器人支持@用户消息
// UserId:@指定的用户ID列表,各消息平台的UserID,邮件平台为邮箱地址
// Mobile:@指定的手机号列表,请注意:飞书平台、邮箱发送不支持手机号
// IsAtAll:@所有人
//var response = _dingtalkNotice!.Send("通知标题", new Exception("同步消息"), new CommonNoticeAtUser(){IsAtAll = false, Mobile = new[]{"159XXXXXX44"}});
// 钉钉群机器人支持@用户消息
// UserId:@指定的用户ID列表,各消息平台的UserID,邮件平台为邮箱地址
// Mobile:@指定的手机号列表,请注意:飞书平台、邮箱发送不支持手机号
// IsAtAll:@所有人
var response = _dingtalkNotice!.Send("通知标题", "同步消息", new CommonNoticeAtUser(){IsAtAll = false, Mobile = new[]{"159XXXXXX44"}});
.True(response.IsSuccess);
Assert}
Copy dll Common.Notice.dll ==> bin
Install-Package Newtonsoft.Json
Install-Package Microsoft.Extensions.Dependencyinjection -version 3.1.23
Install-Package Microsoft.Extensions.Configuration -version 3.1.23
public class Startup
{
//...
public void ConfigureServices(IServiceCollection services)
{
//configuration
.AddCommonNotice(config =>
services{
.IntervalSeconds = 10;//同一标题的消息,10秒内只能发一条,避免短时间内大量发送重复消息
config.UseFeishu(option =>
config{
.WebHook = "https://open.feishu.cn/open-apis/bot/v2/hook/xxxxx";//通知地址
option.Secret = "secret";//签名校验
option});
});
}
}
[ApiController]
[Route("[controller]/[action]")]
public class CommonNoticeController : ControllerBase
{
private readonly IFeishuProvider _feishuProvider;
public CommonNoticeController(IFeishuProvider feishuProvider)
{
= feishuProvider;
_feishuProvider }
[HttpGet]
public async Task SendFeishu([FromQuery] string str)
{
.SendAsync(str, new Exception(str));
await _feishuProvider}
}
public class CommonService
{
private readonly ICommonNotice? _feishuProvider;
public CommonService()
{
= new NoticeFactory().UseFeishuNotice(
_feishuProvider new FeishuOptions()
{
= "https://open.feishu.cn/open-apis/bot/v2/hook/xxxxx", //通知地址
WebHook = "secret"
Secret },
new NoticeOptions()
{
= 1
IntervalSeconds });
}
// 异步调用
public async Task SendFeishu()
{
string str = "测试飞书群机器人消息";
.SendAsync(str, new Exception(str));
await _feishuProvider}
// 同步调用
public void SendFeishu()
{
string str = "测试飞书群机器人消息";
.Send(str, new Exception(str));
_feishuProvider}
}
// 异步发送飞书群机器人消息测试
[Fact]
public async Task Feishu_Send_Should_Be_SucceedByAsync()
{
// 支持Exception对象
//var response = await _feishuProvider!.SendAsync("通知标题", new Exception("异步Hello"));
// 支持Message文本
var response = await _feishuProvider!.SendAsync("通知标题", "异步Hello");
.True(response.IsSuccess);
Assert}
// 同步发送飞书群机器人消息测试
[Fact]
public void Feishu_Send_Should_Be_Succeed()
{
// 支持Exception对象
var response = _feishuProvider!.Send("通知标题", new Exception("同步Hello"));
// 支持Message文本
var response = _feishuProvider!.Send("通知标题", "同步Hello");
.True(response.IsSuccess);
Assert}
// 飞书群机器人支持@用户消息
[Fact]
public void Feishu_Send_Should_Be_SucceedByAt()
{
// 飞书群机器人支持@用户消息
// UserId:@指定的用户ID列表,各消息平台的UserID,邮件平台为邮箱地址
// Mobile:@指定的手机号列表,请注意:飞书平台、邮箱发送不支持手机号
// IsAtAll:@所有人
//var response = _feishuProvider!.Send("通知标题", new Exception("同步Hello"), new CommonNoticeAtUser(){IsAtAll = true});
// 飞书群机器人支持@用户消息
// UserId:@指定的用户ID列表,各消息平台的UserID,邮件平台为邮箱地址
// Mobile:@指定的手机号列表,请注意:飞书平台、邮箱发送不支持手机号
// IsAtAll:@所有人
//var response = _feishuProvider!.Send("通知标题", "同步Hello", new CommonNoticeAtUser(){IsAtAll = true});
.True(response.IsSuccess);
Assert}
Copy dll Common.Notice.dll ==> bin
Install-Package Newtonsoft.Json
Install-Package Microsoft.Extensions.Dependencyinjection -version 3.1.23
Install-Package Microsoft.Extensions.Configuration -version 3.1.23
public class Startup
{
//...
public void ConfigureServices(IServiceCollection services)
{
//configuration
.AddCommonNotice(config =>
services{
.IntervalSeconds = 10;//同一标题的消息,10秒内只能发一条,避免短时间内大量发送重复消息
config.UseWeixin(option =>
config{
.WebHook = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxx";//通知地址
option});
});
}
}
[ApiController]
[Route("[controller]/[action]")]
public class CommonNoticeController : ControllerBase
{
private readonly IWeixinProvider _weixinProvider;
public CommonNoticeController(IWeixinProvider weixinProvider)
{
= weixinProvider;
_weixinProvider }
[HttpGet]
public async Task SendWexin([FromQuery] string str)
{
.SendAsync(str, new Exception(str));
await _weixinProvider}
}
public class CommonService
{
private readonly ICommonNotice? _weixinProvider;
public CommonService()
{
= new NoticeFactory().UseWeixinNotice(
_weixinProvider new WeixinOptions()
{
= "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxx" //通知地址
WebHook },
new NoticeOptions()
{
= 1
IntervalSeconds });
}
// 异步调用
public async Task SendWexin()
{
string str = "测试企业微信群机器人消息";
.SendAsync(str, new Exception(str));
await _weixinProvider}
// 同步调用
public void SendWexin()
{
string str = "测试企业微信群机器人消息";
.Send(str, new Exception(str));
_weixinProvider}
}
// 异步发送企业微信群机器人消息测试
[Fact]
public async Task Weixin_Send_Should_Be_SucceedByAsync()
{
// 支持Exception对象
//var response = await _weixinProvider?.SendAsync("通知标题", new Exception("custom exception"))!;
// 支持Message文本
var response = await _weixinProvider?.SendAsync("通知标题", "custom exception")!;
.True(response.IsSuccess);
Assert}
// 同步发送企业微信群机器人消息测试
[Fact]
public void Weixin_Send_Should_Be_Succeed()
{
// 支持Exception对象
var response = _weixinProvider?.Send("通知标题", new Exception("custom exception"))!;
// 支持Message文本
var response = _weixinProvider?.Send("通知标题", "custom exception")!;
.True(response.IsSuccess);
Assert}
// 企业微信群机器人支持@用户消息
[Fact]
public void Weixin_Send_Should_Be_SucceedByAt()
{
// 企业微信群机器人支持@用户消息
// UserId:@指定的用户ID列表,各消息平台的UserID,邮件平台为邮箱地址
// Mobile:@指定的手机号列表,请注意:飞书平台、邮箱发送不支持手机号
// IsAtAll:@所有人
var response = _weixinProvider?.Send("通知标题", new Exception("custom exception"), new CommonNoticeAtUser(){IsAtAll = false, Mobile = new[]{"159XXXXXX44"}})!;
// 企业微信群机器人支持@用户消息
// UserId:@指定的用户ID列表,各消息平台的UserID,邮件平台为邮箱地址
// Mobile:@指定的手机号列表,请注意:飞书平台、邮箱发送不支持手机号
// IsAtAll:@所有人
var response = _weixinProvider?.Send("通知标题", "custom exception", new CommonNoticeAtUser(){IsAtAll = false, Mobile = new[]{"159XXXXXX44"}})!;
.True(response.IsSuccess);
Assert}