Skip to content

Instantly share code, notes, and snippets.

@PhantomKnight287
Created January 7, 2025 17:07
Show Gist options
  • Select an option

  • Save PhantomKnight287/abdf7a7512dfdd3105c8ae07b24ad91b to your computer and use it in GitHub Desktop.

Select an option

Save PhantomKnight287/abdf7a7512dfdd3105c8ae07b24ad91b to your computer and use it in GitHub Desktop.
@Cron(CronExpression.EVERY_MINUTE)
async streakCronJob() {
const users = await prisma.user.findMany();
for (const user of users) {
if (!user.timezone || !IANATimezones[user.timezone]) continue;
const userLocalTime = moment().tz(IANATimezones[user.timezone]);
// Fetch the last streak record
const lastStreakRecord = await prisma.streak.findFirst({
where: { userId: user.id },
orderBy: [{ createdAt: 'desc' }],
});
// If there's no streak record, continue to the next user
if (!lastStreakRecord) continue;
if (userLocalTime.hour() === 0 && userLocalTime.minute() === 0) {
const createdAt = moment(lastStreakRecord.createdAt).tz(
IANATimezones[user.timezone],
);
const yesterdayStart = userLocalTime
.clone()
.subtract(1, 'day')
.startOf('day');
const yesterdayEnd = userLocalTime
.clone()
.subtract(1, 'day')
.endOf('day');
if (createdAt.isBetween(yesterdayStart, yesterdayEnd, null, '[]')) {
if (user.notificationToken) {
await onesignal.createNotification({
app_id: process.env.ONESIGNAL_APP_ID,
name: 'Streak Safe Notification',
contents: {
en: 'Your streak is safe! Keep up the great work.',
},
headings: {
en: 'Your streak is safe 😊',
},
include_subscription_ids: [user.notificationToken],
large_icon:
'https://cdn.voicelearn.tech/image-removebg-preview%20(1).png',
});
}
} else {
if (user.streakShields > 0) {
await prisma.$transaction([
prisma.user.update({
where: { id: user.id },
data: { streakShields: { decrement: 1 } },
}),
prisma.streak.create({
data: {
id: `streak_${createId()}`,
type: 'shielded',
userId: user.id,
createdAt: yesterdayEnd.toDate(),
},
}),
]);
if (user.notificationToken) {
await onesignal.createNotification({
app_id: process.env.ONESIGNAL_APP_ID,
name: 'Streak Shield Used Notification',
contents: {
en: 'Your streak is safe thanks to the Streak Shield! Keep up the great work by completing a lesson today.',
},
headings: {
en: 'Your streak was saved by Streak Shield! 😊',
},
include_subscription_ids: [user.notificationToken],
large_icon:
'https://cdn.voicelearn.tech/image-removebg-preview%20(1).png',
});
}
} else {
if (
createdAt.isBetween(
userLocalTime.clone().subtract(2, 'day').startOf('day'),
userLocalTime.clone().subtract(2, 'day').endOf('day'),
)
) {
await prisma.user.update({
where: { id: user.id },
data: { activeStreaks: 0 },
});
if (user.notificationToken) {
await onesignal.createNotification({
app_id: process.env.ONESIGNAL_APP_ID,
name: 'Streak Reset Notification',
headings: {
en: 'Your streak was reset πŸ’€',
},
contents: {
en: 'Try not to skip more lessons.',
},
include_subscription_ids: [user.notificationToken],
large_icon:
'https://cdn.voicelearn.tech/image-removebg-preview.png',
});
}
}
}
}
} else if (
(userLocalTime.hour() === 20 || userLocalTime.hour() === 22) &&
userLocalTime.minute() === 0
) {
const createdAt = moment(lastStreakRecord.createdAt).tz(
IANATimezones[user.timezone],
);
const isWithinRange = createdAt.isBetween(
userLocalTime.clone().startOf('day'),
userLocalTime,
null,
'[]',
);
if (!isWithinRange && user.notificationToken) {
await onesignal.createNotification({
app_id: process.env.ONESIGNAL_APP_ID,
name: 'Streak Reminder',
contents: {
en: `Your streak is about to reset in ${userLocalTime.hour() === 20 ? '4' : '2'} hours. Complete a lesson now.`,
},
headings: {
en: `⚠️ Streak about to reset`,
},
include_subscription_ids: [user.notificationToken],
large_icon:
'https://cdn.voicelearn.tech/image-removebg-preview.png',
});
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment