Add quotes (#1)

Quotes!

Co-authored-by: Kalle Struik <kalle@kallestruik.nl>
Reviewed-on: https://gitea.kallestruik.nl/kalle/discord-bot/pulls/1
master
kalle 2022-04-20 20:32:12 +02:00
parent 2b2228cfa2
commit 570040d5ca
3 changed files with 120 additions and 1 deletions

3
.gitignore vendored
View File

@ -1,6 +1,9 @@
# Don't leak secrets
config.json
# And no test data either
quotes.json
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar

View File

@ -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
}
}

View File

@ -0,0 +1,9 @@
package nl.kallestruik.discordbot.data.quotes
import kotlinx.serialization.Serializable
@Serializable
data class QuoteData(
val author: String,
val quote: String,
)