From 22d5298ffa2a3c935ba67ceb0f12920c185f230b Mon Sep 17 00:00:00 2001 From: Thomas Edwin Santosa Date: Fri, 7 Mar 2025 20:05:12 +0700 Subject: [PATCH 1/4] Initial telegram start and stop --- .gitignore | 2 + build.gradle.kts | 4 ++ .../banyuwangi/AppProperties.kt | 2 + .../banyuwangi/model/TelegramChat.kt | 11 ++++ .../banyuwangi/repo/TelegramChatRepo.kt | 12 ++++ .../banyuwangi/service/AlarmService.kt | 2 + .../banyuwangi/service/TelegramService.kt | 64 +++++++++++++++++++ .../banyuwangi/service/TelegramServiceTest.kt | 49 ++++++++++++++ 8 files changed, 146 insertions(+) create mode 100644 src/main/kotlin/com/katalisindonesia/banyuwangi/model/TelegramChat.kt create mode 100644 src/main/kotlin/com/katalisindonesia/banyuwangi/repo/TelegramChatRepo.kt create mode 100644 src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt create mode 100644 src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt diff --git a/.gitignore b/.gitignore index 5a3d098..a49ee55 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,5 @@ out/ *.lock.db src/main/resources/banyuwangi-dashboard-firebase-adminsdk.json +.env +.env.* diff --git a/build.gradle.kts b/build.gradle.kts index 095d78f..5dc2553 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,6 +13,7 @@ plugins { id("org.springdoc.openapi-gradle-plugin") version "1.8.0" id("org.gradle.test-retry") version "1.5.9" + id("co.uzzu.dotenv.gradle") version "4.0.0" } val buildId = System.getenv("GITHUB_RUN_NUMBER") ?: System.getenv("BUILD_ID") ?: "1-SNAPSHOT" @@ -122,6 +123,8 @@ dependencies { // Firebase cloud messaging implementation("com.google.firebase:firebase-admin:9.1.1") + + implementation("io.github.kotlin-telegram-bot.kotlin-telegram-bot:telegram:6.3.0") } tasks.withType { @@ -135,6 +138,7 @@ tasks.withType { useJUnitPlatform() enableAssertions = true // setForkEvery(1L) + environment(env.allVariables()) retry { if (!buildId.contains("SNAPSHOT")) { maxRetries.set(3) diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/AppProperties.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/AppProperties.kt index c68eb02..024b65b 100644 --- a/src/main/kotlin/com/katalisindonesia/banyuwangi/AppProperties.kt +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/AppProperties.kt @@ -40,4 +40,6 @@ data class AppProperties( val alarmHighMessages: Map, val fcmRateLimit: Double, + + val telegramToken: String, ) diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/model/TelegramChat.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/model/TelegramChat.kt new file mode 100644 index 0000000..3bf69a0 --- /dev/null +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/model/TelegramChat.kt @@ -0,0 +1,11 @@ +package com.katalisindonesia.banyuwangi.model + +import javax.persistence.Column +import javax.persistence.Entity + +@Entity +class TelegramChat( + @Column(unique = true) + val chatId: Long, +) : Persistent() { +} diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/repo/TelegramChatRepo.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/repo/TelegramChatRepo.kt new file mode 100644 index 0000000..32c27f7 --- /dev/null +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/repo/TelegramChatRepo.kt @@ -0,0 +1,12 @@ +package com.katalisindonesia.banyuwangi.repo + +import com.katalisindonesia.banyuwangi.model.TelegramChat +import org.springframework.stereotype.Repository +import org.springframework.transaction.annotation.Transactional +import java.util.UUID + +@Repository +interface TelegramChatRepo: BaseRepository { + @Transactional + fun deleteByChatId(chatId: Long): Int +} diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/service/AlarmService.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/AlarmService.kt index 4842999..4f977b9 100644 --- a/src/main/kotlin/com/katalisindonesia/banyuwangi/service/AlarmService.kt +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/AlarmService.kt @@ -89,6 +89,8 @@ class AlarmService( rateLimit.acquire() firebaseMessaging.send(message) + + // todo send telegram } private fun titleBody(alarm: Alarm): TitleBody { diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt new file mode 100644 index 0000000..3519db4 --- /dev/null +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt @@ -0,0 +1,64 @@ +package com.katalisindonesia.banyuwangi.service + +import com.github.kotlintelegrambot.bot +import com.github.kotlintelegrambot.dispatch +import com.github.kotlintelegrambot.dispatcher.command +import com.github.kotlintelegrambot.dispatcher.telegramError +import com.github.kotlintelegrambot.entities.ChatId +import com.github.kotlintelegrambot.logging.LogLevel +import com.katalisindonesia.banyuwangi.AppProperties +import com.katalisindonesia.banyuwangi.model.TelegramChat +import com.katalisindonesia.banyuwangi.repo.TelegramChatRepo +import mu.KotlinLogging +import org.springframework.dao.DataIntegrityViolationException +import org.springframework.stereotype.Service +import javax.annotation.PostConstruct + +private val log = KotlinLogging.logger { } + +@Service +class TelegramService ( + private val appProperties: AppProperties, + private val telegramChatRepo: TelegramChatRepo, +){ + + private val bot = bot { + token = appProperties.telegramToken + timeout = 30 + logLevel = LogLevel.Network.Body + + dispatch { + command("start") { + bot.sendMessage(chatId = ChatId.fromId(update.message!!.chat.id), text = """/start Berlangganan peringatan + |/stop Stop peringatan + """.trimMargin()) + } + + telegramError { + log.error { error.getErrorMessage() } + } + } + } + + fun start(chatId: ChatId.Id) { + val chat = TelegramChat(chatId.id) + try { + telegramChatRepo.saveAndFlush(chat) + bot.sendMessage(chatId = chatId, text = "Berlangganan peringatan") + } catch (e: DataIntegrityViolationException) { + log.debug(e) {"Duplicate subscription: "+chatId.id} + bot.sendMessage(chatId = chatId, text = "Anda sudah berlangganan") + } + } + + fun stop(chatId: ChatId.Id) { + telegramChatRepo.deleteByChatId(chatId.id) + bot.sendMessage(chatId = chatId, text = "Berhenti berlangganan peringatan") + } + + + @PostConstruct + fun init() { + bot.startPolling() + } +} diff --git a/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt b/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt new file mode 100644 index 0000000..c2ccefd --- /dev/null +++ b/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt @@ -0,0 +1,49 @@ +package com.katalisindonesia.banyuwangi.service + +import com.github.kotlintelegrambot.entities.ChatId +import com.katalisindonesia.banyuwangi.repo.TelegramChatRepo +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.ActiveProfiles +import org.springframework.test.context.junit.jupiter.SpringExtension + +@SpringBootTest +@ExtendWith(SpringExtension::class) +@ActiveProfiles("default", "secret") +class TelegramServiceTest( + @Autowired + private val telegramService: TelegramService, + @Autowired + private val telegramChatRepo: TelegramChatRepo, +) { + @Test + fun test_start_stop() { + telegramService.start(ChatId.fromId(10)) + + assertEquals(1, telegramChatRepo.findAll().size) + + // duplicate + telegramService.start(ChatId.fromId(10)) + assertEquals(1, telegramChatRepo.findAll().size) + + // different + telegramService.start(ChatId.fromId(11)) + assertEquals(2, telegramChatRepo.findAll().size) + + // stop + telegramService.stop(ChatId.fromId(11)) + assertEquals(1, telegramChatRepo.findAll().size) + + // duplicate stop + telegramService.stop(ChatId.fromId(11)) + assertEquals(1, telegramChatRepo.findAll().size) + + // all stop + telegramService.stop(ChatId.fromId(10)) + assertEquals(0, telegramChatRepo.findAll().size) + } + +} From 282f92f0834725003d7a0b3e723c4328fb6970f9 Mon Sep 17 00:00:00 2001 From: Thomas Edwin Santosa Date: Sat, 8 Mar 2025 10:05:24 +0700 Subject: [PATCH 2/4] detekt --- .../banyuwangi/model/TelegramChat.kt | 3 +-- .../banyuwangi/repo/TelegramChatRepo.kt | 2 +- .../banyuwangi/service/TelegramService.kt | 18 +++++++++--------- .../banyuwangi/service/TelegramServiceTest.kt | 1 - 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/model/TelegramChat.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/model/TelegramChat.kt index 3bf69a0..905ce08 100644 --- a/src/main/kotlin/com/katalisindonesia/banyuwangi/model/TelegramChat.kt +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/model/TelegramChat.kt @@ -7,5 +7,4 @@ import javax.persistence.Entity class TelegramChat( @Column(unique = true) val chatId: Long, -) : Persistent() { -} +) : Persistent() diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/repo/TelegramChatRepo.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/repo/TelegramChatRepo.kt index 32c27f7..c407267 100644 --- a/src/main/kotlin/com/katalisindonesia/banyuwangi/repo/TelegramChatRepo.kt +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/repo/TelegramChatRepo.kt @@ -6,7 +6,7 @@ import org.springframework.transaction.annotation.Transactional import java.util.UUID @Repository -interface TelegramChatRepo: BaseRepository { +interface TelegramChatRepo : BaseRepository { @Transactional fun deleteByChatId(chatId: Long): Int } diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt index 3519db4..acb40f6 100644 --- a/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt @@ -14,13 +14,13 @@ import org.springframework.dao.DataIntegrityViolationException import org.springframework.stereotype.Service import javax.annotation.PostConstruct -private val log = KotlinLogging.logger { } +private val log = KotlinLogging.logger { } @Service -class TelegramService ( - private val appProperties: AppProperties, +class TelegramService( + private val appProperties: AppProperties, private val telegramChatRepo: TelegramChatRepo, -){ +) { private val bot = bot { token = appProperties.telegramToken @@ -29,9 +29,10 @@ class TelegramService ( dispatch { command("start") { - bot.sendMessage(chatId = ChatId.fromId(update.message!!.chat.id), text = """/start Berlangganan peringatan - |/stop Stop peringatan - """.trimMargin()) + bot.sendMessage( + chatId = ChatId.fromId(update.message!!.chat.id), + text = "/start Berlangganan peringatan\n/stop Stop peringatan" + ) } telegramError { @@ -46,7 +47,7 @@ class TelegramService ( telegramChatRepo.saveAndFlush(chat) bot.sendMessage(chatId = chatId, text = "Berlangganan peringatan") } catch (e: DataIntegrityViolationException) { - log.debug(e) {"Duplicate subscription: "+chatId.id} + log.debug(e) { "Duplicate subscription: " + chatId.id } bot.sendMessage(chatId = chatId, text = "Anda sudah berlangganan") } } @@ -56,7 +57,6 @@ class TelegramService ( bot.sendMessage(chatId = chatId, text = "Berhenti berlangganan peringatan") } - @PostConstruct fun init() { bot.startPolling() diff --git a/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt b/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt index c2ccefd..980fc7f 100644 --- a/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt +++ b/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt @@ -45,5 +45,4 @@ class TelegramServiceTest( telegramService.stop(ChatId.fromId(10)) assertEquals(0, telegramChatRepo.findAll().size) } - } From 774c8b132c61cba7446ed84f7a3e0437d3aaf71c Mon Sep 17 00:00:00 2001 From: Thomas Edwin Santosa Date: Sat, 8 Mar 2025 10:41:45 +0700 Subject: [PATCH 3/4] Implemented telegram alarm --- .../banyuwangi/AppProperties.kt | 1 + .../banyuwangi/consumer/TriggerConsumer.kt | 3 + .../banyuwangi/service/AlarmService.kt | 21 +---- .../banyuwangi/service/Alarms.kt | 21 +++++ .../banyuwangi/service/TelegramService.kt | 55 +++++++++-- .../banyuwangi/service/TelegramServiceTest.kt | 93 ++++++++++++++++++- 6 files changed, 166 insertions(+), 28 deletions(-) create mode 100644 src/main/kotlin/com/katalisindonesia/banyuwangi/service/Alarms.kt diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/AppProperties.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/AppProperties.kt index 024b65b..7bcb630 100644 --- a/src/main/kotlin/com/katalisindonesia/banyuwangi/AppProperties.kt +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/AppProperties.kt @@ -42,4 +42,5 @@ data class AppProperties( val fcmRateLimit: Double, val telegramToken: String, + val telegramRateLimit: Double = 30.0, ) diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/consumer/TriggerConsumer.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/consumer/TriggerConsumer.kt index cd63d19..30f3a54 100644 --- a/src/main/kotlin/com/katalisindonesia/banyuwangi/consumer/TriggerConsumer.kt +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/consumer/TriggerConsumer.kt @@ -5,6 +5,7 @@ import com.katalisindonesia.banyuwangi.model.SnapshotCount import com.katalisindonesia.banyuwangi.repo.AlarmRepo import com.katalisindonesia.banyuwangi.repo.SnapshotCountRepo import com.katalisindonesia.banyuwangi.service.AlarmService +import com.katalisindonesia.banyuwangi.service.TelegramService import org.springframework.amqp.rabbit.annotation.RabbitListener import org.springframework.stereotype.Service import org.springframework.transaction.PlatformTransactionManager @@ -16,6 +17,7 @@ class TriggerConsumer( private val alarmService: AlarmService, private val snapshotCountRepo: SnapshotCountRepo, transactionManager: PlatformTransactionManager, + private val telegramService: TelegramService, ) { private val tt = TransactionTemplate(transactionManager) @@ -42,6 +44,7 @@ class TriggerConsumer( alarm1 }!! alarmService.sendAlarm(alarm) + telegramService.sendAlarm(alarm) } } } diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/service/AlarmService.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/AlarmService.kt index 4f977b9..5fbfbd9 100644 --- a/src/main/kotlin/com/katalisindonesia/banyuwangi/service/AlarmService.kt +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/AlarmService.kt @@ -36,7 +36,7 @@ class AlarmService( fun sendAlarm(alarm: Alarm) { val type = alarm.snapshotCount.type - val titleBody = titleBody(alarm) + val titleBody = titleBody(alarm, appProperties) val title = MessageFormat.format( titleBody.title ?: "", type.localizedName(), alarm.snapshotCount.snapshotCameraName @@ -92,26 +92,9 @@ class AlarmService( // todo send telegram } - - private fun titleBody(alarm: Alarm): TitleBody { - val type = alarm.snapshotCount.type - val value = alarm.snapshotCount.value - val minHighValue = appProperties.alarmHighMinimalValues[type] - - if (minHighValue != null && value >= minHighValue) { - return TitleBody( - title = appProperties.alarmHighTitles[type] ?: appProperties.alarmTitles[type], - body = appProperties.alarmHighMessages[type] ?: appProperties.alarmMessages[type], - ) - } - return TitleBody( - title = appProperties.alarmTitles[type], - body = appProperties.alarmMessages[type], - ) - } } -private data class TitleBody( +data class TitleBody( val title: String?, val body: String?, ) diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/service/Alarms.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/Alarms.kt new file mode 100644 index 0000000..5dcef27 --- /dev/null +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/Alarms.kt @@ -0,0 +1,21 @@ +package com.katalisindonesia.banyuwangi.service + +import com.katalisindonesia.banyuwangi.AppProperties +import com.katalisindonesia.banyuwangi.model.Alarm + +fun titleBody(alarm: Alarm, appProperties: AppProperties): TitleBody { + val type = alarm.snapshotCount.type + val value = alarm.snapshotCount.value + val minHighValue = appProperties.alarmHighMinimalValues[type] + + if (minHighValue != null && value >= minHighValue) { + return TitleBody( + title = appProperties.alarmHighTitles[type] ?: appProperties.alarmTitles[type], + body = appProperties.alarmHighMessages[type] ?: appProperties.alarmMessages[type], + ) + } + return TitleBody( + title = appProperties.alarmTitles[type], + body = appProperties.alarmMessages[type], + ) +} diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt index acb40f6..786625c 100644 --- a/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt @@ -5,13 +5,19 @@ import com.github.kotlintelegrambot.dispatch import com.github.kotlintelegrambot.dispatcher.command import com.github.kotlintelegrambot.dispatcher.telegramError import com.github.kotlintelegrambot.entities.ChatId +import com.github.kotlintelegrambot.entities.TelegramFile import com.github.kotlintelegrambot.logging.LogLevel +import com.google.common.util.concurrent.RateLimiter import com.katalisindonesia.banyuwangi.AppProperties +import com.katalisindonesia.banyuwangi.model.Alarm import com.katalisindonesia.banyuwangi.model.TelegramChat import com.katalisindonesia.banyuwangi.repo.TelegramChatRepo +import com.katalisindonesia.imageserver.service.StorageService import mu.KotlinLogging import org.springframework.dao.DataIntegrityViolationException +import org.springframework.retry.support.RetryTemplate import org.springframework.stereotype.Service +import java.text.MessageFormat import javax.annotation.PostConstruct private val log = KotlinLogging.logger { } @@ -20,7 +26,11 @@ private val log = KotlinLogging.logger { } class TelegramService( private val appProperties: AppProperties, private val telegramChatRepo: TelegramChatRepo, + private val storageService: StorageService, ) { + private val rateLimit = RateLimiter.create(appProperties.telegramRateLimit) + + private val rt = RetryTemplate.builder().maxAttempts(10).exponentialBackoff(100L, 1.2, 10000L).build() private val bot = bot { token = appProperties.telegramToken @@ -29,10 +39,11 @@ class TelegramService( dispatch { command("start") { - bot.sendMessage( - chatId = ChatId.fromId(update.message!!.chat.id), - text = "/start Berlangganan peringatan\n/stop Stop peringatan" - ) + start(ChatId.fromId(update.message!!.chat.id)) + } + + command("stop") { + stop(ChatId.fromId(update.message!!.chat.id)) } telegramError { @@ -45,7 +56,11 @@ class TelegramService( val chat = TelegramChat(chatId.id) try { telegramChatRepo.saveAndFlush(chat) - bot.sendMessage(chatId = chatId, text = "Berlangganan peringatan") + bot.sendMessage( + chatId = chatId, + text = "Anda telah berlangganan peringatan.\n\n" + + "/stop untuk berhenti berlangganan" + ) } catch (e: DataIntegrityViolationException) { log.debug(e) { "Duplicate subscription: " + chatId.id } bot.sendMessage(chatId = chatId, text = "Anda sudah berlangganan") @@ -54,11 +69,39 @@ class TelegramService( fun stop(chatId: ChatId.Id) { telegramChatRepo.deleteByChatId(chatId.id) - bot.sendMessage(chatId = chatId, text = "Berhenti berlangganan peringatan") + bot.sendMessage( + chatId = chatId, + text = "Anda telah berhenti berlangganan.\n\n" + + "/start untuk berlangganan peringatan" + ) } @PostConstruct fun init() { bot.startPolling() } + + fun sendAlarm(alarm: Alarm) { + val type = alarm.snapshotCount.type + + val titleBody = titleBody(alarm, appProperties) + val title = + MessageFormat.format( + titleBody.title ?: "", type.localizedName(), alarm.snapshotCount.snapshotCameraName + ) + val body = titleBody.body ?: "" + val media = TelegramFile.ByFile(storageService.file(alarm.snapshotCount.snapshotImageId)) + + val chats = telegramChatRepo.findAll() + for (chat in chats) { + rateLimit.acquire() + rt.execute { + bot.sendPhoto( + ChatId.fromId(chat.chatId), media, + caption = "$title\n\n$body\n\n" + + "/stop untuk berhenti berlangganan" + ) + } + } + } } diff --git a/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt b/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt index 980fc7f..c45cd2b 100644 --- a/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt +++ b/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt @@ -1,14 +1,24 @@ package com.katalisindonesia.banyuwangi.service import com.github.kotlintelegrambot.entities.ChatId +import com.katalisindonesia.banyuwangi.model.Alarm +import com.katalisindonesia.banyuwangi.model.Camera +import com.katalisindonesia.banyuwangi.model.DetectionType +import com.katalisindonesia.banyuwangi.model.Snapshot +import com.katalisindonesia.banyuwangi.model.SnapshotCount import com.katalisindonesia.banyuwangi.repo.TelegramChatRepo +import com.katalisindonesia.imageserver.service.StorageService import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest +import org.springframework.core.io.ClassPathResource import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.junit.jupiter.SpringExtension +import java.time.ZoneId +import java.time.ZonedDateTime +import java.util.UUID @SpringBootTest @ExtendWith(SpringExtension::class) @@ -18,6 +28,8 @@ class TelegramServiceTest( private val telegramService: TelegramService, @Autowired private val telegramChatRepo: TelegramChatRepo, + @Autowired + private val storageService: StorageService, ) { @Test fun test_start_stop() { @@ -30,19 +42,94 @@ class TelegramServiceTest( assertEquals(1, telegramChatRepo.findAll().size) // different - telegramService.start(ChatId.fromId(11)) + telegramService.start(ChatId.fromId(59573981)) assertEquals(2, telegramChatRepo.findAll().size) // stop - telegramService.stop(ChatId.fromId(11)) + telegramService.stop(ChatId.fromId(59573981)) assertEquals(1, telegramChatRepo.findAll().size) // duplicate stop - telegramService.stop(ChatId.fromId(11)) + telegramService.stop(ChatId.fromId(59573981)) assertEquals(1, telegramChatRepo.findAll().size) // all stop telegramService.stop(ChatId.fromId(10)) assertEquals(0, telegramChatRepo.findAll().size) } + + @Test + fun sendAlarm() { + telegramService.start(ChatId.fromId(59573981)) + val camera0 = Camera(name = "camera0", location = "") + + val snapshot0 = Snapshot(imageId = imageId(), camera = camera0, length = 0, isAnnotation = true) + + val base = ZonedDateTime.of(1970, 1, 1, 7, 0, 0, 0, ZoneId.systemDefault()).toInstant() + snapshot0.created = base.plusMillis(2100) + + val count0 = SnapshotCount( + snapshot = snapshot0, + type = DetectionType.CROWD, + value = 2, + ) + telegramService.sendAlarm( + Alarm( + maxValue = 1, + snapshotCount = count0, + ) + ) + telegramService.stop(ChatId.fromId(59573981)) + } + @Test + fun sendAlarmFloodHigh() { + telegramService.start(ChatId.fromId(59573981)) + val camera0 = Camera(name = "camera0", location = "") + + val snapshot0 = Snapshot(imageId = imageId(), camera = camera0, length = 0, isAnnotation = true) + + val base = ZonedDateTime.of(1970, 1, 1, 7, 0, 0, 0, ZoneId.systemDefault()).toInstant() + snapshot0.created = base.plusMillis(2100) + + val count0 = SnapshotCount( + snapshot = snapshot0, + type = DetectionType.FLOOD, + value = 100, + ) + telegramService.sendAlarm( + Alarm( + maxValue = 1, + snapshotCount = count0, + ) + ) + telegramService.stop(ChatId.fromId(59573981)) + } + @Test + fun sendAlarmFloodLow() { + telegramService.start(ChatId.fromId(59573981)) + val camera0 = Camera(name = "camera0", location = "") + + val snapshot0 = Snapshot(imageId = imageId(), camera = camera0, length = 0, isAnnotation = true) + + val base = ZonedDateTime.of(1970, 1, 1, 7, 0, 0, 0, ZoneId.systemDefault()).toInstant() + snapshot0.created = base.plusMillis(2100) + + val count0 = SnapshotCount( + snapshot = snapshot0, + type = DetectionType.FLOOD, + value = 1, + ) + telegramService.sendAlarm( + Alarm( + maxValue = 1, + snapshotCount = count0, + ) + ) + telegramService.stop(ChatId.fromId(59573981)) + } + + private fun imageId(): UUID { + val imageId = storageService.store(ClassPathResource("dog_bike_car.jpg").inputStream.readAllBytes()) + return imageId + } } From fe095e41225185ef2c805f38d19c59a7b5267cbb Mon Sep 17 00:00:00 2001 From: Thomas Edwin Santosa Date: Sat, 8 Mar 2025 10:42:14 +0700 Subject: [PATCH 4/4] Fix todo --- .../com/katalisindonesia/banyuwangi/service/AlarmService.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/service/AlarmService.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/AlarmService.kt index 5fbfbd9..8c4ba23 100644 --- a/src/main/kotlin/com/katalisindonesia/banyuwangi/service/AlarmService.kt +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/AlarmService.kt @@ -89,8 +89,6 @@ class AlarmService( rateLimit.acquire() firebaseMessaging.send(message) - - // todo send telegram } }