feat: publish dbussmsforward refactor
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Worker">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<InvariantGlobalization>true</InvariantGlobalization>
|
||||
<RootNamespace>DbusSmsForward</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MailKit" Version="4.14.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.0" />
|
||||
<PackageReference Include="Tmds.DBus.Protocol" Version="0.22.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="ProcessUserChoise/**/*.cs" />
|
||||
<Compile Remove="SendMethod/**/*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="appsettings.example.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,208 @@
|
||||
using DbusSmsForward.SettingModel;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace DbusSmsForward.Helper;
|
||||
|
||||
public static class ConfigHelper
|
||||
{
|
||||
private static readonly JsonSerializerOptions JsonOptions = new(SourceGenerationContext.Default.Options)
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
WriteIndented = true
|
||||
};
|
||||
|
||||
public static string DefaultSettingsFileName => Path.Combine(AppContext.BaseDirectory, "appsettings.json");
|
||||
|
||||
public static string ResolveConfigPath(IConfiguration? configuration = null)
|
||||
{
|
||||
string[] candidates =
|
||||
[
|
||||
configuration?["DBUSSMSFORWARD_CONFIG_PATH"] ?? string.Empty,
|
||||
Environment.GetEnvironmentVariable("DBUSSMSFORWARD_CONFIG_PATH") ?? string.Empty,
|
||||
"/etc/dbussmsforward/appsettings.json",
|
||||
DefaultSettingsFileName
|
||||
];
|
||||
|
||||
foreach (string candidate in candidates)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(candidate) && File.Exists(candidate))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
return candidates.Last(static c => !string.IsNullOrWhiteSpace(c));
|
||||
}
|
||||
|
||||
public static DbusSmsForwardOptions LoadOptions(IConfiguration? configuration = null)
|
||||
{
|
||||
DbusSmsForwardOptions options = new();
|
||||
string configPath = ResolveConfigPath(configuration);
|
||||
if (File.Exists(configPath))
|
||||
{
|
||||
string json = File.ReadAllText(configPath);
|
||||
options = JsonSerializer.Deserialize(json, SourceGenerationContext.Default.DbusSmsForwardOptions) ?? new DbusSmsForwardOptions();
|
||||
}
|
||||
|
||||
if (configuration is not null)
|
||||
{
|
||||
configuration.GetSection("DbusSmsForward").Bind(options);
|
||||
configuration.GetSection("Daemon").Bind(options.Daemon);
|
||||
configuration.GetSection("Modem").Bind(options.Modem);
|
||||
configuration.GetSection("Forwarding").Bind(options.Forwarding);
|
||||
configuration.GetSection("Notifications").Bind(options.Notifications);
|
||||
configuration.GetSection("LegacyCompatibility").Bind(options.LegacyCompatibility);
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
public static void SaveOptions(DbusSmsForwardOptions options, string? path = null)
|
||||
{
|
||||
string target = path ?? ResolveConfigPath();
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(target) ?? AppContext.BaseDirectory);
|
||||
string updatedJson = JsonSerializer.Serialize(options, SourceGenerationContext.Default.DbusSmsForwardOptions);
|
||||
File.WriteAllText(target, updatedJson);
|
||||
}
|
||||
|
||||
public static void SaveLegacySettings(appsettingsModel result, string? path = null)
|
||||
{
|
||||
string target = path ?? DefaultSettingsFileName;
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(target) ?? AppContext.BaseDirectory);
|
||||
string updatedJson = JsonSerializer.Serialize(result, SourceGenerationContext.Default.appsettingsModel);
|
||||
File.WriteAllText(target, updatedJson);
|
||||
}
|
||||
|
||||
public static void GetSettings(ref appsettingsModel result)
|
||||
{
|
||||
string settingsFileName = ResolveConfigPath();
|
||||
if (!File.Exists(settingsFileName))
|
||||
{
|
||||
result ??= new appsettingsModel();
|
||||
return;
|
||||
}
|
||||
|
||||
string config = File.ReadAllText(settingsFileName);
|
||||
|
||||
try
|
||||
{
|
||||
if (LooksLikeNewConfig(config))
|
||||
{
|
||||
DbusSmsForwardOptions options = JsonSerializer.Deserialize(config, SourceGenerationContext.Default.DbusSmsForwardOptions) ?? new DbusSmsForwardOptions();
|
||||
result = ConvertToLegacy(options);
|
||||
return;
|
||||
}
|
||||
|
||||
result = JsonSerializer.Deserialize(config, SourceGenerationContext.Default.appsettingsModel) ?? new appsettingsModel();
|
||||
}
|
||||
catch
|
||||
{
|
||||
result ??= new appsettingsModel();
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateSettings(ref appsettingsModel result)
|
||||
{
|
||||
SaveLegacySettings(result);
|
||||
}
|
||||
|
||||
public static bool JudgeIsForwardIgnore(uint storage)
|
||||
{
|
||||
appsettingsModel result = new();
|
||||
GetSettings(ref result);
|
||||
string forwardStorageType = result.appSettings.ForwardIgnoreStorageType?.Trim().ToLowerInvariant() ?? string.Empty;
|
||||
|
||||
return (forwardStorageType, storage) switch
|
||||
{
|
||||
("unknown", 0) => true,
|
||||
("sm", 1) => true,
|
||||
("me", 2) => true,
|
||||
("mt", 3) => true,
|
||||
("sr", 4) => true,
|
||||
("bm", 5) => true,
|
||||
("ta", 6) => true,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
public static string GetDeviceHostName()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Dns.GetHostName();
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
return Environment.MachineName;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string ResolveDeviceName(DbusSmsForwardOptions options)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(options.Forwarding.DeviceName))
|
||||
{
|
||||
return options.Forwarding.DeviceName;
|
||||
}
|
||||
|
||||
return GetDeviceHostName();
|
||||
}
|
||||
|
||||
public static appsettingsModel ConvertToLegacy(DbusSmsForwardOptions options)
|
||||
{
|
||||
return new appsettingsModel
|
||||
{
|
||||
appSettings = new LegacyAppSettings
|
||||
{
|
||||
EmailConfig = options.Notifications.Email,
|
||||
PushPlusConfig = options.Notifications.PushPlus,
|
||||
DingTalkConfig = options.Notifications.DingTalk,
|
||||
BarkConfig = options.Notifications.Bark,
|
||||
WeComApplicationConfig = options.Notifications.WeComApplication,
|
||||
TGBotConfig = options.Notifications.TelegramBot,
|
||||
ShellConfig = options.Notifications.Shell,
|
||||
SmsCodeKey = options.Forwarding.SmsCodeKey,
|
||||
ForwardIgnoreStorageType = options.Forwarding.IgnoreStorageType,
|
||||
DeviceName = options.Forwarding.DeviceName
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static DbusSmsForwardOptions ConvertFromLegacy(appsettingsModel legacy)
|
||||
{
|
||||
return new DbusSmsForwardOptions
|
||||
{
|
||||
Forwarding = new ForwardingConfig
|
||||
{
|
||||
DeviceName = legacy.appSettings.DeviceName,
|
||||
SmsCodeKey = legacy.appSettings.SmsCodeKey,
|
||||
IgnoreStorageType = legacy.appSettings.ForwardIgnoreStorageType
|
||||
},
|
||||
Notifications = new NotificationChannels
|
||||
{
|
||||
Email = legacy.appSettings.EmailConfig,
|
||||
PushPlus = legacy.appSettings.PushPlusConfig,
|
||||
DingTalk = legacy.appSettings.DingTalkConfig,
|
||||
Bark = legacy.appSettings.BarkConfig,
|
||||
WeComApplication = legacy.appSettings.WeComApplicationConfig,
|
||||
TelegramBot = legacy.appSettings.TGBotConfig,
|
||||
Shell = legacy.appSettings.ShellConfig
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static bool LooksLikeNewConfig(string json)
|
||||
{
|
||||
using JsonDocument document = JsonDocument.Parse(json);
|
||||
JsonElement root = document.RootElement;
|
||||
return root.TryGetProperty("Daemon", out _) || root.TryGetProperty("Notifications", out _) || root.TryGetProperty("Forwarding", out _);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Net.Http.Json;
|
||||
using System.Text;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace DbusSmsForward.Helper;
|
||||
|
||||
public static class HttpHelper
|
||||
{
|
||||
public static string HttpGet(string url)
|
||||
=> HttpGetAsync(url).GetAwaiter().GetResult();
|
||||
|
||||
public static async Task<string> HttpGetAsync(string url, bool skipTlsValidation = false, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using HttpClient client = CreateClient(skipTlsValidation);
|
||||
using HttpResponseMessage response = await client.GetAsync(url, cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadAsStringAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public static string Post(string url, JsonObject obj)
|
||||
=> PostAsync(url, obj).GetAwaiter().GetResult();
|
||||
|
||||
public static async Task<string> PostAsync(string url, JsonObject obj, bool skipTlsValidation = false, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using HttpClient client = CreateClient(skipTlsValidation);
|
||||
using StringContent content = new(obj.ToJsonString(), Encoding.UTF8, "application/json");
|
||||
using HttpResponseMessage response = await client.PostAsync(url, content, cancellationToken);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadAsStringAsync(cancellationToken);
|
||||
}
|
||||
|
||||
private static HttpClient CreateClient(bool skipTlsValidation)
|
||||
{
|
||||
HttpClientHandler handler = new();
|
||||
if (skipTlsValidation)
|
||||
{
|
||||
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
|
||||
}
|
||||
|
||||
return new HttpClient(handler)
|
||||
{
|
||||
Timeout = TimeSpan.FromSeconds(30)
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace DbusSmsForward.Models;
|
||||
|
||||
public sealed class AppCommand
|
||||
{
|
||||
public string Name { get; init; } = "run";
|
||||
public bool PrintSampleConfig { get; init; }
|
||||
public bool ValidateConfig { get; init; }
|
||||
public string PhoneNumber { get; init; } = string.Empty;
|
||||
public string Message { get; init; } = string.Empty;
|
||||
public string[] EnabledChannels { get; init; } = [];
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,836 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using ModemManager1.DBus;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using Tmds.DBus.Protocol;
|
||||
|
||||
namespace DbusSmsForward.ModemHelper
|
||||
{
|
||||
public class ModemManagerHelper
|
||||
{
|
||||
private readonly Lock _modemObjectPathListLockObject = new();
|
||||
public Dictionary<ObjectPath, Dictionary<string, Dictionary<string, VariantValue>>> _modemObjectPathList = new Dictionary<ObjectPath, Dictionary<string, Dictionary<string, VariantValue>>>();
|
||||
public string _modemObjectPathNowUse = "";
|
||||
public string qmiPathNowUse = "";
|
||||
public string _modemManagerObjectPath = "/org/freedesktop/ModemManager1";
|
||||
public string? systemBusAddress = Address.System;
|
||||
public string baseService = "org.freedesktop.ModemManager1";
|
||||
public List<Action<SmsContentModel, string, string>> smsSendMethodList = new List<Action<SmsContentModel, string, string>>();
|
||||
public string deviceUidNowUse = "";
|
||||
private readonly Lock _subscribeSmsPathListLockObject = new();
|
||||
public Dictionary<string,bool> SubscribeSmsPathList=new Dictionary<string, bool>();
|
||||
|
||||
public ModemManagerHelper()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(systemBusAddress))
|
||||
{
|
||||
InitLoadModemObjectPathList();
|
||||
WatchModems();
|
||||
}
|
||||
}
|
||||
|
||||
public void InitLoadModemObjectPathList()
|
||||
{
|
||||
lock (_modemObjectPathListLockObject)
|
||||
{
|
||||
_modemObjectPathList = GetModemsPathList().Result;
|
||||
}
|
||||
if (_modemObjectPathList.Count == 1)
|
||||
{
|
||||
SetNowUsedModemPath(_modemObjectPathList.First().Key);
|
||||
}
|
||||
if (_modemObjectPathList.Count == 0)
|
||||
{
|
||||
SetNowUsedModemPath(null);
|
||||
}
|
||||
foreach (var item in _modemObjectPathList)
|
||||
{
|
||||
SubscribeSms(item.Key);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetSendMethodList(List<Action<SmsContentModel, string, string>> SendMethodList)
|
||||
{
|
||||
smsSendMethodList = SendMethodList;
|
||||
}
|
||||
|
||||
public void SetNowUsedModemPath(string modemObjectPathNowUse)
|
||||
{
|
||||
_modemObjectPathNowUse = modemObjectPathNowUse;
|
||||
if (string.IsNullOrEmpty(_modemObjectPathNowUse))
|
||||
{
|
||||
qmiPathNowUse = "";
|
||||
deviceUidNowUse = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
qmiPathNowUse = GetQMIDevice().Result;
|
||||
deviceUidNowUse = GetDevice().Result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void WatchModems()
|
||||
{
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var objectManager = service.CreateObjectManager(_modemManagerObjectPath);
|
||||
//Console.WriteLine($"Subscribing for modem RemovedChanges");
|
||||
await objectManager.WatchInterfacesRemovedAsync(
|
||||
async (Exception? ex, (ObjectPath ObjectPath, string[] Interfaces) change) =>
|
||||
{
|
||||
if (ex is null)
|
||||
{
|
||||
//Console.WriteLine("modem has been removed,modem path:" + change.ObjectPath.ToString());
|
||||
InitLoadModemObjectPathList();
|
||||
if (!string.IsNullOrEmpty(_modemObjectPathNowUse))
|
||||
{
|
||||
DisableAndEnableModem().Wait();
|
||||
}
|
||||
}
|
||||
});
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
var task = tcs.Task;
|
||||
await task;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
});
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var objectManager = service.CreateObjectManager(_modemManagerObjectPath);
|
||||
//Console.WriteLine($"Subscribing for modem AddedChanges");
|
||||
await objectManager.WatchInterfacesAddedAsync(
|
||||
async (Exception? ex, (ObjectPath ObjectPath, Dictionary<string, Dictionary<string, VariantValue>> InterfacesAndProperties) change) =>
|
||||
{
|
||||
if (ex is null)
|
||||
{
|
||||
//Console.WriteLine("new modem added,modem path:" + change.ObjectPath.ToString());
|
||||
InitLoadModemObjectPathList();
|
||||
if (!string.IsNullOrEmpty(_modemObjectPathNowUse))
|
||||
{
|
||||
DisableAndEnableModem().Wait();
|
||||
}
|
||||
}
|
||||
});
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
var task = tcs.Task;
|
||||
await task;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void SubscribeSms(string path)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((!SubscribeSmsPathList.ContainsKey(path) || (SubscribeSmsPathList.ContainsKey(path) && !SubscribeSmsPathList[path]))&& _modemObjectPathList.ContainsKey(path))
|
||||
{
|
||||
if (SubscribeSmsPathList.ContainsKey(path))
|
||||
{
|
||||
lock (_subscribeSmsPathListLockObject)
|
||||
{
|
||||
SubscribeSmsPathList[path] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (_subscribeSmsPathListLockObject)
|
||||
{
|
||||
SubscribeSmsPathList.Add(path, true);
|
||||
}
|
||||
}
|
||||
//SetMsgDefaultStorageToME(path);
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var messaging = service.CreateMessaging(path);
|
||||
//Console.WriteLine($"add subscribe sms for modem path:" + path);
|
||||
await messaging.WatchAddedAsync(
|
||||
async (Exception? ex, (ObjectPath Path, bool Received) change) =>
|
||||
{
|
||||
if (ex is null)
|
||||
{
|
||||
if (change.Received)
|
||||
{
|
||||
try
|
||||
{
|
||||
var smsPath = change.Path;
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var sms = service.CreateSms(smsPath);
|
||||
var smsState = await sms.GetStateAsync();
|
||||
if (smsState == 2 || smsState == 3)
|
||||
{
|
||||
uint Storage = await sms.GetStorageAsync();
|
||||
if (!ConfigHelper.JudgeIsForwardIgnore(Storage))
|
||||
{
|
||||
string telNum = await sms.GetNumberAsync();
|
||||
//string smsDate = (await sms.GetTimestampAsync()).Replace("T", " ").Replace("+08:00", " ");
|
||||
|
||||
string smsdateOrg = await sms.GetTimestampAsync();
|
||||
string smsDate = string.Empty;
|
||||
try
|
||||
{
|
||||
DateTimeOffset dto = DateTimeOffset.Parse(smsdateOrg, null, DateTimeStyles.RoundtripKind);
|
||||
|
||||
// 转换为本地时间
|
||||
DateTime localTime = dto.LocalDateTime;
|
||||
smsDate = localTime.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
catch (Exception ex1)
|
||||
{
|
||||
Console.WriteLine("smsdate转换失败:\n" + ex1.Message);
|
||||
smsDate = smsdateOrg;
|
||||
}
|
||||
int tryCount = 0;
|
||||
do
|
||||
{
|
||||
smsState = await sms.GetStateAsync();
|
||||
Thread.Sleep(100);
|
||||
} while (smsState == 2 && tryCount < 300);
|
||||
|
||||
if (smsState == 3)
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string DeviceName = result.appSettings.DeviceName;
|
||||
result = null;
|
||||
if (string.IsNullOrEmpty(DeviceName) || DeviceName== "*Host*Name*")
|
||||
{
|
||||
DeviceName= ConfigHelper.GetDeviceHostName();
|
||||
}
|
||||
|
||||
string smsContent = await sms.GetTextAsync();
|
||||
SmsContentModel smsmodel = new SmsContentModel();
|
||||
smsmodel.TelNumber = telNum;
|
||||
smsmodel.SmsDate = smsDate;
|
||||
smsmodel.SmsContent = smsContent;
|
||||
string body = "发信电话:" + telNum + "\n" + "时间:" + smsDate + "\n" + "转发设备:" + DeviceName + "\n" + "短信内容:" + smsContent;
|
||||
Console.WriteLine("smspath " + smsPath);
|
||||
if (smsSendMethodList.Count() > 0)
|
||||
{
|
||||
//Console.WriteLine("转发方法数量"+smsSendMethodList.Count());
|
||||
foreach (var action in smsSendMethodList)
|
||||
{
|
||||
action.Invoke(smsmodel, body, DeviceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("smspath:" + change.Path + " 接收超时,转发取消");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
Console.WriteLine("GetSmsError" + ex2.Message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
});
|
||||
Task task = Task.Run(() =>
|
||||
{
|
||||
var modem = service.CreateModem(path);
|
||||
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
var Manufacturer = modem.GetManufacturerAsync().Result;
|
||||
Manufacturer = null;
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
} while (SubscribeSmsPathList.ContainsKey(path) && SubscribeSmsPathList[path] && _modemObjectPathList.ContainsKey(path));
|
||||
if (SubscribeSmsPathList.ContainsKey(path))
|
||||
{
|
||||
lock (_subscribeSmsPathListLockObject)
|
||||
{
|
||||
SubscribeSmsPathList[path] = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
await task;
|
||||
//Console.WriteLine($"remove subscribe sms for modem path:" + path);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
Console.WriteLine($"remove subscribe sms for modem path:" + path);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public async Task<bool> SendSms(string telNum, string smsContent)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var connection = new Connection(Address.System))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var messaging = service.CreateMessaging(_modemObjectPathNowUse);
|
||||
var sendsmsPath = await messaging.CreateAsync(new Dictionary<string, VariantValue> { { "text", smsContent }, { "number", telNum } });
|
||||
var sms = service.CreateSms(sendsmsPath);
|
||||
await sms.SendAsync();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Dictionary<ObjectPath, Dictionary<string, Dictionary<string, VariantValue>>>> GetModemsPathList()
|
||||
{
|
||||
try
|
||||
{
|
||||
await ScanDevices();
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var objectManager = service.CreateObjectManager(_modemManagerObjectPath);
|
||||
return await objectManager.GetManagedObjectsAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
return new Dictionary<ObjectPath, Dictionary<string, Dictionary<string, VariantValue>>>();
|
||||
}
|
||||
|
||||
public async Task ScanDevices()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modemManager = service.CreateModemManager1(_modemManagerObjectPath);
|
||||
await modemManager.ScanDevicesAsync();
|
||||
modemManager = null;
|
||||
service = null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!(ex.Message.IndexOf("unsupported") >-1))
|
||||
{
|
||||
Console.WriteLine("ScanDevices失败" + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> GetManufacturer(string? path = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string actUsePath = path == null ? _modemObjectPathNowUse : path;
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modem = service.CreateModem(actUsePath);
|
||||
var Manufacturer = await modem.GetManufacturerAsync();
|
||||
modem = null;
|
||||
service = null;
|
||||
return Manufacturer;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> JudgeCanGetStatus(string? path = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string actUsePath = path == null ? _modemObjectPathNowUse : path;
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modem = service.CreateSimple(actUsePath);
|
||||
var status = await modem.GetStatusAsync();
|
||||
modem = null;
|
||||
service = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//Console.WriteLine(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DisableAndEnableModem(string? path = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string actUsePath = path == null ? _modemObjectPathNowUse : path;
|
||||
if (!string.IsNullOrEmpty(actUsePath))
|
||||
{
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modem = service.CreateModem(actUsePath);
|
||||
try
|
||||
{
|
||||
await modem.EnableAsync(false);
|
||||
Thread.Sleep(200);
|
||||
await modem.EnableAsync(true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("DisableAndEnableModem:actUsePath为空");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task InhibitModemDevice(string uid, bool inhibit)
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine("device:" + uid);
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modemManager = service.CreateModemManager1(_modemManagerObjectPath);
|
||||
await modemManager.InhibitDeviceAsync(uid, inhibit);
|
||||
modemManager = null;
|
||||
service = null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("InhibitModemDevice失败" + ex);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> GetDevice(string? path = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string actUsePath = path == null ? _modemObjectPathNowUse : path;
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modem = service.CreateModem(actUsePath);
|
||||
var device = await modem.GetDeviceAsync();
|
||||
modem = null;
|
||||
service = null;
|
||||
return device;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> GetQMIDevice(string? path = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string actUsePath = path == null ? _modemObjectPathNowUse : path;
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modem = service.CreateModem(actUsePath);
|
||||
var Ports = await modem.GetPortsAsync();
|
||||
foreach (var port in Ports)
|
||||
{
|
||||
if (port.Item2 == 6)
|
||||
{
|
||||
return "/dev/" + port.Item1;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task<string> GetModel(string? path = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string actUsePath = path == null ? _modemObjectPathNowUse : path;
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modem = service.CreateModem(actUsePath);
|
||||
var Model = await modem.GetModelAsync();
|
||||
modem = null;
|
||||
service = null;
|
||||
return Model;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
public async Task<string> GetRevision(string? path = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string actUsePath = path == null ? _modemObjectPathNowUse : path;
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modem = service.CreateModem(actUsePath);
|
||||
var Revision = await modem.GetRevisionAsync();
|
||||
modem = null;
|
||||
service = null;
|
||||
return Revision;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
public async Task<string> GetSignalQuality(string? path = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string actUsePath = path == null ? _modemObjectPathNowUse : path;
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modem = service.CreateModem(actUsePath);
|
||||
var SignalQuality = await modem.GetSignalQualityAsync();
|
||||
modem = null;
|
||||
service = null;
|
||||
return SignalQuality.Item1.ToString();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
public async Task<string[]> GetOwnNumbers(string? path = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string actUsePath = path == null ? _modemObjectPathNowUse : path;
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modem = service.CreateModem(actUsePath);
|
||||
var OwnNumbers = await modem.GetOwnNumbersAsync();
|
||||
modem = null;
|
||||
service = null;
|
||||
return OwnNumbers;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<uint?> GetPrimarySimSlot(string? path = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string actUsePath = path == null ? _modemObjectPathNowUse : path;
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modem = service.CreateModem(actUsePath);
|
||||
var PrimarySimSlot = await modem.GetPrimarySimSlotAsync();
|
||||
return PrimarySimSlot;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> GetICCID(string? path = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string actUsePath = path == null ? _modemObjectPathNowUse : path;
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modem = service.CreateModem(actUsePath);
|
||||
var simpath = await modem.GetSimAsync();
|
||||
var sim = service.CreateSim(simpath);
|
||||
var iccid = await sim.GetSimIdentifierAsync();
|
||||
modem = null;
|
||||
service = null;
|
||||
return iccid;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> GetImei(string? path = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string actUsePath = path == null ? _modemObjectPathNowUse : path;
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modem3gpp = service.CreateModem3gpp(actUsePath);
|
||||
var Imei = await modem3gpp.GetImeiAsync();
|
||||
modem3gpp = null;
|
||||
service = null;
|
||||
return Imei;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
public async Task<string> GetOperatorCode(string? path = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string actUsePath = path == null ? _modemObjectPathNowUse : path;
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modem3gpp = service.CreateModem3gpp(actUsePath);
|
||||
var OperatorCode = await modem3gpp.GetOperatorCodeAsync();
|
||||
modem3gpp = null;
|
||||
service = null;
|
||||
return OperatorCode;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
public async Task<string> GetOperatorName(string? path = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string actUsePath = path == null ? _modemObjectPathNowUse : path;
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var modem3gpp = service.CreateModem3gpp(actUsePath);
|
||||
var OperatorName = await modem3gpp.GetOperatorNameAsync();
|
||||
modem3gpp = null;
|
||||
service = null;
|
||||
return OperatorName;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SetMsgDefaultStorageToME(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var connection = new Connection(systemBusAddress))
|
||||
{
|
||||
await connection.ConnectAsync();
|
||||
var service = new ModemManager1Service(connection, baseService);
|
||||
var messaging = service.CreateMessaging(path);
|
||||
await messaging.SetDefaultStorageAsync(2);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
public bool RestartModem()
|
||||
{
|
||||
string qmiPath = GetQMIDevice().Result;
|
||||
uint? simslot = GetPrimarySimSlot().Result;
|
||||
string usedDevice = deviceUidNowUse;
|
||||
if (simslot.HasValue)
|
||||
{
|
||||
if (simslot.Value == 0)
|
||||
{
|
||||
simslot += 1;
|
||||
}
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "qmicli",
|
||||
Arguments = @$"-d {qmiPath} -p --uim-sim-power-off={simslot}",
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
using (Process process = Process.Start(startInfo))
|
||||
{
|
||||
if (process != null)
|
||||
{
|
||||
string output = process.StandardOutput.ReadToEnd();
|
||||
string error = process.StandardError.ReadToEnd();
|
||||
process.WaitForExit();
|
||||
if (process.ExitCode != 0)
|
||||
{
|
||||
Console.WriteLine(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Failed to exec qmicli");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ProcessStartInfo startInfo2 = new ProcessStartInfo
|
||||
{
|
||||
FileName = "qmicli",
|
||||
Arguments = @$"-d {qmiPath} -p --uim-sim-power-on={simslot}",
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
using (Process process = Process.Start(startInfo2))
|
||||
{
|
||||
if (process != null)
|
||||
{
|
||||
string output = process.StandardOutput.ReadToEnd();
|
||||
string error = process.StandardError.ReadToEnd();
|
||||
process.WaitForExit();
|
||||
if (process.ExitCode != 0)
|
||||
{
|
||||
Console.WriteLine(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Failed to exec qmicli");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (JudgeCanGetStatus().Result)
|
||||
{
|
||||
DisableAndEnableModem().Wait();
|
||||
}
|
||||
Thread.Sleep(200);
|
||||
if (JudgeCanGetStatus().Result)
|
||||
{
|
||||
InhibitModemDevice(usedDevice, true).Wait();
|
||||
Thread.Sleep(200);
|
||||
InhibitModemDevice(usedDevice, false).Wait();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace DbusSmsForward.ProcessSmsContent
|
||||
{
|
||||
public static class GetSmsContentCode
|
||||
{
|
||||
public static string GetSmsCodeStr(string smscontent)
|
||||
{
|
||||
SmsCodeModel smsCodeModel = new SmsCodeModel();
|
||||
smsCodeModel = GetSmsCodeModel(smscontent);
|
||||
if (smsCodeModel.HasCode)
|
||||
{
|
||||
return smsCodeModel.CodeFrom + smsCodeModel.CodeValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
public static SmsCodeModel GetSmsCodeModel(string smscontent)
|
||||
{
|
||||
SmsCodeModel smsCodeModel = new SmsCodeModel();
|
||||
string newsmscontent=string.Empty;
|
||||
|
||||
if (JudgeSmsContentHasCode(smscontent,out newsmscontent))
|
||||
{
|
||||
string smscode= GetCode(newsmscontent).Trim();
|
||||
if (string.IsNullOrEmpty(smscode))
|
||||
{
|
||||
smsCodeModel.HasCode = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
smsCodeModel.HasCode = true;
|
||||
smsCodeModel.CodeValue = smscode;
|
||||
smsCodeModel.CodeFrom = GetCodeSmsFrom(smscontent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
smsCodeModel.HasCode = false;
|
||||
}
|
||||
return smsCodeModel;
|
||||
}
|
||||
public static bool JudgeSmsContentHasCode(string smscontent,out string newsmscontent)
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string codeKeyStr = result.appSettings.SmsCodeKey;
|
||||
result = null;
|
||||
string[] flagStrList = {};
|
||||
try
|
||||
{
|
||||
flagStrList = codeKeyStr.Split("±");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("配置文件中自定义验证码关键词格式有误,已使用默认关键词“验证码”");
|
||||
flagStrList.Append("验证码");
|
||||
}
|
||||
|
||||
foreach (string flag in flagStrList)
|
||||
{
|
||||
if (smscontent.IndexOf(flag) > -1)
|
||||
{
|
||||
newsmscontent = smscontent.Replace(flag, " "+flag+" ");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
newsmscontent=string.Empty;
|
||||
return false;
|
||||
}
|
||||
public static string GetCode(string smscontent)
|
||||
{
|
||||
string pattern = @"\b[A-Za-z0-9]{4,7}\b";
|
||||
MatchCollection SmsCodeMatches = Regex.Matches(smscontent, pattern);
|
||||
if (SmsCodeMatches.Count()> 1)
|
||||
{
|
||||
int maxDigits = 0;
|
||||
string maxDigitsString = "";
|
||||
foreach (Match match in SmsCodeMatches)
|
||||
{
|
||||
string currentString = match.Value;
|
||||
int digitCount = CountDigits(currentString);
|
||||
if (digitCount > maxDigits)
|
||||
{
|
||||
maxDigits = digitCount;
|
||||
maxDigitsString = currentString;
|
||||
}
|
||||
}
|
||||
return maxDigitsString;
|
||||
}
|
||||
else if (SmsCodeMatches.Count()==1)
|
||||
{
|
||||
return SmsCodeMatches[0].Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
public static string GetCodeSmsFrom(string smscontent)
|
||||
{
|
||||
string pattern = @"^\【(.*?)\】";
|
||||
Match match = Regex.Match(smscontent, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
return match.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
string pattern1 = @"【([^【】]+)】$";
|
||||
Match match1 = Regex.Match(smscontent, pattern1);
|
||||
if (match1.Success)
|
||||
{
|
||||
return match1.Value;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
public static int CountDigits(string input)
|
||||
{
|
||||
int count = 0;
|
||||
foreach (char c in input)
|
||||
{
|
||||
if (char.IsDigit(c))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
using DbusSmsForward.SendMethod;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DbusSmsForward.ProcessUserChoise
|
||||
{
|
||||
public static class ProcessChoise
|
||||
{
|
||||
public static string onStartGuide(string chooseOption)
|
||||
{
|
||||
if (string.IsNullOrEmpty(chooseOption))
|
||||
{
|
||||
Console.WriteLine("请选择运行模式:1为短信转发模式,2为发短信模式");
|
||||
chooseOption = Console.ReadLine();
|
||||
}
|
||||
if (chooseOption == "1" || chooseOption == "2")
|
||||
{
|
||||
return chooseOption;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("请输入1或2");
|
||||
return onStartGuide("");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static List<Action<SmsContentModel, string, string>> sendMethodGuide(List<string> chooseOptions)
|
||||
{
|
||||
if(chooseOptions.Count() == 0)
|
||||
{
|
||||
Console.WriteLine("请选择转发渠道:1.邮箱转发,2.pushplus转发,3.企业微信转发,4.TG机器人转发,5.钉钉转发,6.Bark转发,7.自定义shell转发,同时转发多渠道请以空格分割编号(举例:1 2 3 5)");
|
||||
chooseOptions.Add(Console.ReadLine());
|
||||
return sendMethodGuide(chooseOptions);
|
||||
}
|
||||
else if (chooseOptions.Count() >= 1)
|
||||
{
|
||||
|
||||
if (chooseOptions.Count() == 1 && chooseOptions[0].IndexOf(" ") > -1)
|
||||
{
|
||||
string chooseOption = chooseOptions[0];
|
||||
List<string> newChooseOptions = chooseOption.Split(" ").ToList();
|
||||
return sendMethodGuide(newChooseOptions);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (JudgeChooseIsValid(chooseOptions,true))
|
||||
{
|
||||
List<Action<SmsContentModel, string, string>> actions = new List<Action<SmsContentModel, string, string>>();
|
||||
foreach (var chooseOption in chooseOptions)
|
||||
{
|
||||
if (chooseOption == "1")
|
||||
{
|
||||
SendByEmail.SetupEmailInfo();
|
||||
actions.Add(SendByEmail.SendSms);
|
||||
}
|
||||
if (chooseOption == "2")
|
||||
{
|
||||
SendByPushPlus.SetupPushPlusInfo();
|
||||
actions.Add(SendByPushPlus.SendSms);
|
||||
}
|
||||
if (chooseOption == "3")
|
||||
{
|
||||
SendByWeComApplication.SetupWeComInfo();
|
||||
actions.Add(SendByWeComApplication.SendSms);
|
||||
}
|
||||
if (chooseOption == "4")
|
||||
{
|
||||
SendByTelegramBot.SetupTGBotInfo();
|
||||
actions.Add(SendByTelegramBot.SendSms);
|
||||
}
|
||||
if (chooseOption == "5")
|
||||
{
|
||||
SendByDingTalkBot.SetupDingtalkBotMsg();
|
||||
actions.Add(SendByDingTalkBot.SendSms);
|
||||
}
|
||||
if (chooseOption == "6")
|
||||
{
|
||||
SendByBark.SetupBarkInfo();
|
||||
actions.Add(SendByBark.SendSms);
|
||||
}
|
||||
if (chooseOption == "7")
|
||||
{
|
||||
SendByShell.SetupCustomShellInfo();
|
||||
actions.Add(SendByShell.SendSms);
|
||||
}
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("请输入1或2或3或4或5或6或7");
|
||||
return sendMethodGuide(new List<string>());
|
||||
}
|
||||
}
|
||||
}
|
||||
return new List<Action<SmsContentModel, string, string>>();
|
||||
}
|
||||
public static bool JudgeChooseIsValid(List<string> chooseOptions,bool isCheckAll=false)
|
||||
{
|
||||
if (isCheckAll)
|
||||
{
|
||||
return chooseOptions.Where(a => a == "1" || a == "2" || a == "3" || a == "4" || a == "5" || a == "6" || a == "7").Count() == chooseOptions.Count();
|
||||
}
|
||||
else
|
||||
{
|
||||
return chooseOptions.Where(a => a == "1" || a == "2" || a == "3" || a == "4" || a == "5" || a == "6" || a == "7").Count() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.Models;
|
||||
using DbusSmsForward.ModemHelper;
|
||||
using DbusSmsForward.Notifications;
|
||||
using DbusSmsForward.Services;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Text.Json;
|
||||
|
||||
AppCommand command = CommandLineParser.Parse(args);
|
||||
|
||||
if (command.PrintSampleConfig)
|
||||
{
|
||||
DbusSmsForwardOptions sample = SampleConfigFactory.Create();
|
||||
Console.WriteLine(JsonSerializer.Serialize(sample, SourceGenerationContext.Default.DbusSmsForwardOptions));
|
||||
return;
|
||||
}
|
||||
|
||||
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
|
||||
builder.Configuration.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false);
|
||||
builder.Services.Configure<DbusSmsForwardOptions>(builder.Configuration);
|
||||
builder.Services.AddSingleton(sp =>
|
||||
{
|
||||
DbusSmsForwardOptions options = new();
|
||||
builder.Configuration.Bind(options);
|
||||
LegacyConfigurationBridge.Apply(builder.Configuration, options);
|
||||
CommandLineConfigurationApplier.Apply(command, options);
|
||||
return options;
|
||||
});
|
||||
builder.Services.AddSingleton<ModemManagerHelper>();
|
||||
builder.Services.AddSingleton<NotificationDispatcher>();
|
||||
builder.Services.AddSingleton<INotificationSender, EmailNotificationSender>();
|
||||
builder.Services.AddSingleton<INotificationSender, PushPlusNotificationSender>();
|
||||
builder.Services.AddSingleton<INotificationSender, BarkNotificationSender>();
|
||||
builder.Services.AddSingleton<INotificationSender, TelegramNotificationSender>();
|
||||
builder.Services.AddSingleton<INotificationSender, DingTalkNotificationSender>();
|
||||
builder.Services.AddSingleton<INotificationSender, WeComApplicationNotificationSender>();
|
||||
builder.Services.AddSingleton<INotificationSender, ShellNotificationSender>();
|
||||
builder.Services.AddSingleton<INotificationSender, AutmanPushNotificationSender>();
|
||||
builder.Services.AddHostedService<SmsForwardWorker>();
|
||||
builder.Logging.ClearProviders();
|
||||
builder.Logging.AddSimpleConsole();
|
||||
|
||||
using IHost host = builder.Build();
|
||||
DbusSmsForwardOptions resolvedOptions = host.Services.GetRequiredService<DbusSmsForwardOptions>();
|
||||
|
||||
if (command.ValidateConfig || resolvedOptions.Daemon.ValidateOnStartup)
|
||||
{
|
||||
ConfigurationValidator.Validate(resolvedOptions, command);
|
||||
}
|
||||
|
||||
if (string.Equals(command.Name, "send", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await SendSmsAsync(host.Services, command);
|
||||
return;
|
||||
}
|
||||
|
||||
await host.RunAsync();
|
||||
|
||||
static async Task SendSmsAsync(IServiceProvider services, AppCommand command)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(command.PhoneNumber) || string.IsNullOrWhiteSpace(command.Message))
|
||||
{
|
||||
throw new InvalidOperationException("send 模式需要 --to 和 --text 参数。 ");
|
||||
}
|
||||
|
||||
ModemManagerHelper modemManagerHelper = services.GetRequiredService<ModemManagerHelper>();
|
||||
bool success = await modemManagerHelper.SendSms(command.PhoneNumber, command.Message);
|
||||
Console.WriteLine(success ? "短信已发送" : "短信发送失败");
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DbusSmsForward.SMSModel
|
||||
{
|
||||
public class SmsCodeModel
|
||||
{
|
||||
public bool HasCode { get; set; }=false;
|
||||
public string CodeFrom { get; set; }=string.Empty;
|
||||
public string CodeValue { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace DbusSmsForward.SMSModel;
|
||||
|
||||
public sealed class SmsContentModel
|
||||
{
|
||||
public string TelNumber { get; set; } = string.Empty;
|
||||
public string SmsContent { get; set; } = string.Empty;
|
||||
public string SmsDate { get; set; } = string.Empty;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.ProcessSmsContent;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace DbusSmsForward.SendMethod
|
||||
{
|
||||
public static class SendByBark
|
||||
{
|
||||
public static void SetupBarkInfo()
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string BarkUrl = result.appSettings.BarkConfig.BarkUrl;
|
||||
string BrakKey = result.appSettings.BarkConfig.BarkKey;
|
||||
|
||||
if (string.IsNullOrEmpty(BarkUrl) && string.IsNullOrEmpty(BrakKey))
|
||||
{
|
||||
Console.WriteLine("首次运行请输入Bark服务器地址:");
|
||||
BarkUrl = Console.ReadLine().Trim();
|
||||
result.appSettings.BarkConfig.BarkUrl = BarkUrl;
|
||||
Console.WriteLine("首次运行请输入Bark推送key");
|
||||
BrakKey = Console.ReadLine().Trim();
|
||||
result.appSettings.BarkConfig.BarkKey = BrakKey;
|
||||
ConfigHelper.UpdateSettings(ref result);
|
||||
}
|
||||
result = null;
|
||||
}
|
||||
|
||||
public static void SendSms(SmsContentModel smsmodel, string body, string devicename)
|
||||
{
|
||||
try
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string BarkUrl = result.appSettings.BarkConfig.BarkUrl;
|
||||
string BrakKey = result.appSettings.BarkConfig.BarkKey;
|
||||
result = null;
|
||||
//string SmsCodeStr = GetSmsContentCode.GetSmsCodeStr(smsmodel.SmsContent);
|
||||
|
||||
SmsCodeModel codeResult = GetSmsContentCode.GetSmsCodeModel(smsmodel.SmsContent);
|
||||
|
||||
string url = BarkUrl + "/" + BrakKey + "/";
|
||||
url += System.Web.HttpUtility.UrlEncode(body);
|
||||
url += "?group=" + smsmodel.TelNumber + "&title="+ (string.IsNullOrEmpty(codeResult.CodeValue) ? "" : codeResult.CodeValue + " ") + "短信转发" + smsmodel.TelNumber+(string.IsNullOrEmpty(codeResult.CodeValue) ?"":"&autoCopy=1©="+ codeResult.CodeValue);
|
||||
string msgresult = HttpHelper.HttpGet(url);
|
||||
//JsonObject jsonObjresult = JObject.Parse(msgresult);
|
||||
var jsonObjresult = JsonSerializer.Deserialize(msgresult, SourceGenerationContext.Default.JsonObject);
|
||||
string status = jsonObjresult["code"].ToString();
|
||||
if (status == "200")
|
||||
{
|
||||
Console.WriteLine("Bark转发成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(jsonObjresult["code"].ToString());
|
||||
Console.WriteLine(jsonObjresult["message"].ToString());
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Console.WriteLine("SendByBarkError:\n"+ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using DbusSmsForward.ProcessSmsContent;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using DbusSmsForward.SettingModel;
|
||||
|
||||
namespace DbusSmsForward.SendMethod
|
||||
{
|
||||
public class SendByDingTalkBot
|
||||
{
|
||||
private const string DING_TALK_BOT_URL = "https://oapi.dingtalk.com/robot/send?access_token=";
|
||||
|
||||
public static void SetupDingtalkBotMsg()
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string DingTalkAccessToken = result.appSettings.DingTalkConfig.DingTalkAccessToken;
|
||||
string DingTalkSecret = result.appSettings.DingTalkConfig.DingTalkSecret;
|
||||
|
||||
if (string.IsNullOrEmpty(DingTalkAccessToken) && string.IsNullOrEmpty(DingTalkSecret))
|
||||
{
|
||||
Console.WriteLine("首次运行请输入钉钉机器人AccessToken:");
|
||||
DingTalkAccessToken = Console.ReadLine().Trim();
|
||||
result.appSettings.DingTalkConfig.DingTalkAccessToken = DingTalkAccessToken;
|
||||
Console.WriteLine("请输入钉钉机器人加签secret:");
|
||||
DingTalkSecret = Console.ReadLine().Trim();
|
||||
result.appSettings.DingTalkConfig.DingTalkSecret = DingTalkSecret;
|
||||
ConfigHelper.UpdateSettings(ref result);
|
||||
}
|
||||
result = null;
|
||||
}
|
||||
|
||||
public static void SendSms(SmsContentModel smsmodel, string body, string devicename)
|
||||
{
|
||||
try
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string dingTalkAccessToken = result.appSettings.DingTalkConfig.DingTalkAccessToken;
|
||||
string dingTalkSecret = result.appSettings.DingTalkConfig.DingTalkSecret;
|
||||
result = null;
|
||||
string url = DING_TALK_BOT_URL + dingTalkAccessToken;
|
||||
//string SmsCodeStr = GetSmsContentCode.GetSmsCodeStr(smsmodel.SmsContent);
|
||||
SmsCodeModel codeResult = GetSmsContentCode.GetSmsCodeModel(smsmodel.SmsContent);
|
||||
|
||||
long timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
||||
string sign = addSign(timestamp, dingTalkSecret);
|
||||
url += $"×tamp={timestamp}&sign={sign}";
|
||||
|
||||
JsonObject msgContent = new()
|
||||
{
|
||||
{ "content", (string.IsNullOrEmpty(codeResult.CodeValue) ? "" : codeResult.CodeValue + "\n") + "短信转发\n" + body }
|
||||
};
|
||||
|
||||
JsonObject msgObj = new()
|
||||
{
|
||||
{ "msgtype", "text" },
|
||||
{ "text", msgContent }
|
||||
};
|
||||
|
||||
string resultResp = HttpHelper.Post(url, msgObj);
|
||||
//JObject jsonObjresult = JObject.Parse(resultResp);
|
||||
JsonObject jsonObjresult = JsonSerializer.Deserialize(resultResp, SourceGenerationContext.Default.JsonObject);
|
||||
string errcode1 = jsonObjresult["errcode"].ToString();
|
||||
string errmsg1 = jsonObjresult["errmsg"].ToString();
|
||||
if (errcode1 == "0" && errmsg1 == "ok")
|
||||
{
|
||||
Console.WriteLine("钉钉转发成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(errmsg1);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("SendByDingTalkBotError:\n" + ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static string addSign(long timestamp ,string secret)
|
||||
{
|
||||
string secret1 = secret;
|
||||
string stringToSign = timestamp + "\n" + secret1;
|
||||
var encoding = new ASCIIEncoding();
|
||||
byte[] keyByte = encoding.GetBytes(secret1);
|
||||
byte[] messageBytes = encoding.GetBytes(stringToSign);
|
||||
using (var hmacsha256 = new HMACSHA256(keyByte))
|
||||
{
|
||||
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
|
||||
return HttpUtility.UrlEncode(Convert.ToBase64String(hashmessage), Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
|
||||
public static string Base64Encrypt(string input, Encoding encode)
|
||||
{
|
||||
return Convert.ToBase64String(encode.GetBytes(input));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using DbusSmsForward.SMSModel;
|
||||
using DbusSmsForward.ProcessSmsContent;
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using MimeKit;
|
||||
using MailKit.Net.Smtp;
|
||||
|
||||
namespace DbusSmsForward.SendMethod
|
||||
{
|
||||
public static class SendByEmail
|
||||
{
|
||||
public static void SetupEmailInfo()
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string smtpHost = result.appSettings.EmailConfig.smtpHost;
|
||||
string smtpPort = result.appSettings.EmailConfig.smtpPort;
|
||||
string emailKey = result.appSettings.EmailConfig.emailKey;
|
||||
string sendEmail = result.appSettings.EmailConfig.sendEmail;
|
||||
string reciveEmail = result.appSettings.EmailConfig.reciveEmail;
|
||||
if (string.IsNullOrEmpty(smtpHost) && string.IsNullOrEmpty(smtpPort) && string.IsNullOrEmpty(emailKey) && string.IsNullOrEmpty(sendEmail) && string.IsNullOrEmpty(reciveEmail))
|
||||
{
|
||||
Console.WriteLine("首次运行请输入邮箱转发相关配置信息\n请输入smtp地址:");
|
||||
smtpHost = Console.ReadLine().Trim();
|
||||
result.appSettings.EmailConfig.smtpHost = smtpHost;
|
||||
|
||||
Console.WriteLine("请输入smtp端口:");
|
||||
smtpPort = Console.ReadLine().Trim();
|
||||
result.appSettings.EmailConfig.smtpPort = smtpPort;
|
||||
string sslEnableInput = string.Empty;
|
||||
do
|
||||
{
|
||||
Console.WriteLine("是否需要启用ssl(1.启用 2.不启用)");
|
||||
sslEnableInput = Console.ReadLine().Trim();
|
||||
} while (!(sslEnableInput == "1" || sslEnableInput == "2"));
|
||||
if (sslEnableInput == "1")
|
||||
{
|
||||
result.appSettings.EmailConfig.enableSSL = "true";
|
||||
}
|
||||
else
|
||||
{
|
||||
result.appSettings.EmailConfig.enableSSL = "false";
|
||||
}
|
||||
Console.WriteLine("请输入邮箱密钥:");
|
||||
emailKey = Console.ReadLine().Trim();
|
||||
result.appSettings.EmailConfig.emailKey = emailKey;
|
||||
|
||||
Console.WriteLine("请输入发件邮箱:");
|
||||
sendEmail = Console.ReadLine().Trim();
|
||||
result.appSettings.EmailConfig.sendEmail = sendEmail;
|
||||
|
||||
Console.WriteLine("请输入收件邮箱:");
|
||||
reciveEmail = Console.ReadLine().Trim();
|
||||
result.appSettings.EmailConfig.reciveEmail = reciveEmail;
|
||||
|
||||
ConfigHelper.UpdateSettings(ref result);
|
||||
}
|
||||
result = null;
|
||||
}
|
||||
|
||||
public static void SendSms(SmsContentModel smsmodel, string body, string devicename)
|
||||
{
|
||||
try
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string smtpHost = result.appSettings.EmailConfig.smtpHost;
|
||||
string smtpPort = result.appSettings.EmailConfig.smtpPort;
|
||||
bool enableSSL = Convert.ToBoolean(result.appSettings.EmailConfig.enableSSL);
|
||||
string emailKey = result.appSettings.EmailConfig.emailKey;
|
||||
string sendEmail = result.appSettings.EmailConfig.sendEmail;
|
||||
string reciveEmail = result.appSettings.EmailConfig.reciveEmail;
|
||||
result = null;
|
||||
var message = new MimeMessage();
|
||||
message.From.Add(new MailboxAddress("SMSForwad", sendEmail));
|
||||
message.To.Add(new MailboxAddress("", reciveEmail));
|
||||
//string SmsCodeStr = GetSmsContentCode.GetSmsCodeStr(smsmodel.SmsContent);
|
||||
SmsCodeModel codeResult = GetSmsContentCode.GetSmsCodeModel(smsmodel.SmsContent);
|
||||
|
||||
message.Subject = (string.IsNullOrEmpty(codeResult.CodeValue) ? "" : codeResult.CodeValue + " ") + "短信转发" + smsmodel.TelNumber;
|
||||
message.Body = new TextPart("plain")
|
||||
{
|
||||
Text = body
|
||||
};
|
||||
using (var client = new SmtpClient())
|
||||
{
|
||||
client.Connect(smtpHost, Convert.ToInt32(smtpPort), enableSSL);
|
||||
client.Authenticate(sendEmail, emailKey);
|
||||
client.Send(message);
|
||||
client.Disconnect(true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("SendByEmailError:\n" + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.ProcessSmsContent;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace DbusSmsForward.SendMethod
|
||||
{
|
||||
public static class SendByPushPlus
|
||||
{
|
||||
public static void SetupPushPlusInfo()
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string pushPlusToken = result.appSettings.PushPlusConfig.pushPlusToken;
|
||||
if (string.IsNullOrEmpty(pushPlusToken))
|
||||
{
|
||||
Console.WriteLine("首次运行请输入PushPlusToken:");
|
||||
pushPlusToken = Console.ReadLine().Trim();
|
||||
result.appSettings.PushPlusConfig.pushPlusToken = pushPlusToken;
|
||||
ConfigHelper.UpdateSettings(ref result);
|
||||
}
|
||||
result = null;
|
||||
|
||||
}
|
||||
|
||||
public static void SendSms(SmsContentModel smsmodel, string body, string devicename)
|
||||
{
|
||||
try
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string pushPlusToken = result.appSettings.PushPlusConfig.pushPlusToken;
|
||||
result = null;
|
||||
string pushPlusUrl = "http://www.pushplus.plus/send/";
|
||||
//string SmsCodeStr = GetSmsContentCode.GetSmsCodeStr(smsmodel.SmsContent);
|
||||
SmsCodeModel codeResult = GetSmsContentCode.GetSmsCodeModel(smsmodel.SmsContent);
|
||||
|
||||
JsonObject obj = new JsonObject();
|
||||
obj.Add("token", pushPlusToken);
|
||||
obj.Add("title", (string.IsNullOrEmpty(codeResult.CodeValue) ? "" : codeResult.CodeValue + " ") + "短信转发" + smsmodel.TelNumber);
|
||||
obj.Add("content", body);
|
||||
obj.Add("topic", "");
|
||||
string msgresult = HttpHelper.Post(pushPlusUrl, obj);
|
||||
//JObject jsonObjresult = JObject.Parse(msgresult);
|
||||
JsonObject jsonObjresult = JsonSerializer.Deserialize(msgresult, SourceGenerationContext.Default.JsonObject);
|
||||
string code = jsonObjresult["code"].ToString();
|
||||
string errmsg = jsonObjresult["msg"].ToString();
|
||||
if (code == "200")
|
||||
{
|
||||
Console.WriteLine("pushplus转发成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(errmsg);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("SetupPushPlusInfoError:\n" + ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.ProcessSmsContent;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Xml;
|
||||
|
||||
namespace DbusSmsForward.SendMethod
|
||||
{
|
||||
public static class SendByShell
|
||||
{
|
||||
public static void SetupCustomShellInfo()
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string shellPath = result.appSettings.ShellConfig.ShellPath;
|
||||
if (string.IsNullOrEmpty(shellPath))
|
||||
{
|
||||
Console.WriteLine("首次运行请输入自定义shell脚本路径:");
|
||||
shellPath = Console.ReadLine().Trim();
|
||||
result.appSettings.ShellConfig.ShellPath = shellPath;
|
||||
ConfigHelper.UpdateSettings(ref result);
|
||||
}
|
||||
result = null;
|
||||
}
|
||||
|
||||
public static void SendSms(SmsContentModel smsmodel, string body, string devicename)
|
||||
{
|
||||
try
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string shellPath = result.appSettings.ShellConfig.ShellPath;
|
||||
result = null;
|
||||
|
||||
SmsCodeModel codeResult = GetSmsContentCode.GetSmsCodeModel(smsmodel.SmsContent);
|
||||
string[] arguments =
|
||||
{
|
||||
string.IsNullOrEmpty(smsmodel.TelNumber)?"":smsmodel.TelNumber,
|
||||
string.IsNullOrEmpty(smsmodel.SmsDate)?"":smsmodel.SmsDate,
|
||||
string.IsNullOrEmpty(smsmodel.SmsContent)?"":smsmodel.SmsContent,
|
||||
string.IsNullOrEmpty(codeResult.CodeValue)?"":codeResult.CodeValue,
|
||||
string.IsNullOrEmpty(codeResult.CodeFrom)?"":codeResult.CodeFrom,
|
||||
string.IsNullOrEmpty(devicename)?"":devicename,
|
||||
};
|
||||
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = shellPath,
|
||||
UseShellExecute = false, // 不直接使用操作系统shell启动
|
||||
CreateNoWindow = true, // 不创建新窗口
|
||||
RedirectStandardOutput = true, // 可以重定向输出
|
||||
RedirectStandardError = true // 可以重定向错误
|
||||
};
|
||||
foreach (var arg in arguments)
|
||||
{
|
||||
startInfo.ArgumentList.Add(arg);
|
||||
}
|
||||
|
||||
// 启动进程
|
||||
using (Process process = new Process())
|
||||
{
|
||||
process.StartInfo = startInfo;
|
||||
|
||||
// 可以捕获输出(如果需要)
|
||||
process.OutputDataReceived += (sender, e) =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
Console.WriteLine($"输出: {e.Data}");
|
||||
};
|
||||
|
||||
process.ErrorDataReceived += (sender, e) =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
Console.WriteLine($"错误: {e.Data}");
|
||||
};
|
||||
|
||||
bool started = process.Start();
|
||||
|
||||
if (started)
|
||||
{
|
||||
// 开始异步读取输出
|
||||
process.BeginOutputReadLine();
|
||||
process.BeginErrorReadLine();
|
||||
|
||||
// 等待进程完成(可以设置超时时间)
|
||||
bool exited = process.WaitForExit(30000); // 30秒超时
|
||||
|
||||
if (exited)
|
||||
{
|
||||
int exitCode = process.ExitCode;
|
||||
|
||||
if (exitCode == 0)
|
||||
{
|
||||
Console.WriteLine("\nShell调用成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"\nShell调用失败,退出代码: {exitCode}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\nShell调用超时");
|
||||
process.Kill(); // 强制终止进程
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\n无法启动Shell进程");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("SendByShellError:\n" + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.ProcessSmsContent;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace DbusSmsForward.SendMethod
|
||||
{
|
||||
public static class SendByTelegramBot
|
||||
{
|
||||
public static void SetupTGBotInfo()
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string TGBotToken = result.appSettings.TGBotConfig.TGBotToken;
|
||||
string TGBotChatID = result.appSettings.TGBotConfig.TGBotChatID;
|
||||
string IsEnableCustomTGBotApi = result.appSettings.TGBotConfig.IsEnableCustomTGBotApi;
|
||||
string CustomTGBotApi = result.appSettings.TGBotConfig.CustomTGBotApi;
|
||||
|
||||
if (string.IsNullOrEmpty(TGBotToken) || string.IsNullOrEmpty(TGBotChatID) || string.IsNullOrEmpty(IsEnableCustomTGBotApi))
|
||||
{
|
||||
Console.WriteLine("首次运行请输入TG机器人Token:");
|
||||
TGBotToken = Console.ReadLine().Trim();
|
||||
result.appSettings.TGBotConfig.TGBotToken = TGBotToken;
|
||||
Console.WriteLine("请输入机器人要转发到的ChatId");
|
||||
TGBotChatID = Console.ReadLine().Trim();
|
||||
result.appSettings.TGBotConfig.TGBotChatID = TGBotChatID;
|
||||
|
||||
string customApiEnableInput=string.Empty;
|
||||
do
|
||||
{
|
||||
Console.WriteLine("是否需要使用自定义api(1.使用 2.不使用)");
|
||||
customApiEnableInput= Console.ReadLine().Trim();
|
||||
} while (!(customApiEnableInput=="1"|| customApiEnableInput == "2"));
|
||||
if(customApiEnableInput=="1")
|
||||
{
|
||||
IsEnableCustomTGBotApi = "true";
|
||||
result.appSettings.TGBotConfig.IsEnableCustomTGBotApi = IsEnableCustomTGBotApi;
|
||||
Console.WriteLine("请输入机器人自定义api(格式https://xxx.abc.com)");
|
||||
CustomTGBotApi= Console.ReadLine().Trim();
|
||||
result.appSettings.TGBotConfig.CustomTGBotApi = CustomTGBotApi;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsEnableCustomTGBotApi = "false";
|
||||
result.appSettings.TGBotConfig.IsEnableCustomTGBotApi = IsEnableCustomTGBotApi;
|
||||
}
|
||||
ConfigHelper.UpdateSettings(ref result);
|
||||
}
|
||||
result = null;
|
||||
|
||||
}
|
||||
|
||||
public static void SendSms(SmsContentModel smsmodel, string body, string devicename)
|
||||
{
|
||||
try
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string TGBotToken = result.appSettings.TGBotConfig.TGBotToken;
|
||||
string TGBotChatID = result.appSettings.TGBotConfig.TGBotChatID;
|
||||
string IsEnableCustomTGBotApi = result.appSettings.TGBotConfig.IsEnableCustomTGBotApi;
|
||||
string CustomTGBotApi = result.appSettings.TGBotConfig.CustomTGBotApi;
|
||||
result = null;
|
||||
//string SmsCodeStr = GetSmsContentCode.GetSmsCodeStr(smsmodel.SmsContent);
|
||||
SmsCodeModel codeResult = GetSmsContentCode.GetSmsCodeModel(smsmodel.SmsContent);
|
||||
string url = "";
|
||||
if (IsEnableCustomTGBotApi == "true")
|
||||
{
|
||||
url = CustomTGBotApi;
|
||||
}
|
||||
else
|
||||
{
|
||||
url = "https://api.telegram.org";
|
||||
}
|
||||
url += "/bot" + TGBotToken + "/sendMessage?chat_id=" + TGBotChatID + "&text=";
|
||||
url += System.Web.HttpUtility.UrlEncode((string.IsNullOrEmpty(codeResult.CodeValue) ? "" : codeResult.CodeValue + "\n") + "短信转发\n" + body);
|
||||
string msgresult = HttpHelper.HttpGet(url);
|
||||
JsonObject jsonObjresult = JsonSerializer.Deserialize(msgresult, SourceGenerationContext.Default.JsonObject);
|
||||
string status = jsonObjresult["ok"].ToString();
|
||||
if (status.ToLower() == "true")
|
||||
{
|
||||
Console.WriteLine("TGBot转发成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(jsonObjresult["error_code"].ToString());
|
||||
Console.WriteLine(jsonObjresult["description"].ToString());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("SendByTelegramBotError:\n" + ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.ProcessSmsContent;
|
||||
using DbusSmsForward.SettingModel;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace DbusSmsForward.SendMethod
|
||||
{
|
||||
public class SendByWeComApplication
|
||||
{
|
||||
public static void SetupWeComInfo()
|
||||
{
|
||||
appsettingsModel result = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref result);
|
||||
string corpid = result.appSettings.WeComApplicationConfig.WeChatQYID;
|
||||
string appsecret = result.appSettings.WeComApplicationConfig.WeChatQYApplicationSecret;
|
||||
string appid = result.appSettings.WeComApplicationConfig.WeChatQYApplicationID;
|
||||
|
||||
if (string.IsNullOrEmpty(corpid) && string.IsNullOrEmpty(appsecret) && string.IsNullOrEmpty(appid))
|
||||
{
|
||||
Console.WriteLine("首次运行请输入企业ID:");
|
||||
corpid = Console.ReadLine().Trim();
|
||||
result.appSettings.WeComApplicationConfig.WeChatQYID = corpid;
|
||||
|
||||
Console.WriteLine("请输入自建应用ID:");
|
||||
appid = Console.ReadLine().Trim();
|
||||
result.appSettings.WeComApplicationConfig.WeChatQYApplicationID = appid;
|
||||
|
||||
Console.WriteLine("请输入自建应用密钥:");
|
||||
appsecret = Console.ReadLine().Trim();
|
||||
result.appSettings.WeComApplicationConfig.WeChatQYApplicationSecret = appsecret;
|
||||
|
||||
ConfigHelper.UpdateSettings(ref result);
|
||||
}
|
||||
result = null;
|
||||
|
||||
}
|
||||
|
||||
public static void SendSms(SmsContentModel smsmodel, string body, string devicename)
|
||||
{
|
||||
try
|
||||
{
|
||||
appsettingsModel configResult = new appsettingsModel();
|
||||
ConfigHelper.GetSettings(ref configResult);
|
||||
string corpid = configResult.appSettings.WeComApplicationConfig.WeChatQYID;
|
||||
string corpsecret = configResult.appSettings.WeComApplicationConfig.WeChatQYApplicationSecret;
|
||||
string agentid = configResult.appSettings.WeComApplicationConfig.WeChatQYApplicationID;
|
||||
configResult = null;
|
||||
|
||||
string url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpid + "&corpsecret=" + corpsecret;
|
||||
string result = HttpHelper.HttpGet(url);
|
||||
//JsonObject jsonObj = JsonObject.Parse(result);
|
||||
JsonObject jsonObj = JsonSerializer.Deserialize(result, SourceGenerationContext.Default.JsonObject);
|
||||
string errcode = jsonObj["errcode"].ToString();
|
||||
string errmsg = jsonObj["errmsg"].ToString();
|
||||
//string SmsCodeStr = GetSmsContentCode.GetSmsCodeStr(smsmodel.SmsContent);
|
||||
SmsCodeModel codeResult = GetSmsContentCode.GetSmsCodeModel(smsmodel.SmsContent);
|
||||
|
||||
if (errcode == "0" && errmsg == "ok")
|
||||
{
|
||||
string access_token = jsonObj["access_token"].ToString();
|
||||
JsonObject obj = new JsonObject();
|
||||
JsonObject obj1 = new JsonObject();
|
||||
obj.Add("touser", "@all");
|
||||
obj.Add("toparty", "");
|
||||
obj.Add("totag", "");
|
||||
obj.Add("msgtype", "text");
|
||||
obj.Add("agentid", agentid);
|
||||
obj1.Add("content", (string.IsNullOrEmpty(codeResult.CodeValue) ? "" : codeResult.CodeValue + "\n") + "短信转发\n" + body);
|
||||
obj.Add("text", obj1);
|
||||
obj.Add("safe", 0);
|
||||
obj.Add("enable_id_trans", 0);
|
||||
obj.Add("enable_duplicate_check", 0);
|
||||
obj.Add("duplicate_check_interval", 1800);
|
||||
string msgurl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + access_token;
|
||||
string msgresult = HttpHelper.Post(msgurl, obj);
|
||||
//JsonObject jsonObjresult = JsonObject.Parse(msgresult);
|
||||
//JsonObject jsonObjresult = JsonSerializer.Deserialize<JsonObject>(msgresult);
|
||||
JsonObject jsonObjresult = JsonSerializer.Deserialize(msgresult, SourceGenerationContext.Default.JsonObject);
|
||||
string errcode1 = jsonObjresult["errcode"].ToString();
|
||||
string errmsg1 = jsonObjresult["errmsg"].ToString();
|
||||
if (errcode1 == "0" && errmsg1 == "ok")
|
||||
{
|
||||
Console.WriteLine("企业微信转发成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(errmsg1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(errmsg);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("SendByWeComApplicationError:\n" + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using DbusSmsForward.Helper;
|
||||
using DbusSmsForward.Models;
|
||||
|
||||
namespace DbusSmsForward.Services;
|
||||
|
||||
public static class CommandLineParser
|
||||
{
|
||||
public static AppCommand Parse(string[] args)
|
||||
{
|
||||
if (args.Length == 0)
|
||||
{
|
||||
return new AppCommand { Name = "run" };
|
||||
}
|
||||
|
||||
List<string> enabledChannels = [];
|
||||
string commandName = "run";
|
||||
string phoneNumber = string.Empty;
|
||||
string message = string.Empty;
|
||||
bool validateConfig = false;
|
||||
bool printSampleConfig = false;
|
||||
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
string arg = args[i];
|
||||
switch (arg)
|
||||
{
|
||||
case "run":
|
||||
case "send":
|
||||
case "validate-config":
|
||||
case "print-sample-config":
|
||||
commandName = arg;
|
||||
break;
|
||||
case "--to":
|
||||
if (i + 1 < args.Length) phoneNumber = args[++i];
|
||||
break;
|
||||
case "--text":
|
||||
if (i + 1 < args.Length) message = args[++i];
|
||||
break;
|
||||
case "-fE":
|
||||
commandName = "run";
|
||||
enabledChannels.Add("email");
|
||||
break;
|
||||
case "-fP":
|
||||
commandName = "run";
|
||||
enabledChannels.Add("pushplus");
|
||||
break;
|
||||
case "-fW":
|
||||
commandName = "run";
|
||||
enabledChannels.Add("wecom");
|
||||
break;
|
||||
case "-fT":
|
||||
commandName = "run";
|
||||
enabledChannels.Add("telegram");
|
||||
break;
|
||||
case "-fD":
|
||||
commandName = "run";
|
||||
enabledChannels.Add("dingtalk");
|
||||
break;
|
||||
case "-fB":
|
||||
commandName = "run";
|
||||
enabledChannels.Add("bark");
|
||||
break;
|
||||
case "-fS":
|
||||
commandName = "run";
|
||||
enabledChannels.Add("shell");
|
||||
break;
|
||||
case "-fA":
|
||||
commandName = "run";
|
||||
enabledChannels.Add("autmanpush");
|
||||
break;
|
||||
case "-sS":
|
||||
commandName = "send";
|
||||
break;
|
||||
case "--validate-config":
|
||||
validateConfig = true;
|
||||
break;
|
||||
case "--print-sample-config":
|
||||
printSampleConfig = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new AppCommand
|
||||
{
|
||||
Name = commandName,
|
||||
PhoneNumber = phoneNumber,
|
||||
Message = message,
|
||||
EnabledChannels = enabledChannels.Distinct(StringComparer.OrdinalIgnoreCase).ToArray(),
|
||||
ValidateConfig = validateConfig || commandName == "validate-config",
|
||||
PrintSampleConfig = printSampleConfig || commandName == "print-sample-config"
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using DbusSmsForward.ProcessSmsContent;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using DbusSmsForward.SettingModel;
|
||||
|
||||
namespace DbusSmsForward.Services;
|
||||
|
||||
public static class NotificationContentBuilder
|
||||
{
|
||||
public static string BuildBody(SmsContentModel sms, string deviceName)
|
||||
=> $"发信电话:{sms.TelNumber}\n时间:{sms.SmsDate}\n转发设备:{deviceName}\n短信内容:{sms.SmsContent}";
|
||||
|
||||
public static SmsCodeModel ExtractCode(DbusSmsForwardOptions options, SmsContentModel sms)
|
||||
{
|
||||
if (!options.Forwarding.EnableSmsCodeExtraction)
|
||||
{
|
||||
return new SmsCodeModel();
|
||||
}
|
||||
|
||||
return GetSmsContentCode.GetSmsCodeModel(sms.SmsContent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using DbusSmsForward.Notifications;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DbusSmsForward.Services;
|
||||
|
||||
public sealed class NotificationDispatcher(IEnumerable<INotificationSender> senders, ILogger<NotificationDispatcher> logger)
|
||||
{
|
||||
private readonly IReadOnlyList<INotificationSender> _senders = senders.Where(static s => s.IsEnabled).ToList();
|
||||
|
||||
public async Task DispatchAsync(SmsContentModel sms, string body, string deviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
foreach (INotificationSender sender in _senders)
|
||||
{
|
||||
try
|
||||
{
|
||||
await sender.SendAsync(sms, body, deviceName, cancellationToken);
|
||||
logger.LogInformation("Notification sender {Sender} completed for {PhoneNumber}", sender.Name, sms.TelNumber);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Notification sender {Sender} failed for {PhoneNumber}", sender.Name, sms.TelNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using DbusSmsForward.ModemHelper;
|
||||
using DbusSmsForward.SMSModel;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DbusSmsForward.Services;
|
||||
|
||||
public sealed class SmsForwardWorker(ModemManagerHelper modemManagerHelper, NotificationDispatcher dispatcher, ILogger<SmsForwardWorker> logger) : BackgroundService
|
||||
{
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
logger.LogInformation("SmsForwardWorker started.");
|
||||
modemManagerHelper.SetSendMethodList(
|
||||
[
|
||||
(SmsContentModel sms, string body, string deviceName) =>
|
||||
{
|
||||
dispatcher.DispatchAsync(sms, body, deviceName, stoppingToken).GetAwaiter().GetResult();
|
||||
}
|
||||
]);
|
||||
|
||||
await Task.Delay(Timeout.Infinite, stoppingToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using DbusSmsForward.SettingModel;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace DbusSmsForward;
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true, PropertyNameCaseInsensitive = true)]
|
||||
[JsonSerializable(typeof(JsonObject))]
|
||||
[JsonSerializable(typeof(DbusSmsForwardOptions))]
|
||||
[JsonSerializable(typeof(LegacyAppsettingsModel))]
|
||||
[JsonSerializable(typeof(appsettingsModel))]
|
||||
internal partial class SourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"appSettings": {
|
||||
"EmailConfig": {
|
||||
"smtpHost": "",
|
||||
"smtpPort": "",
|
||||
"enableSSL": "",
|
||||
"emailKey": "",
|
||||
"sendEmail": "",
|
||||
"reciveEmail": ""
|
||||
},
|
||||
"PushPlusConfig": {
|
||||
"pushPlusToken": ""
|
||||
},
|
||||
"DingTalkConfig": {
|
||||
"DingTalkAccessToken": "",
|
||||
"DingTalkSecret": ""
|
||||
},
|
||||
"BarkConfig": {
|
||||
"BarkUrl": "",
|
||||
"BarkKey": ""
|
||||
},
|
||||
"WeComApplicationConfig": {
|
||||
"WeChatQYID": "",
|
||||
"WeChatQYApplicationID": "",
|
||||
"WeChatQYApplicationSecret": ""
|
||||
},
|
||||
"TGBotConfig": {
|
||||
"IsEnableCustomTGBotApi": "",
|
||||
"CustomTGBotApi": "",
|
||||
"TGBotToken": "",
|
||||
"TGBotChatID": ""
|
||||
},
|
||||
"ShellConfig": {
|
||||
"ShellPath": ""
|
||||
},
|
||||
"SmsCodeKey": "验证码±verification±code±인증±代码±随机码",
|
||||
"ForwardIgnoreStorageType": "sm",
|
||||
"DeviceName": ""
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
using Tmds.DBus.Protocol;
|
||||
|
||||
namespace DbusSmsForward.SettingModel;
|
||||
|
||||
public sealed class appsettingsModel
|
||||
{
|
||||
public LegacyAppSettings appSettings { get; set; } = new();
|
||||
}
|
||||
|
||||
public sealed class LegacyAppsettingsModel
|
||||
{
|
||||
public LegacyAppSettings appSettings { get; set; } = new();
|
||||
}
|
||||
|
||||
public sealed class LegacyAppSettings
|
||||
{
|
||||
public EmailConfig EmailConfig { get; set; } = new();
|
||||
public PushPlusConfig PushPlusConfig { get; set; } = new();
|
||||
public DingTalkConfig DingTalkConfig { get; set; } = new();
|
||||
public BarkConfig BarkConfig { get; set; } = new();
|
||||
public WeComApplicationConfig WeComApplicationConfig { get; set; } = new();
|
||||
public TelegramBotConfig TGBotConfig { get; set; } = new();
|
||||
public ShellConfig ShellConfig { get; set; } = new();
|
||||
public string SmsCodeKey { get; set; } = "验证码±verification±code±认证±代码±随机码";
|
||||
public string ForwardIgnoreStorageType { get; set; } = "sm";
|
||||
public string DeviceName { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public sealed class DbusSmsForwardOptions
|
||||
{
|
||||
public DaemonConfig Daemon { get; set; } = new();
|
||||
public ModemConfig Modem { get; set; } = new();
|
||||
public ForwardingConfig Forwarding { get; set; } = new();
|
||||
public NotificationChannels Notifications { get; set; } = new();
|
||||
public LegacyCompatibilityConfig LegacyCompatibility { get; set; } = new();
|
||||
}
|
||||
|
||||
public sealed class DaemonConfig
|
||||
{
|
||||
public string Mode { get; set; } = "forward";
|
||||
public bool ValidateOnStartup { get; set; } = true;
|
||||
public bool UseSystemd { get; set; } = true;
|
||||
public string LogLevel { get; set; } = "Information";
|
||||
}
|
||||
|
||||
public sealed class ModemConfig
|
||||
{
|
||||
public string SystemBusAddress { get; set; } = Address.System ?? string.Empty;
|
||||
public string ServiceName { get; set; } = "org.freedesktop.ModemManager1";
|
||||
public string ManagerObjectPath { get; set; } = "/org/freedesktop/ModemManager1";
|
||||
public bool ScanDevicesOnStartup { get; set; } = true;
|
||||
}
|
||||
|
||||
public sealed class ForwardingConfig
|
||||
{
|
||||
public string DeviceName { get; set; } = string.Empty;
|
||||
public string SmsCodeKey { get; set; } = "验证码±verification±code±认证±代码±随机码";
|
||||
public string IgnoreStorageType { get; set; } = "sm";
|
||||
public bool EnableSmsCodeExtraction { get; set; } = true;
|
||||
public string[] EnabledChannels { get; set; } = [];
|
||||
}
|
||||
|
||||
public sealed class NotificationChannels
|
||||
{
|
||||
public EmailConfig Email { get; set; } = new();
|
||||
public PushPlusConfig PushPlus { get; set; } = new();
|
||||
public DingTalkConfig DingTalk { get; set; } = new();
|
||||
public BarkConfig Bark { get; set; } = new();
|
||||
public WeComApplicationConfig WeComApplication { get; set; } = new();
|
||||
public TelegramBotConfig TelegramBot { get; set; } = new();
|
||||
public ShellConfig Shell { get; set; } = new();
|
||||
public AutmanPushConfig AutmanPush { get; set; } = new();
|
||||
}
|
||||
|
||||
public sealed class LegacyCompatibilityConfig
|
||||
{
|
||||
public bool EnableLegacyCliFlags { get; set; } = true;
|
||||
public bool WriteLegacyAppSettings { get; set; } = false;
|
||||
}
|
||||
|
||||
public class ChannelConfigBase
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
public int TimeoutSeconds { get; set; } = 15;
|
||||
public bool SkipTlsValidation { get; set; }
|
||||
}
|
||||
|
||||
public sealed class EmailConfig : ChannelConfigBase
|
||||
{
|
||||
public string SmtpHost { get; set; } = string.Empty;
|
||||
public int SmtpPort { get; set; } = 465;
|
||||
public bool EnableSsl { get; set; } = true;
|
||||
public string EmailKey { get; set; } = string.Empty;
|
||||
public string SendEmail { get; set; } = string.Empty;
|
||||
public string ReceiveEmail { get; set; } = string.Empty;
|
||||
|
||||
public string smtpHost { get => SmtpHost; set => SmtpHost = value; }
|
||||
public string smtpPort { get => SmtpPort.ToString(); set => SmtpPort = int.TryParse(value, out int parsed) ? parsed : 465; }
|
||||
public string enableSSL { get => EnableSsl.ToString().ToLowerInvariant(); set => EnableSsl = bool.TryParse(value, out bool parsed) && parsed; }
|
||||
public string emailKey { get => EmailKey; set => EmailKey = value; }
|
||||
public string sendEmail { get => SendEmail; set => SendEmail = value; }
|
||||
public string reciveEmail { get => ReceiveEmail; set => ReceiveEmail = value; }
|
||||
}
|
||||
|
||||
public sealed class PushPlusConfig : ChannelConfigBase
|
||||
{
|
||||
public string Token { get; set; } = string.Empty;
|
||||
public string Endpoint { get; set; } = "https://www.pushplus.plus/send";
|
||||
|
||||
public string pushPlusToken { get => Token; set => Token = value; }
|
||||
}
|
||||
|
||||
public sealed class DingTalkConfig : ChannelConfigBase
|
||||
{
|
||||
public string AccessToken { get; set; } = string.Empty;
|
||||
public string Secret { get; set; } = string.Empty;
|
||||
public string Endpoint { get; set; } = "https://oapi.dingtalk.com/robot/send";
|
||||
|
||||
public string DingTalkAccessToken { get => AccessToken; set => AccessToken = value; }
|
||||
public string DingTalkSecret { get => Secret; set => Secret = value; }
|
||||
}
|
||||
|
||||
public sealed class BarkConfig : ChannelConfigBase
|
||||
{
|
||||
public string ServerUrl { get; set; } = string.Empty;
|
||||
public string BarkKey { get; set; } = string.Empty;
|
||||
|
||||
public string BarkUrl { get => ServerUrl; set => ServerUrl = value; }
|
||||
}
|
||||
|
||||
public sealed class WeComApplicationConfig : ChannelConfigBase
|
||||
{
|
||||
public string CorpId { get; set; } = string.Empty;
|
||||
public string AgentId { get; set; } = string.Empty;
|
||||
public string ApplicationSecret { get; set; } = string.Empty;
|
||||
|
||||
public string WeChatQYID { get => CorpId; set => CorpId = value; }
|
||||
public string WeChatQYApplicationID { get => AgentId; set => AgentId = value; }
|
||||
public string WeChatQYApplicationSecret { get => ApplicationSecret; set => ApplicationSecret = value; }
|
||||
}
|
||||
|
||||
public sealed class TelegramBotConfig : ChannelConfigBase
|
||||
{
|
||||
public bool EnableCustomApi { get; set; }
|
||||
public string CustomApi { get; set; } = string.Empty;
|
||||
public string BotToken { get; set; } = string.Empty;
|
||||
public string ChatId { get; set; } = string.Empty;
|
||||
|
||||
public string IsEnableCustomTGBotApi { get => EnableCustomApi.ToString().ToLowerInvariant(); set => EnableCustomApi = bool.TryParse(value, out bool parsed) && parsed; }
|
||||
public string CustomTGBotApi { get => CustomApi; set => CustomApi = value; }
|
||||
public string TGBotToken { get => BotToken; set => BotToken = value; }
|
||||
public string TGBotChatID { get => ChatId; set => ChatId = value; }
|
||||
}
|
||||
|
||||
public sealed class ShellConfig : ChannelConfigBase
|
||||
{
|
||||
public string ShellPath { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public sealed class AutmanPushConfig : ChannelConfigBase
|
||||
{
|
||||
public string ApiUrl { get; set; } = string.Empty;
|
||||
public string AccessToken { get; set; } = string.Empty;
|
||||
public string Method { get; set; } = "POST";
|
||||
}
|
||||
Reference in New Issue
Block a user