From 3f60348ace12cc260027f1276766df7399f0ffaa Mon Sep 17 00:00:00 2001 From: dalbodeule <11470513+dalbodeule@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:10:34 +0900 Subject: [PATCH] stream info add --- src/main/kotlin/space/mori/chzzk_bot/Main.kt | 10 +-- .../mori/chzzk_bot/chzzk/ChzzkHandler.kt | 61 ++++++++++++++++++- .../space/mori/chzzk_bot/discord/Discord.kt | 6 +- .../space/mori/chzzk_bot/models/User.kt | 6 ++ .../mori/chzzk_bot/services/UserService.kt | 15 +++++ 5 files changed, 91 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/space/mori/chzzk_bot/Main.kt b/src/main/kotlin/space/mori/chzzk_bot/Main.kt index 4ad7eb8..9a34f2a 100644 --- a/src/main/kotlin/space/mori/chzzk_bot/Main.kt +++ b/src/main/kotlin/space/mori/chzzk_bot/Main.kt @@ -16,13 +16,13 @@ val dotenv = dotenv { } val logger: Logger = LoggerFactory.getLogger("main") -fun main(args: Array) { - val discord = Discord() +val discord = Discord() - val connector = Connector - val chzzkConnector = ChzzkConnector - val chzzkHandler = ChzzkHandler +val connector = Connector +val chzzkConnector = ChzzkConnector +val chzzkHandler = ChzzkHandler +fun main(args: Array) { discord.enable() chzzkHandler.enable() diff --git a/src/main/kotlin/space/mori/chzzk_bot/chzzk/ChzzkHandler.kt b/src/main/kotlin/space/mori/chzzk_bot/chzzk/ChzzkHandler.kt index 2df46d2..e3d2634 100644 --- a/src/main/kotlin/space/mori/chzzk_bot/chzzk/ChzzkHandler.kt +++ b/src/main/kotlin/space/mori/chzzk_bot/chzzk/ChzzkHandler.kt @@ -1,8 +1,11 @@ package space.mori.chzzk_bot.chzzk +import net.dv8tion.jda.api.EmbedBuilder +import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder import org.slf4j.Logger import org.slf4j.LoggerFactory import space.mori.chzzk_bot.chzzk.Connector.chzzk +import space.mori.chzzk_bot.discord import space.mori.chzzk_bot.models.User import space.mori.chzzk_bot.services.UserService import xyz.r2turntrue.chzzk4j.chat.ChatEventListener @@ -10,10 +13,12 @@ import xyz.r2turntrue.chzzk4j.chat.ChatMessage import xyz.r2turntrue.chzzk4j.chat.ChzzkChat import xyz.r2turntrue.chzzk4j.types.channel.ChzzkChannel import java.lang.Exception +import java.time.Instant object ChzzkHandler { private val handlers = mutableListOf() private val logger = LoggerFactory.getLogger(this::class.java) + @Volatile private var running: Boolean = false internal fun addUser(chzzkChannel: ChzzkChannel, user: User) { handlers.add(UserHandler(chzzkChannel, logger, user)) @@ -38,10 +43,32 @@ object ChzzkHandler { else throw RuntimeException("${chzzkChannel.channelName} doesn't have handler") } + + internal fun runStreamInfo() { + running = true + Thread { + while(running) { + handlers.forEach { + if (!running) return@forEach + val streamInfo = getStreamInfo(it.channel.channelId) + if(streamInfo.content.status == "OPEN" && !it.isActive) it.isActive(true, streamInfo) + if(streamInfo.content.status == "CLOSED" && it.isActive) it.isActive(false, streamInfo) + Thread.sleep(3000) + } + } + }.start() + } + + internal fun stopStreamInfo() { + running = false + } } class UserHandler( - val channel: ChzzkChannel, private val logger: Logger, private val user: User + val channel: ChzzkChannel, + private val logger: Logger, + private val user: User, + private var _isActive: Boolean = false ) { private lateinit var messageHandler: MessageHandler @@ -81,4 +108,36 @@ class UserHandler( internal fun reloadCommand() { messageHandler.reloadCommand() } + + internal val isActive: Boolean + get() = _isActive + + internal fun isActive(value: Boolean, status: IData) { + _isActive = value + if(value) { + logger.info("${user.username} is live.") + if(user.liveAlertMessage != "" && user.liveAlertGuild != null && user.liveAlertChannel != null) { + val channel = discord.getChannel(user.liveAlertGuild!!, user.liveAlertGuild!!) ?: throw RuntimeException("${user.liveAlertChannel} is not valid.") + + val embed = EmbedBuilder() + embed.setTitle(status.content.liveTitle, "https://chzzk.naver.com/live/${user.token}") + embed.setDescription("${user.username} 님이 방송을 시작했습니다.") + embed.setUrl(status.content.channel.channelImageUrl) + embed.setTimestamp(Instant.now()) + embed.setAuthor(user.username, "https://chzzk.naver.com/live/${user.token}", status.content.channel.channelImageUrl) + embed.addField("카테고리", status.content.liveCategoryValue, true) + embed.addField("태그", status.content.tags.joinToString(", "), true) + embed.setImage(status.content.liveImageUrl) + + channel.sendMessage( + MessageCreateBuilder() + .setContent(user.liveAlertMessage) + .setEmbeds(embed.build()) + .build() + ).queue() + } + } else { + logger.info("${user.username} is offline.") + } + } } \ No newline at end of file diff --git a/src/main/kotlin/space/mori/chzzk_bot/discord/Discord.kt b/src/main/kotlin/space/mori/chzzk_bot/discord/Discord.kt index 04a153d..29038a5 100644 --- a/src/main/kotlin/space/mori/chzzk_bot/discord/Discord.kt +++ b/src/main/kotlin/space/mori/chzzk_bot/discord/Discord.kt @@ -4,6 +4,7 @@ import net.dv8tion.jda.api.JDA import net.dv8tion.jda.api.JDABuilder import net.dv8tion.jda.api.entities.Activity import net.dv8tion.jda.api.entities.Guild +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent import net.dv8tion.jda.api.hooks.ListenerAdapter import space.mori.chzzk_bot.dotenv @@ -69,4 +70,7 @@ class Discord: ListenerAdapter() { logger.debug(e.stackTraceToString()) } } -} \ No newline at end of file + + internal fun getChannel(guildId: Long, channelId: Long) = + bot.getGuildById(guildId)?.getTextChannelById(channelId) +} diff --git a/src/main/kotlin/space/mori/chzzk_bot/models/User.kt b/src/main/kotlin/space/mori/chzzk_bot/models/User.kt index 4aea843..6aa65d7 100644 --- a/src/main/kotlin/space/mori/chzzk_bot/models/User.kt +++ b/src/main/kotlin/space/mori/chzzk_bot/models/User.kt @@ -10,6 +10,9 @@ object Users: IntIdTable("users") { val username = varchar("username", 255) val token = varchar("token", 64) val discord = long("discord") + val liveAlertGuild = long("live_alert_guild").nullable() + val liveAlertChannel = long("live_alert_channel").nullable() + val liveAlertMessage = text("live_alert_message").nullable() } class User(id: EntityID) : IntEntity(id) { @@ -18,4 +21,7 @@ class User(id: EntityID) : IntEntity(id) { var username by Users.username var token by Users.token var discord by Users.discord + var liveAlertGuild by Users.liveAlertGuild + var liveAlertChannel by Users.liveAlertChannel + var liveAlertMessage by Users.liveAlertMessage } \ No newline at end of file diff --git a/src/main/kotlin/space/mori/chzzk_bot/services/UserService.kt b/src/main/kotlin/space/mori/chzzk_bot/services/UserService.kt index 7353fab..6c2e501 100644 --- a/src/main/kotlin/space/mori/chzzk_bot/services/UserService.kt +++ b/src/main/kotlin/space/mori/chzzk_bot/services/UserService.kt @@ -2,6 +2,7 @@ package space.mori.chzzk_bot.services import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction +import org.jetbrains.exposed.sql.update import space.mori.chzzk_bot.models.User import space.mori.chzzk_bot.models.Users @@ -43,4 +44,18 @@ object UserService { User.all().toList() } } + + fun updateLiveAlert(id: Int, guildId: Long, channelId: Long, alertMessage: String?) { + return transaction { + val updated = Users.update({ Users.id eq id }) { + it[Users.liveAlertGuild] = guildId + it[Users.liveAlertChannel] = channelId + it[Users.liveAlertMessage] = alertMessage ?: "" + } + + if(updated == 0) throw RuntimeException("User not found! $id") + + User.find(Users.id eq id) + } + } } \ No newline at end of file