fix(scheduled-task): deliver verified WeChat links only after page is ready
Memind CI / Test, build, and release guards (push) Successful in 8m42s
Memind CI / Test, build, and release guards (push) Successful in 8m42s
Wait for HTML materialization before releasing delivery contracts, pass verified MindSpace URLs through proactive WeChat sends, resend on reconcile when pages land late, and report deferred customer-service delivery as unsent. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
import {
|
||||
buildScheduledTaskVerifiedHtmlUrls,
|
||||
deliveryTextPromisesPublicHtml,
|
||||
executeScheduledTask,
|
||||
formatScheduledTaskDeliveryMessage,
|
||||
looksLikeScheduledTaskNonDelivery,
|
||||
reconcileStuckStaticPageDeliveryContracts,
|
||||
resendScheduledTaskWechatForReadyPage,
|
||||
} from './scheduled-task-executor.mjs';
|
||||
|
||||
export function startScheduledTaskWorker({
|
||||
@@ -36,9 +39,12 @@ export function startScheduledTaskWorker({
|
||||
let stopped = false;
|
||||
let running = false;
|
||||
|
||||
const deliverTaskResult = async (task, deliveryText) => {
|
||||
const deliverTaskResult = async (task, deliveryText, { readyPaths = [] } = {}) => {
|
||||
const text = formatScheduledTaskDeliveryMessage(task, deliveryText);
|
||||
const notifyChannel = task.notifyChannel ?? 'both';
|
||||
const verifiedHtmlUrls = buildScheduledTaskVerifiedHtmlUrls(task.userId, readyPaths);
|
||||
const promisesHtml = deliveryTextPromisesPublicHtml(deliveryText);
|
||||
let wechatDelivery = null;
|
||||
if (scheduleService?.createUserNotification && (notifyChannel === 'web' || notifyChannel === 'both')) {
|
||||
await scheduleService.createUserNotification({
|
||||
userId: task.userId,
|
||||
@@ -58,10 +64,30 @@ export function startScheduledTaskWorker({
|
||||
(notifyChannel === 'wechat' || notifyChannel === 'both')
|
||||
&& typeof sendScheduleNotification === 'function'
|
||||
) {
|
||||
await sendScheduleNotification({ userId: task.userId, text }).catch((err) => {
|
||||
logger.warn?.('Scheduled task wechat notification failed:', err);
|
||||
});
|
||||
if (promisesHtml && verifiedHtmlUrls.length === 0) {
|
||||
logger.warn?.('[ScheduledTask] skip wechat until public html is ready', {
|
||||
taskId: task.id,
|
||||
userId: task.userId,
|
||||
});
|
||||
} else {
|
||||
const sent = await sendScheduleNotification({
|
||||
userId: task.userId,
|
||||
text,
|
||||
verifiedHtmlUrls,
|
||||
}).catch((err) => {
|
||||
logger.warn?.('Scheduled task wechat notification failed:', err);
|
||||
return false;
|
||||
});
|
||||
if (sent && verifiedHtmlUrls.length > 0) {
|
||||
wechatDelivery = {
|
||||
sentAt: Date.now(),
|
||||
relativePaths: readyPaths.map((value) => String(value ?? '').trim()).filter(Boolean),
|
||||
source: 'scheduled_task_worker',
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return { wechatDelivery };
|
||||
};
|
||||
|
||||
const runOnce = async () => {
|
||||
@@ -69,13 +95,25 @@ export function startScheduledTaskWorker({
|
||||
running = true;
|
||||
try {
|
||||
if (pool && h5Root) {
|
||||
await reconcileStuckStaticPageDeliveryContracts({
|
||||
const reconciled = await reconcileStuckStaticPageDeliveryContracts({
|
||||
pool,
|
||||
h5Root,
|
||||
logger,
|
||||
}).catch((err) => {
|
||||
logger.warn?.('Scheduled task delivery reconcile failed:', err);
|
||||
return [];
|
||||
});
|
||||
for (const item of reconciled) {
|
||||
await resendScheduledTaskWechatForReadyPage({
|
||||
pool,
|
||||
userId: item.userId,
|
||||
relativePath: item.relativePath,
|
||||
notificationDispatcher,
|
||||
logger,
|
||||
}).catch((err) => {
|
||||
logger.warn?.('Scheduled task reconcile wechat resend failed:', err);
|
||||
});
|
||||
}
|
||||
}
|
||||
const dueTasks = await scheduledTaskService.listDueTasks({ limit: 10 });
|
||||
for (const candidate of dueTasks) {
|
||||
@@ -99,10 +137,15 @@ export function startScheduledTaskWorker({
|
||||
err.code = 'SCHEDULED_TASK_NON_DELIVERY';
|
||||
throw err;
|
||||
}
|
||||
await deliverTaskResult(task, result.deliveryText);
|
||||
const deliveryMeta = await deliverTaskResult(task, result.deliveryText, {
|
||||
readyPaths: result.readyPaths,
|
||||
});
|
||||
await scheduledTaskService.markTaskSucceeded(task, {
|
||||
result: {
|
||||
deliveryText: result.deliveryText,
|
||||
...(deliveryMeta.wechatDelivery
|
||||
? { wechatDelivery: deliveryMeta.wechatDelivery }
|
||||
: {}),
|
||||
},
|
||||
deliveryText: result.deliveryText,
|
||||
sessionId: result.sessionId,
|
||||
|
||||
Reference in New Issue
Block a user