|
|
|
@ -7,22 +7,38 @@ import dev.kord.core.behavior.channel.createMessage
|
|
|
|
|
import dev.kord.core.behavior.interaction.response.respond
|
|
|
|
|
import dev.kord.core.builder.components.emoji
|
|
|
|
|
import dev.kord.core.entity.channel.TextChannel
|
|
|
|
|
import dev.kord.core.entity.interaction.GuildChatInputCommandInteraction
|
|
|
|
|
import dev.kord.core.entity.interaction.InteractionCommand
|
|
|
|
|
import dev.kord.core.event.interaction.GuildButtonInteractionCreateEvent
|
|
|
|
|
import dev.kord.core.event.interaction.GuildChatInputCommandInteractionCreateEvent
|
|
|
|
|
import dev.kord.core.on
|
|
|
|
|
import dev.kord.rest.builder.interaction.string
|
|
|
|
|
import dev.kord.rest.builder.message.create.actionRow
|
|
|
|
|
import kotlinx.coroutines.flow.*
|
|
|
|
|
import kotlinx.serialization.decodeFromString
|
|
|
|
|
import kotlinx.serialization.encodeToString
|
|
|
|
|
import kotlinx.serialization.json.Json
|
|
|
|
|
import nl.kallestruik.discordbot.config.Config
|
|
|
|
|
import nl.kallestruik.discordbot.data.quotes.QuoteData
|
|
|
|
|
import java.io.File
|
|
|
|
|
|
|
|
|
|
val prettyJson = Json {
|
|
|
|
|
prettyPrint = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
suspend fun main() {
|
|
|
|
|
val quoteFile = File("quotes.json")
|
|
|
|
|
if (!quoteFile.exists())
|
|
|
|
|
quoteFile.writeText("[]") // Write an empty array if the file does not exist.
|
|
|
|
|
|
|
|
|
|
val config: Config = Json.decodeFromString(File("config.json").readText())
|
|
|
|
|
val quotes: MutableList<QuoteData> = Json.decodeFromString(quoteFile.readText())
|
|
|
|
|
|
|
|
|
|
val kord = Kord(config.token)
|
|
|
|
|
|
|
|
|
|
val channel = kord.getChannel(Snowflake(config.roleChannelID)) as? TextChannel ?: return
|
|
|
|
|
|
|
|
|
|
// Delete old role selection messages
|
|
|
|
|
val oldMessages = mutableSetOf<Snowflake>()
|
|
|
|
|
channel.messages
|
|
|
|
|
.filter { it.author == kord.getSelf() }
|
|
|
|
@ -30,6 +46,7 @@ suspend fun main() {
|
|
|
|
|
.toSet(oldMessages)
|
|
|
|
|
channel.bulkDelete(oldMessages)
|
|
|
|
|
|
|
|
|
|
// Send the role selection message
|
|
|
|
|
channel.createMessage {
|
|
|
|
|
actionRow {
|
|
|
|
|
for (role in config.roles) {
|
|
|
|
@ -43,6 +60,32 @@ suspend fun main() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create the quotes command. Does discord get mad if this gets done on every startup?
|
|
|
|
|
kord.createGuildChatInputCommand(Snowflake(config.guildID), "quotes", "Get a quote") {
|
|
|
|
|
string("query", "What to search for.")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
kord.createGuildChatInputCommand(Snowflake(config.guildID), "quote", "Add a new quote") {
|
|
|
|
|
string("author", "The author of the quote.") {
|
|
|
|
|
required = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string("quote", "The quote.") {
|
|
|
|
|
required = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle guild chat commands
|
|
|
|
|
kord.on<GuildChatInputCommandInteractionCreateEvent> {
|
|
|
|
|
val command = interaction.command
|
|
|
|
|
if (command.rootName == "quotes")
|
|
|
|
|
quotesCommandHandler(interaction, command, quotes)
|
|
|
|
|
|
|
|
|
|
if (command.rootName == "quote")
|
|
|
|
|
quoteCommandHandler(interaction, command, quotes, quoteFile)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle guild chat buttons
|
|
|
|
|
kord.on<GuildButtonInteractionCreateEvent> {
|
|
|
|
|
val response = interaction.deferEphemeralResponse()
|
|
|
|
|
val roleConfig = config.roles[interaction.data.data.customId.value]
|
|
|
|
@ -68,5 +111,69 @@ suspend fun main() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Start the bot
|
|
|
|
|
kord.login()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
suspend fun quoteCommandHandler(
|
|
|
|
|
interaction: GuildChatInputCommandInteraction,
|
|
|
|
|
command: InteractionCommand,
|
|
|
|
|
quotes: MutableList<QuoteData>,
|
|
|
|
|
quoteFile: File
|
|
|
|
|
) {
|
|
|
|
|
val response = interaction.deferEphemeralResponse()
|
|
|
|
|
|
|
|
|
|
val author = command.strings["author"]!! // These are required so they can't be null
|
|
|
|
|
val quote = command.strings["quote"]!!.replace("\\n", "\n")
|
|
|
|
|
quotes.add(QuoteData(author, quote))
|
|
|
|
|
|
|
|
|
|
quoteFile.writeText(prettyJson.encodeToString(quotes))
|
|
|
|
|
|
|
|
|
|
response.respond {
|
|
|
|
|
content = "Added quote successfully!"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
suspend fun quotesCommandHandler(
|
|
|
|
|
interaction: GuildChatInputCommandInteraction,
|
|
|
|
|
command: InteractionCommand,
|
|
|
|
|
quotes: MutableList<QuoteData>
|
|
|
|
|
) {
|
|
|
|
|
val response = interaction.deferPublicResponse()
|
|
|
|
|
|
|
|
|
|
val query = Regex(command.strings["query"] ?: "", RegexOption.IGNORE_CASE)
|
|
|
|
|
|
|
|
|
|
val quotes = quotes.filter {
|
|
|
|
|
it.quote.contains(query) || it.author.contains(query)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (quotes.isEmpty()) {
|
|
|
|
|
response.respond {
|
|
|
|
|
content = "No quotes found!"
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
response.respond {
|
|
|
|
|
content = "Search results for: $query"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var content = ""
|
|
|
|
|
for (quote in quotes) {
|
|
|
|
|
val quoteString = "**${quote.author}:** ${quote.quote}\n"
|
|
|
|
|
if (content.length + quoteString.length >= 2000) {
|
|
|
|
|
interaction.channel.createMessage {
|
|
|
|
|
this.content = content
|
|
|
|
|
}
|
|
|
|
|
content = quoteString
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
content += quoteString
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interaction.channel.createMessage {
|
|
|
|
|
this.content = content
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|