Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions BetterGenshinImpact/Service/Notification/NotificationConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -276,4 +276,14 @@ public partial class NotificationConfig : ObservableObject
/// Discord Webhook 图像编码
/// </summary>
[ObservableProperty] private string _discordWebhookImageEncoder = "Jpeg";

/// <summary>
/// ServerChan通知是否启用
/// </summary>
[ObservableProperty] private bool _serverChanNotificationEnabled;

/// <summary>
/// ServerChan SendKey
/// </summary>
[ObservableProperty] private string _serverChanSendKey = string.Empty;
}
14 changes: 14 additions & 0 deletions BetterGenshinImpact/Service/Notification/NotificationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ private void InitializeNotifiers()
InitializeTelegramNotifier();
InitializeXxtuiNotifier();
InitializeDiscordWebhookNotifier();
InitializeServerChanNotifier();

// 添加新通知渠道时,在此处添加对应的初始化方法调用
}
Expand Down Expand Up @@ -300,6 +301,19 @@ private void InitializeDiscordWebhookNotifier()
));
}

/// <summary>
/// 初始化 ServerChan 通知器
/// </summary>
private void InitializeServerChanNotifier()
{
if (_notificationConfig?.ServerChanNotificationEnabled != true) return;

_notifierManager.RegisterNotifier(new ServerChanNotifier(
_notifyHttpClient,
_notificationConfig.ServerChanSendKey
));
}

/// <summary>
/// 解析信息推送通知渠道配置
/// </summary>
Expand Down
115 changes: 115 additions & 0 deletions BetterGenshinImpact/Service/Notifier/ServerChanNotifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using System;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BetterGenshinImpact.Service.Notification.Model;
using BetterGenshinImpact.Service.Notifier.Exception;
using BetterGenshinImpact.Service.Notifier.Interface;

namespace BetterGenshinImpact.Service.Notifier;

/// <summary>
/// ServerChan通知器
/// </summary>
public class ServerChanNotifier : INotifier
{
public string Name { get; set; } = "ServerChan";

private readonly HttpClient _httpClient;
private readonly string _sendKey;


public ServerChanNotifier(HttpClient httpClient, string sendKey)
{
_httpClient = httpClient;
_sendKey = sendKey;
}

public async Task SendAsync(BaseNotificationData content)
{
if (string.IsNullOrEmpty(_sendKey))
{
throw new NotifierException("ServerChan SendKey为空");
}

try
{
// 获取正确的API URL
string apiUrl = GetServerChanApiUrl(_sendKey);

// 生成通知标题和内容
string title = $"BetterGI·更好的原神";
string desp = GenerateDescription(content);

// 准备表单数据
var postData = $"title={Uri.EscapeDataString(title)}&desp={Uri.EscapeDataString(desp)}";

// 创建请求
var request = new HttpRequestMessage(HttpMethod.Post, apiUrl);
request.Content = new StringContent(postData, Encoding.UTF8, "application/x-www-form-urlencoded");

// 发送请求
var response = await _httpClient.SendAsync(request);

// 检查响应状态
if (!response.IsSuccessStatusCode)
{
throw new NotifierException($"ServerChan调用失败,状态码: {response.StatusCode}");
}
}
catch (NotifierException)
{
throw;
}
catch (System.Exception ex)
{
throw new NotifierException($"Error sending ServerChan message: {ex.Message}");
}
}

/// <summary>
/// 根据sendKey格式获取正确的API URL
/// </summary>
private string GetServerChanApiUrl(string key)
{
// 判断sendkey是否以"sctp"开头并提取数字部分
if (key.StartsWith("sctp"))
{
var match = Regex.Match(key, @"^sctp(\d+)t");
if (match.Success)
{
var num = match.Groups[1].Value;
return $"https://{num}.push.ft07.com/send/{key}.send";
}
else
{
throw new ArgumentException("Invalid key format for sctp.");
}
}
else
{
return $"https://sctapi.ftqq.com/{key}.send";
}
}

/// <summary>
/// 生成通知描述内容
/// </summary>
private string GenerateDescription(BaseNotificationData data)
{
var sb = new StringBuilder();

// 添加事件时间
sb.AppendLine($"**时间**: {data.Timestamp.ToString("yyyy-MM-dd HH:mm:ss")}");

// 添加事件消息
if (!string.IsNullOrEmpty(data.Message))
{
sb.AppendLine();
sb.AppendLine($"**消息**: {data.Message}");
}

return sb.ToString();
}
}
88 changes: 88 additions & 0 deletions BetterGenshinImpact/View/Pages/NotificationSettingsPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2003,5 +2003,93 @@
</Grid>
</StackPanel>
</ui:CardExpander>
<!-- ServerChan通知 -->
<ui:CardExpander Margin="0,0,0,12"
ContentPadding="0"
Icon="{ui:SymbolIcon ChatMultiple24}">
<ui:CardExpander.Header>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ui:TextBlock Grid.Row="0"
Grid.Column="0"
FontTypography="Body"
Text="启用 ServerChan 通知"
TextWrapping="Wrap" />
<ui:TextBlock Grid.Row="1"
Grid.Column="0"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
Text="ServerChan 推送通知相关设置"
TextWrapping="Wrap" />
<ui:ToggleSwitch Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,24,0"
IsChecked="{Binding Config.NotificationConfig.ServerChanNotificationEnabled, Mode=TwoWay}" />
</Grid>
</ui:CardExpander.Header>
<StackPanel>
<Grid Margin="16">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<ui:TextBlock Grid.Row="0"
Grid.Column="0"
FontTypography="Body"
Text="SendKey"
TextWrapping="Wrap" />
<ui:TextBlock Grid.Row="1"
Grid.Column="0"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
Text="填写 ServerChan 的 SendKey"
TextWrapping="Wrap" />
<ui:TextBox Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
MinWidth="180"
MaxWidth="800"
Margin="0,0,36,0"
Text="{Binding Config.NotificationConfig.ServerChanSendKey, Mode=TwoWay}"
TextWrapping="NoWrap" />
</Grid>
<Grid Margin="16">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ui:TextBlock Grid.Row="0"
Grid.Column="0"
FontTypography="Body"
Text="测试 ServerChan 通知"
TextWrapping="Wrap" />
<ui:TextBlock Grid.Row="1"
Grid.Column="0"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
Text="发送测试通知"
TextWrapping="Wrap" />
<ui:Button Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,36,0"
Command="{Binding TestServerChanNotificationCommand}"
Content="发送" />
</Grid>
</StackPanel>
</ui:CardExpander>
</StackPanel>
</Page>
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public partial class NotificationSettingsPageViewModel : ObservableObject, IView
nameof(DiscordWebhookNotifier.ImageEncoderEnum.WebP)
];

[ObservableProperty] private string _serverChanStatus = string.Empty;

public NotificationSettingsPageViewModel(IConfigService configService, NotificationService notificationService)
{
Config = configService.Get();
Expand Down Expand Up @@ -284,4 +286,23 @@ private async Task OnTestDiscordWebhookNotification()

IsLoading = false;
}

[RelayCommand]
private async Task OnTestServerChanNotification()
{
IsLoading = true;
ServerChanStatus = string.Empty;

var res = await _notificationService.TestNotifierAsync<ServerChanNotifier>();

ServerChanStatus = res.Message;

// 添加Toast提示
if (res.IsSuccess)
Toast.Success(res.Message);
else
Toast.Error(res.Message);

IsLoading = false;
}
}