-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscheduler.js
More file actions
109 lines (95 loc) · 3.54 KB
/
scheduler.js
File metadata and controls
109 lines (95 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import cron from 'node-cron';
import mongoose from 'mongoose';
import { User } from './models/user.js';
import { fetchNewsForUser } from './utils/newsAPI.js';
import { sendNewsEmail as sendEmail } from './utils/emailSender.js';
import { generateFunnySummary } from './utils/aiSummarizer.js';
import dotenv from 'dotenv';
dotenv.config();
// Connect to MongoDB
mongoose
.connect(process.env.MONGO_URI)
.then(() => console.log('✅ MongoDB connected'))
.catch((err) => console.log('❌ MongoDB connection error:', err));
let cachedNews = {};
let cachedFunnySummary = {};
cron.schedule('0 0 * * *', async () => {
console.log('Scheduler running at @1');
try {
const currentTime = new Date();
// Fetch users whose daily insights are enabled and due
const users = await User.find({
dailyInsightsEnabled: true,
dailyInsightsTime: { $lte: currentTime },
});
for (const user of users) {
try {
// Fetch news for this user
const newsItems = (await fetchNewsForUser(user)) || [];
cachedNews[user._id] = Array.isArray(newsItems) ? newsItems : [];
// Generate funny summary
const funnySummary = await generateFunnySummary(newsItems);
cachedFunnySummary[user._id] = funnySummary;
console.log(cachedFunnySummary[user._id], '- cachedFunnySummary');
console.log(`✅ News + summary refreshed for ${user.email}`);
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
} catch (userErr) {
console.error(
`❌ Error fetching/summarizing for ${user.email}:`,
userErr
);
}
}
} catch (err) {
console.error('❌ Failed to refresh news:', err);
}
});
cron.schedule('* * * * *', async () => {
try {
const now = new Date();
const currentHour = now.getHours();
const currentMinute = now.getMinutes();
const currentTime = `${currentHour.toString().padStart(2, '0')}:${currentMinute.toString().padStart(2, '0')}`;
console.log(`🕒 Scheduler running at ${currentTime}`);
// Start of today for checking duplicates
const startOfToday = new Date();
startOfToday.setHours(0, 0, 0, 0);
// Fetch users who are enabled and haven't received email today
const users = await User.find({
dailyInsightsEnabled: true,
$or: [
{ lastInsightsSent: { $lt: startOfToday } },
{ lastInsightsSent: { $exists: false } },
],
});
// Filter users whose dailyInsightsTime matches current hour/minute
const usersToSend = users.filter((user) => {
const [hour, minute] = user.dailyInsightsTime.split(':').map(Number);
return hour === currentHour && minute === currentMinute;
});
for (const user of usersToSend) {
try {
let newsToSend;
if (cachedFunnySummary && cachedFunnySummary[user._id]) {
newsToSend = cachedFunnySummary[user._id];
} else if (cachedNews && cachedNews[user._id]?.length) {
newsToSend = cachedNews[user._id].slice(0, 5);
} else {
console.log(
`⚠️ No news available for ${user.email}, skipping email.`
);
continue;
}
await sendEmail(user.email, newsToSend);
console.log(`📧 Email sent to ${user.email} at ${currentTime}`);
// Update lastInsightsSent to prevent duplicates
user.lastInsightsSent = now;
await user.save();
} catch (err) {
console.error(`❌ Failed for ${user.email}:`, err);
}
}
} catch (err) {
console.error('❌ Error in scheduler:', err);
}
});