diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/model/TelegramChat.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/model/TelegramChat.kt index 905ce08..87d817f 100644 --- a/src/main/kotlin/com/katalisindonesia/banyuwangi/model/TelegramChat.kt +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/model/TelegramChat.kt @@ -2,9 +2,25 @@ package com.katalisindonesia.banyuwangi.model import javax.persistence.Column import javax.persistence.Entity +import javax.persistence.EnumType +import javax.persistence.Enumerated +import javax.persistence.Table +import javax.persistence.UniqueConstraint @Entity +@Table( + uniqueConstraints = [ + UniqueConstraint( + name = "telegram_chat_chatid_detectiontype_key", + columnNames = ["chatId", "detectionType"] + ) + ] +) class TelegramChat( - @Column(unique = true) + @Column(unique = true, nullable = false) val chatId: Long, + + @Column(nullable = false) + @Enumerated(EnumType.STRING) + var detectionType: DetectionType?, ) : Persistent() diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/repo/TelegramChatRepo.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/repo/TelegramChatRepo.kt index c407267..a3ca5bd 100644 --- a/src/main/kotlin/com/katalisindonesia/banyuwangi/repo/TelegramChatRepo.kt +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/repo/TelegramChatRepo.kt @@ -1,5 +1,6 @@ package com.katalisindonesia.banyuwangi.repo +import com.katalisindonesia.banyuwangi.model.DetectionType import com.katalisindonesia.banyuwangi.model.TelegramChat import org.springframework.stereotype.Repository import org.springframework.transaction.annotation.Transactional @@ -8,5 +9,7 @@ import java.util.UUID @Repository interface TelegramChatRepo : BaseRepository { @Transactional - fun deleteByChatId(chatId: Long): Int + fun deleteByChatIdAndDetectionType(chatId: Long, detectionType: DetectionType): Int + + fun findByDetectionType(detectionType: DetectionType): List } diff --git a/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt index 786625c..af7a344 100644 --- a/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt +++ b/src/main/kotlin/com/katalisindonesia/banyuwangi/service/TelegramService.kt @@ -2,14 +2,18 @@ package com.katalisindonesia.banyuwangi.service import com.github.kotlintelegrambot.bot import com.github.kotlintelegrambot.dispatch +import com.github.kotlintelegrambot.dispatcher.callbackQuery import com.github.kotlintelegrambot.dispatcher.command import com.github.kotlintelegrambot.dispatcher.telegramError import com.github.kotlintelegrambot.entities.ChatId +import com.github.kotlintelegrambot.entities.InlineKeyboardMarkup import com.github.kotlintelegrambot.entities.TelegramFile +import com.github.kotlintelegrambot.entities.keyboard.InlineKeyboardButton 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.DetectionType import com.katalisindonesia.banyuwangi.model.TelegramChat import com.katalisindonesia.banyuwangi.repo.TelegramChatRepo import com.katalisindonesia.imageserver.service.StorageService @@ -38,12 +42,46 @@ class TelegramService( logLevel = LogLevel.Network.Body dispatch { + DetectionType.values().forEach { + callbackQuery("start${it.name}") { + start(ChatId.fromId(update.message!!.chat.id), it) + } + callbackQuery("stop${it.name}") { + stop(ChatId.fromId(update.message!!.chat.id), it) + } + } command("start") { - start(ChatId.fromId(update.message!!.chat.id)) + val list = DetectionType.values().map { + listOf( + InlineKeyboardButton.CallbackData( + text = it.localizedName(), + callbackData = "start${it.name}" + ) + ) + } + val inlineKeyboardMarkup = InlineKeyboardMarkup.create(list.toList()) + bot.sendMessage( + chatId = ChatId.fromId(message.chat.id), + text = "Mau berlangganan peringatan apa?", + replyMarkup = inlineKeyboardMarkup, + ) } command("stop") { - stop(ChatId.fromId(update.message!!.chat.id)) + val list = DetectionType.values().map { + listOf( + InlineKeyboardButton.CallbackData( + text = it.localizedName(), + callbackData = "stop${it.name}" + ) + ) + } + val inlineKeyboardMarkup = InlineKeyboardMarkup.create(list.toList()) + bot.sendMessage( + chatId = ChatId.fromId(message.chat.id), + text = "Mau hentikan peringatan apa?", + replyMarkup = inlineKeyboardMarkup, + ) } telegramError { @@ -52,14 +90,14 @@ class TelegramService( } } - fun start(chatId: ChatId.Id) { - val chat = TelegramChat(chatId.id) + fun start(chatId: ChatId.Id, detectionType: DetectionType) { + val chat = TelegramChat(chatId.id, detectionType) try { telegramChatRepo.saveAndFlush(chat) bot.sendMessage( chatId = chatId, - text = "Anda telah berlangganan peringatan.\n\n" + - "/stop untuk berhenti berlangganan" + text = "Anda telah berlangganan peringatan ${detectionType.localizedName()}.\n\n" + + "/stop untuk berhenti berlangganan", ) } catch (e: DataIntegrityViolationException) { log.debug(e) { "Duplicate subscription: " + chatId.id } @@ -67,12 +105,12 @@ class TelegramService( } } - fun stop(chatId: ChatId.Id) { - telegramChatRepo.deleteByChatId(chatId.id) + fun stop(chatId: ChatId.Id, detectionType: DetectionType) { + telegramChatRepo.deleteByChatIdAndDetectionType(chatId.id, detectionType) bot.sendMessage( chatId = chatId, - text = "Anda telah berhenti berlangganan.\n\n" + - "/start untuk berlangganan peringatan" + text = "Anda telah berhenti berlangganan peringatan ${detectionType.localizedName()}.\n\n" + + "/start untuk berlangganan peringatan", ) } @@ -92,7 +130,7 @@ class TelegramService( val body = titleBody.body ?: "" val media = TelegramFile.ByFile(storageService.file(alarm.snapshotCount.snapshotImageId)) - val chats = telegramChatRepo.findAll() + val chats = telegramChatRepo.findByDetectionType(type) for (chat in chats) { rateLimit.acquire() rt.execute { diff --git a/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt b/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt index c45cd2b..21f1e9b 100644 --- a/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt +++ b/src/test/kotlin/com/katalisindonesia/banyuwangi/service/TelegramServiceTest.kt @@ -33,34 +33,34 @@ class TelegramServiceTest( ) { @Test fun test_start_stop() { - telegramService.start(ChatId.fromId(10)) + telegramService.start(ChatId.fromId(10), DetectionType.TRAFFIC) assertEquals(1, telegramChatRepo.findAll().size) // duplicate - telegramService.start(ChatId.fromId(10)) + telegramService.start(ChatId.fromId(10), DetectionType.TRAFFIC) assertEquals(1, telegramChatRepo.findAll().size) // different - telegramService.start(ChatId.fromId(59573981)) + telegramService.start(ChatId.fromId(59573981), DetectionType.TRAFFIC) assertEquals(2, telegramChatRepo.findAll().size) // stop - telegramService.stop(ChatId.fromId(59573981)) + telegramService.stop(ChatId.fromId(59573981), DetectionType.TRAFFIC) assertEquals(1, telegramChatRepo.findAll().size) // duplicate stop - telegramService.stop(ChatId.fromId(59573981)) + telegramService.stop(ChatId.fromId(59573981), DetectionType.TRAFFIC) assertEquals(1, telegramChatRepo.findAll().size) // all stop - telegramService.stop(ChatId.fromId(10)) + telegramService.stop(ChatId.fromId(10), DetectionType.TRAFFIC) assertEquals(0, telegramChatRepo.findAll().size) } @Test fun sendAlarm() { - telegramService.start(ChatId.fromId(59573981)) + telegramService.start(ChatId.fromId(59573981), DetectionType.TRAFFIC) val camera0 = Camera(name = "camera0", location = "") val snapshot0 = Snapshot(imageId = imageId(), camera = camera0, length = 0, isAnnotation = true) @@ -79,11 +79,11 @@ class TelegramServiceTest( snapshotCount = count0, ) ) - telegramService.stop(ChatId.fromId(59573981)) + telegramService.stop(ChatId.fromId(59573981), DetectionType.TRAFFIC) } @Test fun sendAlarmFloodHigh() { - telegramService.start(ChatId.fromId(59573981)) + telegramService.start(ChatId.fromId(59573981), DetectionType.TRAFFIC) val camera0 = Camera(name = "camera0", location = "") val snapshot0 = Snapshot(imageId = imageId(), camera = camera0, length = 0, isAnnotation = true) @@ -102,11 +102,11 @@ class TelegramServiceTest( snapshotCount = count0, ) ) - telegramService.stop(ChatId.fromId(59573981)) + telegramService.stop(ChatId.fromId(59573981), DetectionType.TRAFFIC) } @Test fun sendAlarmFloodLow() { - telegramService.start(ChatId.fromId(59573981)) + telegramService.start(ChatId.fromId(59573981), DetectionType.TRAFFIC) val camera0 = Camera(name = "camera0", location = "") val snapshot0 = Snapshot(imageId = imageId(), camera = camera0, length = 0, isAnnotation = true) @@ -125,7 +125,7 @@ class TelegramServiceTest( snapshotCount = count0, ) ) - telegramService.stop(ChatId.fromId(59573981)) + telegramService.stop(ChatId.fromId(59573981), DetectionType.TRAFFIC) } private fun imageId(): UUID {