1
0

this database stuff should work, making the livestream announcements configurable.

This commit is contained in:
Jannik Reimers 2024-11-06 19:28:45 +01:00
parent 207d5dba2e
commit 0ad78ba494
Signed by: jansel
GPG Key ID: 39C62D7D5233CFD0
7 changed files with 143 additions and 14 deletions

View File

@ -31,7 +31,7 @@ dependencies {
} }
kordEx { kordEx {
kordExVersion = "2.3.1-SNAPSHOT" kordExVersion = "2.2.1-SNAPSHOT"
jvmTarget = 21 jvmTarget = 21

View File

@ -3,20 +3,22 @@
*/ */
package dev.jansel.feixiao package dev.jansel.feixiao
import com.github.twitch4j.TwitchClient
import com.github.twitch4j.TwitchClientBuilder import com.github.twitch4j.TwitchClientBuilder
import com.github.twitch4j.events.ChannelChangeTitleEvent
import com.github.twitch4j.events.ChannelGoLiveEvent import com.github.twitch4j.events.ChannelGoLiveEvent
import com.github.twitch4j.events.ChannelGoOfflineEvent import dev.jansel.feixiao.database.collections.StreamerCollection
import dev.jansel.feixiao.extensions.EventHooks import dev.jansel.feixiao.extensions.EventHooks
import dev.jansel.feixiao.extensions.MessageEvents import dev.jansel.feixiao.extensions.MessageEvents
import dev.jansel.feixiao.extensions.StreamerCommand
import dev.jansel.feixiao.utils.* import dev.jansel.feixiao.utils.*
import dev.kord.core.behavior.getChannelOf
import dev.kord.core.entity.channel.GuildMessageChannel import dev.kord.core.entity.channel.GuildMessageChannel
import dev.kordex.core.ExtensibleBot import dev.kordex.core.ExtensibleBot
import dev.kordex.data.api.DataCollection import dev.kordex.data.api.DataCollection
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
var twitchClient: TwitchClient? = null
suspend fun main() { suspend fun main() {
val bot = ExtensibleBot(token) { val bot = ExtensibleBot(token) {
database(true) database(true)
@ -24,27 +26,32 @@ suspend fun main() {
extensions { extensions {
add(::MessageEvents) add(::MessageEvents)
add(::EventHooks) add(::EventHooks)
add(::StreamerCommand)
} }
} }
val twitchClient = TwitchClientBuilder.builder() twitchClient = TwitchClientBuilder.builder()
.withEnableHelix(true) .withEnableHelix(true)
.withClientId(twitchcid) .withClientId(twitchcid)
.withClientSecret(twitchcs) .withClientSecret(twitchcs)
.build() .build()
twitchClient.clientHelper.enableStreamEventListener("janselosu") twitchClient!!.eventManager.onEvent(ChannelGoLiveEvent::class.java) {
twitchClient.eventManager.onEvent(ChannelGoLiveEvent::class.java) {
println("${it.channel.name} went live!") println("${it.channel.name} went live!")
runBlocking { runBlocking {
launch { launch {
val twitchpingschannel = val streamer = StreamerCollection().getData(it.channel.name)
bot.kordRef.getGuildOrNull(tserverid)?.getChannelOf<GuildMessageChannel>(tchannelid) val channel = bot.kordRef.getChannelOf<GuildMessageChannel>(streamer!!.servers.first().channelId)
twitchpingschannel?.createMessage("<@&1130981452130037800> ${it.channel.name} is now live at https://twitch.tv/${it.channel.name} streaming ${it.stream.gameName}: ${it.stream.title}") val role = streamer.servers.first().roleId
bot.kordRef.editPresence { streaming(it.stream.title, "https://twitch.tv/${it.channel.name}") } if (role != null) {
channel?.createMessage("<@&$role> ${it.channel.name} went live streaming ${it.stream.gameName}: ${it.stream.title}")
} else {
channel?.createMessage("${it.channel.name} went live: ${it.stream.title}")
}
} }
} }
} }
bot.start() bot.start()
} }

View File

@ -0,0 +1,46 @@
package dev.jansel.feixiao.database.collections
import dev.jansel.feixiao.database.Database
import dev.jansel.feixiao.database.entities.Server
import dev.jansel.feixiao.database.entities.StreamerData
import dev.kord.common.entity.Snowflake
import dev.kordex.core.koin.KordExKoinComponent
import org.koin.core.component.inject
import org.litote.kmongo.eq
import org.litote.kmongo.setValue
class StreamerCollection : KordExKoinComponent {
private val db:
Database by inject()
@PublishedApi
internal val collection =
db.mongo.getCollection<StreamerData>()
suspend fun getData(channelName: String): StreamerData? =
collection.findOne(StreamerData::name eq channelName)
suspend fun updateData(guildId: Snowflake, channelId: Snowflake, streamerName: String, roleId: Snowflake?) {
val coll = collection.findOne(StreamerData::name eq streamerName)
if (coll != null) {
collection.updateOne(
StreamerData::name eq streamerName,
setValue(StreamerData::servers, coll.servers + listOf(Server(guildId, channelId, roleId)))
)
} else {
collection.insertOne(
StreamerData(streamerName, listOf(Server(guildId, channelId, roleId)))
)
}
}
suspend fun removeData(guildId: Snowflake, channelId: Snowflake, streamerName: String, roleId: Snowflake?) {
val coll = collection.findOne(StreamerData::name eq streamerName)
if (coll != null) {
collection.updateOne(
StreamerData::name eq streamerName,
setValue(StreamerData::servers, coll.servers - Server(guildId, channelId, roleId))
)
}
}
}

View File

@ -0,0 +1,17 @@
package dev.jansel.feixiao.database.entities
import dev.kord.common.entity.Snowflake
import kotlinx.serialization.Serializable
@Serializable
data class StreamerData(
val name: String,
val servers: List<Server>
)
@Serializable
data class Server(
val guildId: Snowflake,
val channelId: Snowflake,
val roleId: Snowflake?
)

View File

@ -11,7 +11,7 @@ class EventHooks : Extension() {
event<ReadyEvent> { event<ReadyEvent> {
action { action {
println("Bot is ready!") println("Bot is ready!")
kord.editPresence { "electing a president..." } kord.editPresence { listening("to the database") }
} }
} }
} }

View File

@ -0,0 +1,59 @@
package dev.jansel.feixiao.extensions
import dev.jansel.feixiao.database.collections.StreamerCollection
import dev.jansel.feixiao.twitchClient
import dev.kord.common.entity.Permission
import dev.kordex.core.checks.anyGuild
import dev.kordex.core.checks.hasPermission
import dev.kordex.core.commands.Arguments
import dev.kordex.core.commands.application.slash.publicSubCommand
import dev.kordex.core.commands.converters.impl.snowflake
import dev.kordex.core.commands.converters.impl.string
import dev.kordex.core.extensions.Extension
import dev.kordex.core.extensions.publicSlashCommand
class StreamerCommand : Extension() {
override val name = "streamer"
override suspend fun setup() {
publicSlashCommand {
name = "streamer"
description = "Streamer commands"
publicSubCommand(::StreamerArgs) {
name = "add"
description = "Add a streamer to the listener"
check {
anyGuild()
hasPermission(Permission.ManageGuild)
}
action {
val streamer = arguments.streamer
StreamerCollection().updateData(guild!!.id, channel.id, streamer, arguments.role)
twitchClient!!.clientHelper.enableStreamEventListener(streamer)
respond {
content = "Added streamer $streamer"
}
}
}
}
}
inner class StreamerArgs : Arguments() {
val streamer by string {
name = "streamer"
description = "The streamer to add"
require(true)
}
val channel by snowflake {
name = "announceChannel"
description = "Channel where the bot will send a message when the streamer goes live"
require(true)
}
val role by snowflake {
name = "role"
description = "Role to ping when the streamer goes live"
require(false)
}
}
}