feat: publish dbussmsforward refactor
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.Services;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace DbusSmsForward.Notifications;
|
||||
|
||||
public sealed class AutmanPushNotificationSender(DbusSmsForwardOptions options) : NotificationSenderBase("autmanpush")
|
||||
{
|
||||
private readonly AutmanPushConfig _config = options.Notifications.AutmanPush;
|
||||
|
||||
public override bool IsEnabled => _config.Enabled && !string.IsNullOrWhiteSpace(_config.ApiUrl);
|
||||
|
||||
public override async Task SendAsync(SmsContentModel sms, string body, string deviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
JsonObject payload = new()
|
||||
{
|
||||
["title"] = BuildTitle(sms.TelNumber, string.Empty),
|
||||
["content"] = body,
|
||||
["deviceName"] = deviceName,
|
||||
["phoneNumber"] = sms.TelNumber
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_config.AccessToken))
|
||||
{
|
||||
payload["accessToken"] = _config.AccessToken;
|
||||
}
|
||||
|
||||
await HttpHelper.PostAsync(_config.ApiUrl, payload, _config.SkipTlsValidation, cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.ProcessSmsContent;
|
||||
using DbusSmsForward.Services;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using System.Web;
|
||||
|
||||
namespace DbusSmsForward.Notifications;
|
||||
|
||||
public sealed class BarkNotificationSender(DbusSmsForwardOptions options) : NotificationSenderBase("bark")
|
||||
{
|
||||
private readonly BarkConfig _config = options.Notifications.Bark;
|
||||
|
||||
public override bool IsEnabled => _config.Enabled && !string.IsNullOrWhiteSpace(_config.ServerUrl) && !string.IsNullOrWhiteSpace(_config.BarkKey);
|
||||
|
||||
public override async Task SendAsync(SmsContentModel sms, string body, string deviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
SmsCodeModel code = NotificationContentBuilder.ExtractCode(options, sms);
|
||||
string url = $"{_config.ServerUrl.TrimEnd('/')}/{_config.BarkKey}/{HttpUtility.UrlEncode(body)}?group={HttpUtility.UrlEncode(sms.TelNumber)}&title={HttpUtility.UrlEncode(BuildTitle(sms.TelNumber, code.CodeValue))}";
|
||||
if (!string.IsNullOrWhiteSpace(code.CodeValue))
|
||||
{
|
||||
url += $"&autoCopy=1©={HttpUtility.UrlEncode(code.CodeValue)}";
|
||||
}
|
||||
|
||||
await HttpHelper.HttpGetAsync(url, _config.SkipTlsValidation, cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.Services;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Web;
|
||||
|
||||
namespace DbusSmsForward.Notifications;
|
||||
|
||||
public sealed class DingTalkNotificationSender(DbusSmsForwardOptions options) : NotificationSenderBase("dingtalk")
|
||||
{
|
||||
private readonly DingTalkConfig _config = options.Notifications.DingTalk;
|
||||
|
||||
public override bool IsEnabled => _config.Enabled && !string.IsNullOrWhiteSpace(_config.AccessToken);
|
||||
|
||||
public override async Task SendAsync(SmsContentModel sms, string body, string deviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
string url = $"{_config.Endpoint}?access_token={HttpUtility.UrlEncode(_config.AccessToken)}";
|
||||
if (!string.IsNullOrWhiteSpace(_config.Secret))
|
||||
{
|
||||
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
string sign = AddSign(timestamp, _config.Secret);
|
||||
url += $"×tamp={timestamp}&sign={sign}";
|
||||
}
|
||||
|
||||
JsonObject payload = new()
|
||||
{
|
||||
["msgtype"] = "text",
|
||||
["text"] = new JsonObject
|
||||
{
|
||||
["content"] = body
|
||||
}
|
||||
};
|
||||
|
||||
await HttpHelper.PostAsync(url, payload, _config.SkipTlsValidation, cancellationToken);
|
||||
}
|
||||
|
||||
private static string AddSign(long timestamp, string secret)
|
||||
{
|
||||
string stringToSign = $"{timestamp}\n{secret}";
|
||||
using HMACSHA256 hmacsha256 = new(Encoding.UTF8.GetBytes(secret));
|
||||
byte[] hashmessage = hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(stringToSign));
|
||||
return HttpUtility.UrlEncode(Convert.ToBase64String(hashmessage), Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using DbusSmsForward.ProcessSmsContent;
|
||||
using DbusSmsForward.Services;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using MailKit.Net.Smtp;
|
||||
using MimeKit;
|
||||
|
||||
namespace DbusSmsForward.Notifications;
|
||||
|
||||
public sealed class EmailNotificationSender(DbusSmsForwardOptions options) : NotificationSenderBase("email")
|
||||
{
|
||||
private readonly EmailConfig _config = options.Notifications.Email;
|
||||
|
||||
public override bool IsEnabled => _config.Enabled && !string.IsNullOrWhiteSpace(_config.SmtpHost) && !string.IsNullOrWhiteSpace(_config.SendEmail) && !string.IsNullOrWhiteSpace(_config.ReceiveEmail);
|
||||
|
||||
public override async Task SendAsync(SmsContentModel sms, string body, string deviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
SmsCodeModel code = NotificationContentBuilder.ExtractCode(options, sms);
|
||||
MimeMessage message = new();
|
||||
message.From.Add(new MailboxAddress("DbusSmsForward", _config.SendEmail));
|
||||
message.To.Add(new MailboxAddress(string.Empty, _config.ReceiveEmail));
|
||||
message.Subject = BuildTitle(sms.TelNumber, code.CodeValue);
|
||||
message.Body = new TextPart("plain") { Text = body };
|
||||
|
||||
using SmtpClient client = new();
|
||||
await client.ConnectAsync(_config.SmtpHost, _config.SmtpPort, _config.EnableSsl, cancellationToken);
|
||||
await client.AuthenticateAsync(_config.SendEmail, _config.EmailKey, cancellationToken);
|
||||
await client.SendAsync(message, cancellationToken);
|
||||
await client.DisconnectAsync(true, cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using DbusSmsForward.SMSModel;
|
||||
|
||||
namespace DbusSmsForward.Notifications;
|
||||
|
||||
public interface INotificationSender
|
||||
{
|
||||
string Name { get; }
|
||||
bool IsEnabled { get; }
|
||||
Task SendAsync(SmsContentModel sms, string body, string deviceName, CancellationToken cancellationToken);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using DbusSmsForward.SMSModel;
|
||||
|
||||
namespace DbusSmsForward.Notifications;
|
||||
|
||||
public abstract class NotificationSenderBase(string name) : INotificationSender
|
||||
{
|
||||
public string Name { get; } = name;
|
||||
public abstract bool IsEnabled { get; }
|
||||
public abstract Task SendAsync(SmsContentModel sms, string body, string deviceName, CancellationToken cancellationToken);
|
||||
|
||||
protected static string BuildTitle(string telNumber, string codeValue)
|
||||
=> string.IsNullOrWhiteSpace(codeValue) ? $"短信转发 {telNumber}" : $"{codeValue} 短信转发 {telNumber}";
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.Notifications;
|
||||
using DbusSmsForward.ProcessSmsContent;
|
||||
using DbusSmsForward.Services;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace DbusSmsForward.Notifications;
|
||||
|
||||
public sealed class PushPlusNotificationSender(DbusSmsForwardOptions options) : NotificationSenderBase("pushplus")
|
||||
{
|
||||
private readonly PushPlusConfig _config = options.Notifications.PushPlus;
|
||||
|
||||
public override bool IsEnabled => _config.Enabled && !string.IsNullOrWhiteSpace(_config.Token);
|
||||
|
||||
public override async Task SendAsync(SmsContentModel sms, string body, string deviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
SmsCodeModel code = NotificationContentBuilder.ExtractCode(options, sms);
|
||||
JsonObject payload = new()
|
||||
{
|
||||
["token"] = _config.Token,
|
||||
["title"] = BuildTitle(sms.TelNumber, code.CodeValue),
|
||||
["content"] = body,
|
||||
["topic"] = string.Empty
|
||||
};
|
||||
|
||||
await HttpHelper.PostAsync(_config.Endpoint, payload, _config.SkipTlsValidation, cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using DbusSmsForward.Services;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace DbusSmsForward.Notifications;
|
||||
|
||||
public sealed class ShellNotificationSender(DbusSmsForwardOptions options) : NotificationSenderBase("shell")
|
||||
{
|
||||
private readonly ShellConfig _config = options.Notifications.Shell;
|
||||
|
||||
public override bool IsEnabled => _config.Enabled && !string.IsNullOrWhiteSpace(_config.ShellPath);
|
||||
|
||||
public override async Task SendAsync(SmsContentModel sms, string body, string deviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
ProcessStartInfo startInfo = new()
|
||||
{
|
||||
FileName = _config.ShellPath,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true
|
||||
};
|
||||
|
||||
foreach (string arg in new[]
|
||||
{
|
||||
sms.TelNumber,
|
||||
sms.SmsDate,
|
||||
sms.SmsContent,
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
deviceName
|
||||
})
|
||||
{
|
||||
startInfo.ArgumentList.Add(arg ?? string.Empty);
|
||||
}
|
||||
|
||||
using Process process = Process.Start(startInfo) ?? throw new InvalidOperationException("Unable to start shell process.");
|
||||
using CancellationTokenRegistration registration = cancellationToken.Register(() =>
|
||||
{
|
||||
try { if (!process.HasExited) process.Kill(true); } catch { }
|
||||
});
|
||||
|
||||
await process.WaitForExitAsync(cancellationToken);
|
||||
if (process.ExitCode != 0)
|
||||
{
|
||||
string error = await process.StandardError.ReadToEndAsync(cancellationToken);
|
||||
throw new InvalidOperationException($"Shell sender exited with code {process.ExitCode}: {error}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.Services;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using System.Web;
|
||||
|
||||
namespace DbusSmsForward.Notifications;
|
||||
|
||||
public sealed class TelegramNotificationSender(DbusSmsForwardOptions options) : NotificationSenderBase("telegram")
|
||||
{
|
||||
private readonly TelegramBotConfig _config = options.Notifications.TelegramBot;
|
||||
|
||||
public override bool IsEnabled => _config.Enabled && !string.IsNullOrWhiteSpace(_config.BotToken) && !string.IsNullOrWhiteSpace(_config.ChatId);
|
||||
|
||||
public override async Task SendAsync(SmsContentModel sms, string body, string deviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
string apiBase = _config.EnableCustomApi && !string.IsNullOrWhiteSpace(_config.CustomApi)
|
||||
? _config.CustomApi.TrimEnd('/')
|
||||
: "https://api.telegram.org";
|
||||
|
||||
string text = body;
|
||||
string url = $"{apiBase}/bot{_config.BotToken}/sendMessage?chat_id={HttpUtility.UrlEncode(_config.ChatId)}&text={HttpUtility.UrlEncode(text)}";
|
||||
await HttpHelper.HttpGetAsync(url, _config.SkipTlsValidation, cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.Services;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace DbusSmsForward.Notifications;
|
||||
|
||||
public sealed class WeComApplicationNotificationSender(DbusSmsForwardOptions options) : NotificationSenderBase("wecom")
|
||||
{
|
||||
private readonly WeComApplicationConfig _config = options.Notifications.WeComApplication;
|
||||
|
||||
public override bool IsEnabled => _config.Enabled && !string.IsNullOrWhiteSpace(_config.CorpId) && !string.IsNullOrWhiteSpace(_config.AgentId) && !string.IsNullOrWhiteSpace(_config.ApplicationSecret);
|
||||
|
||||
public override async Task SendAsync(SmsContentModel sms, string body, string deviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
string tokenUrl = $"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={Uri.EscapeDataString(_config.CorpId)}&corpsecret={Uri.EscapeDataString(_config.ApplicationSecret)}";
|
||||
string tokenResponse = await HttpHelper.HttpGetAsync(tokenUrl, _config.SkipTlsValidation, cancellationToken);
|
||||
JsonObject tokenJson = JsonNode.Parse(tokenResponse)?.AsObject() ?? throw new InvalidOperationException("Invalid WeCom token response.");
|
||||
string accessToken = tokenJson["access_token"]?.ToString() ?? throw new InvalidOperationException("WeCom access_token missing.");
|
||||
|
||||
JsonObject payload = new()
|
||||
{
|
||||
["touser"] = "@all",
|
||||
["msgtype"] = "text",
|
||||
["agentid"] = _config.AgentId,
|
||||
["text"] = new JsonObject
|
||||
{
|
||||
["content"] = body
|
||||
},
|
||||
["safe"] = 0
|
||||
};
|
||||
|
||||
string sendUrl = $"https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={Uri.EscapeDataString(accessToken)}";
|
||||
await HttpHelper.PostAsync(sendUrl, payload, _config.SkipTlsValidation, cancellationToken);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user