Skip to content

Commit 03e7350

Browse files
committed
feat(checker): add next due date and add checker
1 parent f59515c commit 03e7350

File tree

3 files changed

+20
-64
lines changed

3 files changed

+20
-64
lines changed

src/bot/index.ts

Lines changed: 18 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { statsCommand } from "./commands/stats.ts";
77
import { registrationWizard } from "./scenes/registration.ts";
88
import { getUserLeetcodeInfo } from "../modules/leetcode.ts";
99
import { User } from "../types/index.ts";
10-
import { Update } from "npm:telegraf/types";
10+
import { CallbackQuery, Update } from "npm:telegraf/types";
1111

1212
export class LeetCodeBot {
1313
private bot: Telegraf;
@@ -28,6 +28,9 @@ export class LeetCodeBot {
2828

2929
// Set up error handling
3030
this.setupErrorHandling();
31+
32+
// Setup checker
33+
this.setupChecker();
3134
}
3235

3336
private setupMiddleware() {
@@ -48,65 +51,27 @@ export class LeetCodeBot {
4851
}
4952

5053
private registerCommands() {
51-
this.bot.command('start', (ctx) => (ctx as never as Scenes.SceneContext).scene.enter('registration-wizard'));
52-
this.bot.command('help', helpCommand);
54+
this.bot.command('start', (ctx) => (ctx as unknown as Scenes.SceneContext).scene.enter('registration-wizard'));
5355

54-
this.bot.command('stats', statsCommand);
56+
// TODO add skip command
57+
// TODO add reschedule logic
5558

56-
// Schedule command
57-
this.bot.command('schedule', async (ctx) => {
58-
const userId = ctx.from?.id;
59-
if (!userId) return;
60-
61-
try {
62-
await ctx.reply(
63-
"How often would you like to solve problems?",
64-
{
65-
reply_markup: {
66-
inline_keyboard: [
67-
[
68-
{ text: "Daily", callback_data: "schedule_1" },
69-
{ text: "Every 2 days", callback_data: "schedule_2" }
70-
],
71-
[
72-
{ text: "Every 3 days", callback_data: "schedule_3" },
73-
{ text: "Weekly", callback_data: "schedule_7" }
74-
]
75-
]
76-
}
77-
}
78-
);
79-
} catch (error) {
80-
console.error('Error in schedule command:', error);
81-
await ctx.reply('Sorry, something went wrong. Please try again.');
82-
}
83-
});
59+
this.bot.command('help', helpCommand);
60+
this.bot.command('stats', statsCommand);
8461

8562
this.bot.on("callback_query", async (ctx) => {
86-
const command = (ctx.callbackQuery as any).data;
87-
console.log(command)
63+
const command = (ctx.callbackQuery as unknown as CallbackQuery.DataQuery).data;
8864

89-
// Acknowledge the callback to remove the "loading" spinner.
9065
await ctx.answerCbQuery();
9166

92-
// Check if command exists, then call the appropriate command function.
9367
switch (command) {
9468
case "/start":
95-
// await startCommand(ctx);
69+
await (ctx as never as Scenes.SceneContext).scene.enter('registration-wizard');
9670
break;
9771
case "/help":
9872
await helpCommand(ctx);
9973
break;
100-
// Add more cases for each command you support.
101-
// For example:
102-
// case "/status":
103-
// await statusCommand(ctx);
104-
// break;
105-
// case "/schedule":
106-
// await scheduleCommand(ctx);
107-
// break;
10874
default:
109-
// Inform the user if the command is unknown.
11075
await ctx.reply("Unknown command. Please use /help to see available commands.");
11176
}
11277
});
@@ -120,27 +85,17 @@ export class LeetCodeBot {
12085
}
12186

12287
private setupChecker() {
123-
const DAY = 24 * 60 * 60 * 1000;
88+
const HOUR = 60 * 60 * 1000;
12489

12590
setInterval(async () => {
126-
const users = await this.userRepo.collection.find({ frequency: 1 }).toArray();
127-
128-
for (const user of users) {
129-
await this.checkUser(user);
130-
}
131-
}, DAY);
132-
133-
setInterval(async () => {
134-
const users = await this.userRepo.collection.find({ frequency: 7 }).toArray();
135-
136-
for (const user of users) {
137-
await this.checkUser(user);
138-
}
139-
}, DAY);
91+
const users = await this.userRepo.collection.find().toArray();
92+
for (const user of users) await this.checkUser(user);
93+
}, HOUR);
14094
}
14195

14296
private async checkUser(user: User) {
14397
try {
98+
if (user.nextDueDate && Date.now() < user.nextDueDate.getTime()) return;
14499

145100
const updatedInfo = await getUserLeetcodeInfo(user.leetcodeUsername).catch(() => null);
146101
if (!updatedInfo) return; // Optionally handle later
@@ -178,15 +133,14 @@ export class LeetCodeBot {
178133
);
179134
}
180135

181-
182136
await this.userRepo.update(user.telegramId, {
183137
stats: {
184138
totalSolved: allSubmissions.count,
185139
streakCount: user.stats.streakCount + 1
186140
},
187-
updatedAt: new Date()
141+
updatedAt: new Date(),
142+
nextDueDate: new Date(Date.now() + (user.frequency * 24 * 60 * 60_000))
188143
})
189-
190144
} catch (error) {
191145
console.error("Error during daily check:", error);
192146
}

src/bot/scenes/registration.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ export const registrationWizard = new Scenes.WizardScene<MyContext>(
192192
frequency,
193193
tasksCount,
194194
stats: { streakCount: 0, totalSolved: allSubmissions?.count ?? 0 },
195+
nextDueDate: new Date(Date.now() + (frequency * 24 * 60 * 60_000))
195196
};
196197

197198
try {

src/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export interface User {
2929

3030
createdAt: Date; // Registration date
3131
updatedAt: Date; // Used to update the last time leetcode stats were fetched
32+
nextDueDate: Date; // The date which until which the taskCount should be updated
3233
}
3334

3435
export type UserInput = Omit<User, 'createdAt' | 'updatedAt'>;

0 commit comments

Comments
 (0)