搭建消息告警模块以及跨网推送服务,支持企微,飞书,钉钉通知

This commit is contained in:
2026-09-03 14:02:35 +08:00
parent cfa8e78d33
commit 3927b0c201
40 changed files with 4360 additions and 7 deletions
@@ -0,0 +1,75 @@
using Model.Entity.Inspection;
using Service.Interface;
using Common.Notify;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
namespace Service.Implement
{
/// <summary>
/// 企业微信群机器人通知发送器(群机器人 Webhook 无加签机制)
/// 报文:msgtype=texttext 类型才支持 mentioned_mobile_list @手机号)
/// </summary>
public class WeComNotifier : IAlertNotifier
{
private readonly HttpClient _httpClient;
private readonly ILogger<WeComNotifier> _logger;
public WeComNotifier(HttpClient httpClient, ILogger<WeComNotifier> logger)
{
_httpClient = httpClient;
_logger = logger;
}
public NotifyChannelTypeEnum ChannelType => NotifyChannelTypeEnum.WeCom;
public async Task<NotifyResult> SendAsync(AlertNotifyMessage message, string webhookUrl, string? secret, CancellationToken ct = default)
{
try
{
var text = new StringBuilder();
text.AppendLine(message.Title);
text.AppendLine(message.Content);
var body = new Dictionary<string, object>
{
["msgtype"] = "text",
["text"] = new Dictionary<string, object>
{
["content"] = text.ToString(),
["mentioned_mobile_list"] = message.AtMobiles
}
};
string json = JsonSerializer.Serialize(body);
_logger.LogInformation("企微推送 mentioned_mobile_list=[{At}]", string.Join(",", message.AtMobiles));
using var content = new StringContent(json, Encoding.UTF8, "application/json");
using var response = await _httpClient.PostAsync(webhookUrl, content, ct);
string respText = await response.Content.ReadAsStringAsync(ct);
if (!response.IsSuccessStatusCode)
{
return NotifyResult.Fail($"HTTP {(int)response.StatusCode}: {Truncate(respText)}");
}
// 企微返回 {"errcode":0,"errmsg":"ok"}
using var doc = JsonDocument.Parse(respText);
bool ok = doc.RootElement.TryGetProperty("errcode", out var errcode) && errcode.GetInt32() == 0;
return ok ? NotifyResult.Ok() : NotifyResult.Fail(Truncate(respText));
}
catch (Exception ex)
{
return NotifyResult.Fail($"企微推送异常: {NotifyError.Describe(ex)}");
}
}
private static string Truncate(string s, int max = 200) =>
string.IsNullOrEmpty(s) || s.Length <= max ? s : s.Substring(0, max) + "...";
}
}