feat: additional webhook url in torrent blocker plugin

This commit is contained in:
kastov 2026-08-09 18:54:01 +03:00
parent fc2bb8896e
commit 3768d73f1c
No known key found for this signature in database
GPG key ID: 1B27BE29057F4C90
5 changed files with 33 additions and 5 deletions

8
package-lock.json generated
View file

@ -20,7 +20,7 @@
"@nestjs/platform-express": "11.1.28",
"@nestjs/schedule": "^6.1.3",
"@remnawave/hashed-set": "^0.0.4",
"@remnawave/node-plugins": "0.6.0",
"@remnawave/node-plugins": "0.6.2",
"@remnawave/xtls-sdk": "0.16.0",
"@remnawave/xtls-sdk-nestjs": "0.6.1",
"compression": "^1.8.1",
@ -2545,9 +2545,9 @@
"license": "AGPL-3.0-only"
},
"node_modules/@remnawave/node-plugins": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@remnawave/node-plugins/-/node-plugins-0.6.0.tgz",
"integrity": "sha512-q82oHyZxqw0OdbTyC6fDs6s+Wbky9HzVL36T/nDyRA4BKdboOuOH58tET0YiO12M1kQFXqiMsEci0ZEB1ONKmQ==",
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/@remnawave/node-plugins/-/node-plugins-0.6.2.tgz",
"integrity": "sha512-M5r50NVA94Lh7uWx16+PjCV34OxdKDieVmfrCS97qynk9sQm+VvHkS5wIDfsDSKxIB05y0HyT/N1cS3WxR/uEA==",
"license": "AGPL-3.0-only",
"dependencies": {
"zod": "4.4.3"

View file

@ -42,7 +42,7 @@
"@nestjs/platform-express": "11.1.28",
"@nestjs/schedule": "^6.1.3",
"@remnawave/hashed-set": "^0.0.4",
"@remnawave/node-plugins": "0.6.0",
"@remnawave/node-plugins": "0.6.2",
"@remnawave/xtls-sdk": "0.16.0",
"@remnawave/xtls-sdk-nestjs": "0.6.1",
"compression": "^1.8.1",

View file

@ -11,6 +11,7 @@ import { PluginStateService } from '../../services/plugin-state.service';
import { XrayWebhookEvent } from './xray-webhook.event';
const SOURCE_REGEX = /^(?:(?:tcp|udp):)?(?:\[(.+?)\]|(.+?))(?::(\d+))?$/;
const WEBHOOK_TIMEOUT_MS = 5_000;
@EventsHandler(XrayWebhookEvent)
export class XrayWebhookHandler implements IEventHandler<XrayWebhookEvent> {
@ -75,6 +76,12 @@ export class XrayWebhookHandler implements IEventHandler<XrayWebhookEvent> {
};
this.pluginState.torrentBlocker.addReport(report);
const webhookUrl = this.pluginState.torrentBlocker.getWebhookUrl();
if (webhookUrl) {
this.sendWebhook(webhookUrl, report);
}
} catch (error) {
this.logger.error(`Error in Event XrayWebhookHandler: ${error}`);
} finally {
@ -92,4 +99,15 @@ export class XrayWebhookHandler implements IEventHandler<XrayWebhookEvent> {
return candidate;
}
private sendWebhook(url: string, report: TorrentBlockerReportModel): void {
fetch(url, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify(report),
signal: AbortSignal.timeout(WEBHOOK_TIMEOUT_MS),
})
.then((response) => response.body?.cancel())
.catch(() => void 0);
}
}

View file

@ -209,6 +209,7 @@ export class PluginService {
this.state.torrentBlocker.setIgnoredIps(ips);
this.state.torrentBlocker.setIgnoredUsers(users);
this.state.torrentBlocker.configure(blockDuration);
this.state.torrentBlocker.setWebhookUrl(pluginData.torrentBlocker.webhookUrl);
this.state.torrentBlocker.setIncludeRuleTags(pluginData.torrentBlocker.includeRuleTags);
this.logger.log(

View file

@ -7,6 +7,7 @@ export class TorrentBlockerState {
private ignoredIps = new Set<string>();
private ignoredUsers = new Set<string>();
private includeRuleTags = new Set<string>();
private webhookUrl: string | null = null;
private reports: TorrentBlockerReportModel[] = [];
get isEnabled(): boolean {
@ -30,6 +31,14 @@ export class TorrentBlockerState {
this.ignoredUsers = new Set(users);
}
setWebhookUrl(url: string | undefined | null): void {
this.webhookUrl = url ?? null;
}
getWebhookUrl(): string | null {
return this.webhookUrl;
}
isIpIgnored(ip: string): boolean {
return this.ignoredIps.has(ip) || DEFAULT_IGNORED_IPS.has(ip);
}