✨ feat: 实现企业微信消息推送功能,支持Markdown格式
This commit is contained in:
parent
981d7f1c2a
commit
924da331c7
|
|
@ -2,7 +2,8 @@
|
||||||
import { EventEmitter } from "events";
|
import { EventEmitter } from "events";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { EmailSender } from "./mailer.js";
|
// import { EmailSender } from "./mailer.js";
|
||||||
|
import { sendQYWechatMessage } from "./utils.js"
|
||||||
import { SQLiteMessageQueue } from "./sqlite.js";
|
import { SQLiteMessageQueue } from "./sqlite.js";
|
||||||
import { md5 } from "./utils.js";
|
import { md5 } from "./utils.js";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
@ -13,15 +14,15 @@ class MessageQueue extends EventEmitter {
|
||||||
this.queue = new SQLiteMessageQueue();
|
this.queue = new SQLiteMessageQueue();
|
||||||
this.processing = false;
|
this.processing = false;
|
||||||
// this.queueFile = path.resolve("message_queue.json");K
|
// this.queueFile = path.resolve("message_queue.json");K
|
||||||
this.emailSender = new EmailSender({
|
// this.emailSender = new EmailSender({
|
||||||
host: "smtp.exmail.qq.com",
|
// host: "smtp.exmail.qq.com",
|
||||||
port: 465,
|
// port: 465,
|
||||||
secure: true,
|
// secure: true,
|
||||||
auth: {
|
// auth: {
|
||||||
user: "jiqiren@axbbaoxian.com",
|
// user: "jiqiren@axbbaoxian.com",
|
||||||
pass: "Am13579q",
|
// pass: "Am13579q",
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
this.recipients = [
|
this.recipients = [
|
||||||
"huzhengrong@axbbaoxian.com",
|
"huzhengrong@axbbaoxian.com",
|
||||||
];
|
];
|
||||||
|
|
@ -88,7 +89,8 @@ class MessageQueue extends EventEmitter {
|
||||||
html += this.generateTable(spiderName, msgMap[spiderName]);
|
html += this.generateTable(spiderName, msgMap[spiderName]);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
this.emailSender.sendBulkEmail(this.recipients, "招标项目最新公告", html);
|
// this.emailSender.sendBulkEmail(this.recipients, "招标项目最新公告", html);
|
||||||
|
await sendQYWechatMessage(html)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`❌ 通知发送失败: ${error}`);
|
console.error(`❌ 通知发送失败: ${error}`);
|
||||||
}
|
}
|
||||||
|
|
@ -97,62 +99,18 @@ class MessageQueue extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
generateTable(spiderName, data) {
|
generateTable(spiderName, data) {
|
||||||
let tableHtml = `
|
let tableHtml =`
|
||||||
<div style="margin: 30px 0; font-family: Arial, sans-serif;">
|
各位好,
|
||||||
<h2 style="color: #2c3e50; border-bottom: 3px solid #3498db; padding-bottom: 10px; margin-bottom: 20px;">
|
本次检测发现了${data.length}条新增招标信息,详情如下:
|
||||||
🕷️ ${spiderName} (${data.length} 条新增)
|
`
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div style="overflow-x: auto; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border-radius: 8px; margin-bottom: 20px;">
|
|
||||||
<table style="width: 100%; border-collapse: collapse; background: white; min-width: 800px;">
|
|
||||||
<thead>
|
|
||||||
<tr style="background: linear-gradient(135deg, #3498db 0%, #2980b9 100%); color: white;">
|
|
||||||
<th style="border: 1px solid #ddd; padding: 12px 8px; text-align: left; font-weight: bold; width: 50px;">序号</th>
|
|
||||||
<th style="border: 1px solid #ddd; padding: 12px 8px; text-align: left; font-weight: bold; min-width: 300px;">项目名称</th>
|
|
||||||
<th style="border: 1px solid #ddd; padding: 12px 8px; text-align: left; font-weight: bold; width: 140px;">发布时间</th>
|
|
||||||
<th style="border: 1px solid #ddd; padding: 12px 8px; text-align: left; font-weight: bold; width: 140px;">截止时间</th>
|
|
||||||
<th style="border: 1px solid #ddd; padding: 12px 8px; text-align: left; font-weight: bold; width: 100px;">查看详情</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
`;
|
|
||||||
data.forEach((item, index) => {
|
data.forEach((item, index) => {
|
||||||
const rowColor = index % 2 === 0 ? "#f8f9fa" : "white";
|
|
||||||
// const publishTime = this.formatDateTime(item.publishTime);
|
|
||||||
// const endTime = this.formatDateTime(item.endTime);
|
|
||||||
const urls = this.formatUrls(item.urls);
|
|
||||||
|
|
||||||
tableHtml += `
|
tableHtml += `
|
||||||
<tr style="background-color: ${rowColor}; border-bottom: 1px solid #eee;">
|
【${index+1}】
|
||||||
<td style="border: 1px solid #ddd; padding: 10px 8px; text-align: center; font-weight: bold; color: #666;">
|
保司:${spiderName}
|
||||||
${index + 1}
|
招标标题:${item.name}
|
||||||
</td>
|
详情链接:[链接](${item.urls})
|
||||||
<td style="border: 1px solid #ddd; padding: 10px 8px; line-height: 1.4;">
|
|
||||||
<div style="font-weight: 500; color: #2c3e50; margin-bottom: 4px;">
|
|
||||||
${item.name}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td style="border: 1px solid #ddd; padding: 10px 8px; color: #495057;">
|
|
||||||
${item.publishTime}
|
|
||||||
</td>
|
|
||||||
<td style="border: 1px solid #ddd; padding: 10px 8px; color: #495057;">
|
|
||||||
<div>${item.endTime}</div>
|
|
||||||
</td>
|
|
||||||
<td style="border: 1px solid #ddd; padding: 10px 8px; text-align: center;">
|
|
||||||
${urls}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
`;
|
`;
|
||||||
});
|
});
|
||||||
|
|
||||||
tableHtml += `
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
return tableHtml;
|
return tableHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
8
utils.js
8
utils.js
|
|
@ -255,8 +255,8 @@ async function sendQYWechatMessage(message) {
|
||||||
try {
|
try {
|
||||||
const webhook = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=7de26c43-8652-4204-9665-47a5cef58b58";
|
const webhook = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=7de26c43-8652-4204-9665-47a5cef58b58";
|
||||||
await axios.post(webhook, {
|
await axios.post(webhook, {
|
||||||
msgtype: "text",
|
msgtype: "markdown",
|
||||||
text: {
|
markdown: {
|
||||||
content: message
|
content: message
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
|
@ -264,9 +264,9 @@ async function sendQYWechatMessage(message) {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log(`${this.key}-企业微信消息推送成功: ${message}`);
|
console.log(`企业微信消息推送成功: ${message}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`${this.key}-企业微信消息推送失败:`, error.message);
|
console.error(`企业微信消息推送失败:`, error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export {
|
export {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue