feat: 支持自定义 webhook 模板,支持发送测试信息 (#551)

This commit is contained in:
ᴀᴍᴛᴏᴀᴇʀ
2025-12-05 00:21:36 +08:00
committed by GitHub
parent e76673d076
commit 7ef38a38ed
7 changed files with 114 additions and 13 deletions

View File

@@ -229,6 +229,10 @@ class ApiClient {
return this.get<string>(`/video-sources/${type}/default-path`, { name });
}
async testNotifier(notifier: Notifier): Promise<ApiResponse<boolean>> {
return this.post<boolean>('/config/notifiers/ping', notifier);
}
async getConfig(): Promise<ApiResponse<Config>> {
return this.get<Config>('/config');
}
@@ -283,6 +287,7 @@ const api = {
evaluateVideoSourceRules: (type: string, id: number) =>
apiClient.evaluateVideoSourceRules(type, id),
getDefaultPath: (type: string, name: string) => apiClient.getDefaultPath(type, name),
testNotifier: (notifier: Notifier) => apiClient.testNotifier(notifier),
getConfig: () => apiClient.getConfig(),
updateConfig: (config: Config) => apiClient.updateConfig(config),
getDashboard: () => apiClient.getDashboard(),

View File

@@ -282,6 +282,7 @@ export interface TelegramNotifier {
export interface WebhookNotifier {
type: 'webhook';
url: string;
template?: string | null;
}
export type Notifier = TelegramNotifier | WebhookNotifier;

View File

@@ -74,6 +74,18 @@
formData.notifiers = formData.notifiers.filter((_, i) => i !== index);
}
async function testNotifier(notifier: Notifier) {
try {
await api.testNotifier(notifier);
toast.success('测试通知发送成功');
} catch (error) {
console.error('测试通知失败:', error);
toast.error('测试通知失败', {
description: (error as ApiError).message
});
}
}
async function loadConfig() {
loading = true;
try {
@@ -772,6 +784,9 @@
>
编辑
</Button>
<Button size="sm" variant="secondary" onclick={() => testNotifier(notifier)}>
测试
</Button>
<Button size="sm" variant="destructive" onclick={() => deleteNotifier(index)}>
删除
</Button>

View File

@@ -15,6 +15,7 @@
let botToken = '';
let chatId = '';
let webhookUrl = '';
let webhookTemplate = '';
// 初始化表单
$: {
@@ -26,12 +27,14 @@
} else {
type = 'webhook';
webhookUrl = notifier.url;
webhookTemplate = notifier.template || '';
}
} else {
type = 'telegram';
botToken = '';
chatId = '';
webhookUrl = '';
webhookTemplate = '';
}
}
@@ -69,7 +72,8 @@
const newNotifier: Notifier = {
type: 'webhook',
url: webhookUrl.trim()
url: webhookUrl.trim(),
template: webhookTemplate.trim() || null
};
onSave(newNotifier);
}
@@ -113,10 +117,23 @@
格式示例:{jsonExample}
</p>
</div>
<div class="space-y-2">
<Label for="webhook-template">模板(可选)</Label>
<textarea
id="webhook-template"
class="border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex min-h-[120px] w-full rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
placeholder={'{"text": "{{{message}}}"}'}
bind:value={webhookTemplate}
></textarea>
<p class="text-muted-foreground text-xs">
用于渲染 Webhook 的 Handlebars 模板。如果不填写,将使用默认模板。<br />
可用变量:<code class="text-xs">message</code>(通知内容)
</p>
</div>
{/if}
</div>
<div class="flex justify-end gap-3">
<Button variant="outline" onclick={onCancel}>取消</Button>
<Button onclick={handleSave}>保存</Button>
<Button onclick={handleSave}>确认</Button>
</div>