Add EOI automation system with email processing and document management
- Implement automated EOI processing from sales emails - Add EOI document upload and management capabilities - Enhance email thread handling with better parsing and grouping - Add retry logic and error handling for file operations - Introduce Documeso integration for document processing - Create server tasks and plugins infrastructure - Update email composer with improved attachment handling
This commit is contained in:
107
server/tasks/eoi-reminders.ts
Normal file
107
server/tasks/eoi-reminders.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import cron from 'node-cron';
|
||||
import { getInterests } from '~/server/utils/nocodb';
|
||||
import { checkDocumentSignatureStatus } from '~/server/utils/documeso';
|
||||
|
||||
// Track if tasks are already scheduled
|
||||
let tasksScheduled = false;
|
||||
|
||||
export function scheduleEOIReminders() {
|
||||
if (tasksScheduled) {
|
||||
console.log('[EOI Reminders] Tasks already scheduled');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('[EOI Reminders] Scheduling reminder tasks...');
|
||||
|
||||
// Schedule for 9am daily
|
||||
cron.schedule('0 9 * * *', async () => {
|
||||
console.log('[EOI Reminders] Running 9am reminder check...');
|
||||
await processReminders();
|
||||
}, {
|
||||
timezone: 'Europe/Paris'
|
||||
});
|
||||
|
||||
// Schedule for 4pm daily
|
||||
cron.schedule('0 16 * * *', async () => {
|
||||
console.log('[EOI Reminders] Running 4pm reminder check...');
|
||||
await processReminders();
|
||||
}, {
|
||||
timezone: 'Europe/Paris'
|
||||
});
|
||||
|
||||
tasksScheduled = true;
|
||||
console.log('[EOI Reminders] Tasks scheduled successfully');
|
||||
}
|
||||
|
||||
async function processReminders() {
|
||||
try {
|
||||
// Get all interests
|
||||
const response = await getInterests();
|
||||
const interests = response.list || [];
|
||||
|
||||
console.log(`[EOI Reminders] Processing ${interests.length} interests...`);
|
||||
|
||||
for (const interest of interests) {
|
||||
try {
|
||||
// Skip if no document ID or reminders disabled
|
||||
const documentId = (interest as any)['documeso_document_id'];
|
||||
const remindersEnabled = (interest as any)['reminder_enabled'] !== false;
|
||||
|
||||
if (!documentId || !remindersEnabled) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if we should send reminder (not sent in last 12 hours)
|
||||
const lastReminderSent = (interest as any)['last_reminder_sent'];
|
||||
if (lastReminderSent) {
|
||||
const lastSentTime = new Date(lastReminderSent).getTime();
|
||||
const twelveHoursAgo = Date.now() - (12 * 60 * 60 * 1000);
|
||||
if (lastSentTime > twelveHoursAgo) {
|
||||
continue; // Skip if reminder sent within last 12 hours
|
||||
}
|
||||
}
|
||||
|
||||
// Send reminder
|
||||
await sendReminder(interest);
|
||||
} catch (error) {
|
||||
console.error(`[EOI Reminders] Error processing interest ${interest.Id}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[EOI Reminders] Reminder processing completed');
|
||||
} catch (error) {
|
||||
console.error('[EOI Reminders] Error in processReminders:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function sendReminder(interest: any) {
|
||||
try {
|
||||
const response = await $fetch<{
|
||||
success: boolean;
|
||||
remindersSent: number;
|
||||
results: any[];
|
||||
message?: string;
|
||||
}>('/api/eoi/send-reminders', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-tag': '094ut234' // System tag for automated processes
|
||||
},
|
||||
body: {
|
||||
interestId: interest.Id.toString(),
|
||||
documentId: (interest as any)['documeso_document_id']
|
||||
}
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
console.log(`[EOI Reminders] Sent ${response.remindersSent} reminders for interest ${interest.Id}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[EOI Reminders] Failed to send reminder for interest ${interest.Id}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
// Export function to manually trigger reminders (for testing)
|
||||
export async function triggerReminders() {
|
||||
console.log('[EOI Reminders] Manually triggering reminder check...');
|
||||
await processReminders();
|
||||
}
|
||||
59
server/tasks/process-sales-emails.ts
Normal file
59
server/tasks/process-sales-emails.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
// Task to process sales emails for EOI documents
|
||||
import { $fetch } from 'ofetch';
|
||||
|
||||
let taskScheduled = false;
|
||||
|
||||
export function scheduleEmailProcessing() {
|
||||
if (taskScheduled) {
|
||||
console.log('[Process Sales Emails] Task already scheduled');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('[Process Sales Emails] Scheduling email processing task...');
|
||||
|
||||
// Process emails every 30 minutes
|
||||
setInterval(async () => {
|
||||
console.log('[Process Sales Emails] Running email check...');
|
||||
await processEmails();
|
||||
}, 30 * 60 * 1000); // 30 minutes
|
||||
|
||||
// Also run immediately on startup
|
||||
setTimeout(() => {
|
||||
processEmails();
|
||||
}, 10000); // 10 seconds after startup
|
||||
|
||||
taskScheduled = true;
|
||||
console.log('[Process Sales Emails] Task scheduled successfully');
|
||||
}
|
||||
|
||||
async function processEmails() {
|
||||
try {
|
||||
const response = await $fetch('/api/email/process-sales-eois', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-tag': '094ut234' // System tag for automated processes
|
||||
}
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
console.log(`[Process Sales Emails] Processed ${response.processed} emails`);
|
||||
if (response.results && response.results.length > 0) {
|
||||
response.results.forEach((result: any) => {
|
||||
if (result.processed) {
|
||||
console.log(`[Process Sales Emails] Successfully processed EOI for ${result.clientName}`);
|
||||
} else {
|
||||
console.log(`[Process Sales Emails] Failed to process EOI: ${result.error}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Process Sales Emails] Error processing emails:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Export function to manually trigger processing (for testing)
|
||||
export async function triggerEmailProcessing() {
|
||||
console.log('[Process Sales Emails] Manually triggering email processing...');
|
||||
await processEmails();
|
||||
}
|
||||
Reference in New Issue
Block a user