|
|
@@ -186,7 +186,7 @@ const sendAndRecordMessage = async (uid, fcmToken, template, messageData, strate
|
|
|
errorMessage = errorInfo ? errorInfo.code : error.message;
|
|
|
if (isInvalidToken) {
|
|
|
// 如果是无效令牌错误,清空该用户的 fmToken
|
|
|
- await userModel_1.User.findByIdAndUpdate(uid, { fmToken: null });
|
|
|
+ await userModel_1.User.findOneAndUpdate({ uid: uid }, { fmToken: null });
|
|
|
console.warn(`[FCM] 检测到无效令牌,自动清除 UID ${uid} 的 fmToken。`);
|
|
|
errorMessage += " (Token cleared)";
|
|
|
}
|
|
|
@@ -209,10 +209,12 @@ const sendAndRecordMessage = async (uid, fcmToken, template, messageData, strate
|
|
|
/**
|
|
|
* 脚本的入口方法,用于筛选用户并发送每日FCM通知。
|
|
|
* 此方法通过cron外部调用。
|
|
|
+ *
|
|
|
+ * @returns {Promise<void>} 返回一个 Promise,当所有任务(包括定时任务)完成后解决。
|
|
|
*/
|
|
|
async function run() {
|
|
|
console.log("脚本开始:发送活跃用户每日通知...");
|
|
|
- // 在启动所有定时任务之前,首先建立数据库连接
|
|
|
+ // 在启动所有任务之前,首先建立数据库连接
|
|
|
await (0, database_1.connectToDatabase)();
|
|
|
try {
|
|
|
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
|
|
|
@@ -223,16 +225,18 @@ async function run() {
|
|
|
versionName: { $in: ["5.8.0-debug"] },
|
|
|
// versionName: { $in: ["5.8.0", "5.8.0-debug"] },
|
|
|
})
|
|
|
- .select("_id fmToken lang cc")
|
|
|
+ .select("_id uid fmToken lang cc")
|
|
|
.lean();
|
|
|
if (activeUsers.length === 0) {
|
|
|
console.log("未找到符合条件的用户,脚本结束。");
|
|
|
+ await (0, database_1.disconnectFromDatabase)();
|
|
|
return;
|
|
|
}
|
|
|
console.log(`找到 ${activeUsers.length} 位活跃用户。`);
|
|
|
const strategy = await messageStrategyModel_1.MessageStrategy.findOne({ name: strategyName }).populate("templates");
|
|
|
if (!strategy || !strategy.templates || strategy.templates.length < 2) {
|
|
|
console.error(`未找到策略 '${strategyName}' 或其绑定的消息模板,或模板数量不足2个。`);
|
|
|
+ await (0, database_1.disconnectFromDatabase)();
|
|
|
return;
|
|
|
}
|
|
|
const templates = strategy.templates;
|
|
|
@@ -240,6 +244,7 @@ async function run() {
|
|
|
const todaysArtworks = await getTodaysArtworksForFCM();
|
|
|
if (todaysArtworks.length < 2) {
|
|
|
console.warn("今日用于FCM消息推送的画作数量不足2个,无法执行双消息策略。脚本结束。");
|
|
|
+ await (0, database_1.disconnectFromDatabase)();
|
|
|
return;
|
|
|
}
|
|
|
const artwork1Id = todaysArtworks[0];
|
|
|
@@ -269,33 +274,36 @@ async function run() {
|
|
|
data1.bigger = "true";
|
|
|
data1.action = "go/art";
|
|
|
data1.param = artwork1Id;
|
|
|
- await sendAndRecordMessage(user._id, fcmToken, messageData.template1, data1, strategy._id, strategy.name);
|
|
|
+ await sendAndRecordMessage(user.uid, fcmToken, messageData.template1, data1, strategy._id, strategy.name);
|
|
|
}
|
|
|
console.log("第一批消息发送完成。");
|
|
|
- // --- 设置单个定时器,延迟30分钟后发送第二批消息 ---
|
|
|
- setTimeout(async () => {
|
|
|
- console.log("\n定时任务触发:开始发送第二批消息...");
|
|
|
- for (const messageData of messagesToSend) {
|
|
|
- const user = messageData.user;
|
|
|
- const userLang = getUserLanguage(user);
|
|
|
- const fcmToken = user.fmToken;
|
|
|
- const data2 = getMessageDataFromTemplate(messageData.template2, userLang);
|
|
|
- data2.image = `https://d1e6q48ob2nxw1.cloudfront.net/thumbs/v2/page/640/${artwork2Id}.png`;
|
|
|
- data2.bigger = "true";
|
|
|
- data2.action = "go/art";
|
|
|
- data2.param = artwork2Id;
|
|
|
- await sendAndRecordMessage(user._id, fcmToken, messageData.template2, data2, strategy._id, strategy.name);
|
|
|
- }
|
|
|
- console.log("第二批消息发送完成。");
|
|
|
- }, 30 * 60 * 1000);
|
|
|
- console.log("脚本执行完毕。第二批消息将在30分钟后发送。");
|
|
|
+ // 返回一个 Promise,该 Promise 将在 30 分钟后执行并完成所有后续操作
|
|
|
+ return new Promise((resolve) => {
|
|
|
+ setTimeout(async () => {
|
|
|
+ console.log("\n定时任务触发:开始发送第二批消息...");
|
|
|
+ for (const messageData of messagesToSend) {
|
|
|
+ const user = messageData.user;
|
|
|
+ const userLang = getUserLanguage(user);
|
|
|
+ const fcmToken = user.fmToken;
|
|
|
+ const data2 = getMessageDataFromTemplate(messageData.template2, userLang);
|
|
|
+ data2.image = `https://d1e6q48ob2nxw1.cloudfront.net/thumbs/v2/page/640/${artwork2Id}.png`;
|
|
|
+ data2.bigger = "true";
|
|
|
+ data2.action = "go/art";
|
|
|
+ data2.param = artwork2Id;
|
|
|
+ await sendAndRecordMessage(user.uid, fcmToken, messageData.template2, data2, strategy._id, strategy.name);
|
|
|
+ }
|
|
|
+ console.log("第二批消息发送完成。");
|
|
|
+ // 所有任务完成后,安全地断开数据库连接
|
|
|
+ await (0, database_1.disconnectFromDatabase)();
|
|
|
+ resolve();
|
|
|
+ }, 30 * 60 * 1000);
|
|
|
+ });
|
|
|
}
|
|
|
catch (error) {
|
|
|
console.error("脚本执行过程中发生致命错误:", error);
|
|
|
- }
|
|
|
- finally {
|
|
|
- // 脚本执行完毕,您可以在这里调用数据库断开连接
|
|
|
- await (0, database_1.disconnectFromDatabase)(); // 在退出前断开数据库连接
|
|
|
+ // 如果在第一阶段发生错误,确保断开数据库连接
|
|
|
+ await (0, database_1.disconnectFromDatabase)();
|
|
|
+ throw error;
|
|
|
}
|
|
|
}
|
|
|
// 这个 if 块确保只有在直接运行此文件时才调用 run() 函数
|