浏览代码

分组发送报告

Taio_O 1 周之前
父节点
当前提交
03fa6f9bc3
共有 3 个文件被更改,包括 20 次插入9 次删除
  1. 3 2
      src/core/notifier.js
  2. 8 7
      src/core/scheduler.js
  3. 9 0
      src/utils/markdown.js

+ 3 - 2
src/core/notifier.js

@@ -1,6 +1,7 @@
 const TelegramBot = require('node-telegram-bot-api');
 const logger = require('../utils/logger');
 const { Notification } = require('../models');
+const { escapeMarkdown } = require('../utils/markdown');
 
 class TelegramNotifier {
   constructor() {
@@ -83,8 +84,8 @@ class TelegramNotifier {
 
     await this.sendNotification({
       type: 'subscription',
-      title,
-      message,
+      title: escapeMarkdown(title),
+      message: message,
       subscriptionId: subscription.id,
       metadata: {
         subscriptionName: subscription.name,

+ 8 - 7
src/core/scheduler.js

@@ -4,6 +4,7 @@ const SpeedTester = require('./speedTester');
 const TelegramNotifier = require('./notifier');
 const MultiSubscriptionManager = require('./multiSubscriptionManager');
 const { Node, TestResult } = require('../models');
+const { escapeMarkdown } = require('../utils/markdown');
 
 class Scheduler {
   constructor() {
@@ -295,11 +296,11 @@ class Scheduler {
       return;
     }
 
-    const title = `📊 订阅测试报告: ${subscription.name}`;
+    const title = `📊 订阅测试报告: ${escapeMarkdown(subscription.name)}`;
     
     const lines = [
-      `*订阅名称:* ${subscription.name}`,
-      `*测试时间:* ${summary.testTime}`,
+      `*订阅名称:* ${escapeMarkdown(subscription.name)}`,
+      `*测试时间:* ${escapeMarkdown(summary.testTime)}`,
       `*节点总数:* ${summary.totalNodes}个`,
       `*在线节点:* ${summary.onlineNodes}个`,
       `*离线节点:* ${summary.offlineNodes}个`,
@@ -317,14 +318,14 @@ class Scheduler {
     if (summary.bestNodes.length > 0) {
       lines.push(`\n🏆 *最佳节点:*`);
       summary.bestNodes.forEach((node, index) => {
-        lines.push(`${index + 1}. ${node.name} - ${node.latency}ms`);
+        lines.push(`${index + 1}. ${escapeMarkdown(node.name)} - ${node.latency}ms`);
       });
     }
 
     if (summary.failedNodes.length > 0) {
       lines.push(`\n❌ *故障节点:*`);
       summary.failedNodes.forEach((node, index) => {
-        lines.push(`${index + 1}. ${node.name}`);
+        lines.push(`${index + 1}. ${escapeMarkdown(node.name)}`);
       });
     }
 
@@ -353,7 +354,7 @@ class Scheduler {
 
     const title = '📈 总体测试报告';
     const lines = [
-      `*测试时间:* ${new Date().toLocaleString('zh-CN')}`,
+      `*测试时间:* ${escapeMarkdown(new Date().toLocaleString('zh-CN'))}`,
       `*订阅数量:* ${totalSubscriptions}个`,
       `*节点总数:* ${totalNodes}个`,
       `*在线节点:* ${totalOnlineNodes}个`,
@@ -370,7 +371,7 @@ class Scheduler {
     subscriptionResults.forEach(result => {
       const { subscription, summary } = result;
       const status = summary.successRate >= 80 ? '🟢' : summary.successRate >= 50 ? '🟡' : '🔴';
-      lines.push(`${status} ${subscription.name}: ${summary.onlineNodes}/${summary.totalNodes} (${summary.successRate}%)`);
+      lines.push(`${status} ${escapeMarkdown(subscription.name)}: ${summary.onlineNodes}/${summary.totalNodes} (${summary.successRate}%)`);
     });
 
     const message = lines.join('\n');

+ 9 - 0
src/utils/markdown.js

@@ -0,0 +1,9 @@
+// Markdown转义工具函数
+function escapeMarkdown(text) {
+  if (!text) return '';
+  return text
+    .toString()
+    .replace(/([_\*\[\]()~`>#+\-=|{}.!])/g, '\\$1');
+}
+
+module.exports = { escapeMarkdown };