Improve WeChat MP replies and ship MindSpace/H5 production updates.
Add WeChat service account routing with sync acks, connectivity tests, and context isolation; document deploy runbooks; and bundle related MindSpace, voice, Plaza, and server gateway changes for production rollout. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
export function startScheduleReminderWorker({
|
||||
scheduleService,
|
||||
sendWechatTextToUser,
|
||||
logger = console,
|
||||
intervalMs = Number(process.env.H5_REMINDER_SCAN_INTERVAL_MS ?? 30_000),
|
||||
maxAttempts = Number(process.env.H5_REMINDER_MAX_ATTEMPTS ?? 5),
|
||||
runOnStart = true,
|
||||
} = {}) {
|
||||
if (!scheduleService || typeof sendWechatTextToUser !== 'function') {
|
||||
return { stop() {} };
|
||||
}
|
||||
|
||||
let stopped = false;
|
||||
let running = false;
|
||||
|
||||
const runOnce = async () => {
|
||||
if (running || stopped) return;
|
||||
running = true;
|
||||
try {
|
||||
const due = await scheduleService.listDueDigestSubscriptions({ limit: 50 });
|
||||
for (const candidate of due) {
|
||||
const subscription = await scheduleService.lockDigestSubscription(candidate.id);
|
||||
if (!subscription) continue;
|
||||
try {
|
||||
const text = await scheduleService.buildTodoDigestText({
|
||||
userId: subscription.userId,
|
||||
timezone: subscription.timezone,
|
||||
});
|
||||
await sendWechatTextToUser(subscription.userId, text);
|
||||
await scheduleService.logDelivery({
|
||||
subscriptionId: subscription.id,
|
||||
userId: subscription.userId,
|
||||
channel: subscription.channel,
|
||||
status: 'success',
|
||||
});
|
||||
await scheduleService.markDigestSent(subscription);
|
||||
} catch (err) {
|
||||
logger.warn?.('Schedule digest delivery failed:', err);
|
||||
await scheduleService.logDelivery({
|
||||
subscriptionId: subscription.id,
|
||||
userId: subscription.userId,
|
||||
channel: subscription.channel,
|
||||
status: 'failed',
|
||||
errorMessage: err instanceof Error ? err.message : String(err),
|
||||
}).catch(() => {});
|
||||
await scheduleService.markDigestFailed(subscription, err, { maxAttempts });
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.warn?.('Schedule reminder worker failed:', err);
|
||||
} finally {
|
||||
running = false;
|
||||
}
|
||||
};
|
||||
|
||||
const timer = setInterval(runOnce, Math.max(1000, Number(intervalMs) || 30_000));
|
||||
timer.unref?.();
|
||||
if (runOnStart) void runOnce();
|
||||
|
||||
return {
|
||||
runOnce,
|
||||
stop() {
|
||||
stopped = true;
|
||||
clearInterval(timer);
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user