Add scheduled app update checks and notifications

Introduces a scheduled task that checks for apps not updated within a warning threshold and sends notifications to groups. Adds scheduling utilities, constants for scheduling, and logic to format and send update reports for both Apple and Google apps. Also includes a new NonUpdatedApp record and improvements to the Table class for better formatting.
This commit is contained in:
2025-11-07 23:45:30 +07:00
parent 77f4e08946
commit 7349501086
6 changed files with 157 additions and 1 deletions
@@ -1,5 +1,8 @@
package com.miti99.storescraperbot;
import static com.miti99.storescraperbot.constant.Constant.SCHEDULE_CHECK_APP_TIME;
import static com.miti99.storescraperbot.constant.Constant.SECONDS_PER_DAY;
import static com.miti99.storescraperbot.constant.Constant.VIETNAM_ZONE_ID;
import static com.miti99.storescraperbot.env.Environment.CREATOR_ID;
import static com.miti99.storescraperbot.env.Environment.SOURCE_COMMIT;
@@ -8,6 +11,12 @@ import com.miti99.storescraperbot.bot.StoreScrapeBotTelegramClient;
import com.miti99.storescraperbot.env.Environment;
import com.miti99.storescraperbot.repository.AdminRepository;
import com.miti99.storescraperbot.type.Env;
import com.miti99.storescraperbot.util.SchedulerUtil;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.concurrent.TimeUnit;
import lombok.extern.log4j.Log4j2;
import org.telegram.telegrambots.longpolling.TelegramBotsLongPollingApplication;
@@ -24,9 +33,26 @@ public class Main {
StoreScrapeBotTelegramClient.INSTANCE.sendMessage(
CREATOR_ID, "Bot started! Version <code>%s</code>".formatted(SOURCE_COMMIT));
}
scheduleCheckApp();
Thread.currentThread().join();
} catch (Exception e) {
log.error("Error while running bot", e);
}
}
private static void scheduleCheckApp() {
var now = LocalDateTime.now();
var checkTime =
LocalDateTime.of(LocalDate.now(VIETNAM_ZONE_ID), SCHEDULE_CHECK_APP_TIME)
.atZone(VIETNAM_ZONE_ID)
.withZoneSameInstant(ZoneId.systemDefault())
.toLocalDateTime();
long initialDelay = Duration.between(now, checkTime).getSeconds();
if (initialDelay < 0) {
initialDelay += SECONDS_PER_DAY;
}
SchedulerUtil.SCHEDULER.scheduleAtFixedRate(
StoreScrapeBot.INSTANCE::runCheckApp, initialDelay, SECONDS_PER_DAY, TimeUnit.SECONDS);
}
}