Watchtower/src/main/kotlin/nl/voidcorp/watchtower/Main.kt

93 lines
3.7 KiB
Kotlin

package nl.voidcorp.watchtower
import net.dv8tion.jda.api.EmbedBuilder
import net.dv8tion.jda.api.JDABuilder
import net.dv8tion.jda.api.entities.Activity
import net.dv8tion.jda.api.events.message.guild.GenericGuildMessageEvent
import net.dv8tion.jda.api.events.message.guild.GuildMessageDeleteEvent
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent
import net.dv8tion.jda.api.events.message.guild.GuildMessageUpdateEvent
import net.dv8tion.jda.api.hooks.ListenerAdapter
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.transactions.TransactionManager
import org.jetbrains.exposed.sql.transactions.transaction
import java.awt.Color
import java.sql.Connection
import java.time.Instant
fun main() {
val token: String = System.getenv("DISCORD_TOKEN") ?: throw RuntimeException("Missing DISCORD_TOKEN in env!")
Database.connect(
System.getenv("JDBC_URl") ?: "jdbc:sqlite:test.db",
System.getenv("JDBC_DRIVER") ?: "org.sqlite.JDBC"
)
TransactionManager.manager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE
transaction {
SchemaUtils.createMissingTablesAndColumns(Messages, MessageHistories)
}
JDABuilder().setToken(token).setActivity(Activity.watching("you")).addEventListeners(LogListener).build()
}
fun GuildMessageReceivedEvent.log() {
transaction {
Message.new {
channel = this@log.channel.idLong
user = this@log.author.idLong
guild = this@log.guild.idLong
message = this@log.messageIdLong
}.update(this@log.message.contentRaw)
}
}
object LogListener : ListenerAdapter() {
override fun onGuildMessageReceived(event: GuildMessageReceivedEvent) {
if (!event.isWebhookMessage && !event.author.isBot) {
event.log()
}
}
override fun onGuildMessageUpdate(event: GuildMessageUpdateEvent) {
if (!event.author.isBot) {
val m = transaction { Message.find { Messages.message eq event.messageIdLong }.firstOrNull() } ?: return
m.update(event.message.contentRaw)
messageEdit(event, "Message Edited!")
}
}
override fun onGuildMessageDelete(event: GuildMessageDeleteEvent) {
messageEdit(event, "Message Deleted!")
}
private fun messageEdit(event: GenericGuildMessageEvent, what: String) {
val m = transaction { Message.find { Messages.message eq event.messageIdLong }.firstOrNull() } ?: return
val logs = event.guild.textChannels.find { it.name == "logs" }
logs?.sendMessage(
EmbedBuilder().setDescription(transaction { m.lastVersion.content }).setTitle(what)
.addField("Channel", event.channel.asMention, true).addField(
"User",
event.jda.getUserById(m.user)?.asTag ?: "No Idea...",
true
).setColor(Color.ORANGE.let {
if (what.contains("delete", true)) Color.RED.darker() else it
}).apply {
this.addField(
"History",
transaction {
m.history.sortedBy { it.updated }.dropLast(1).joinToString("\n") { it.content }
}, false
)
}.setTimestamp(Instant.ofEpochMilli(transaction { m.lastVersion.updated })).setFooter("Last changed at")
.build()
)?.queue {
if (event is GuildMessageDeleteEvent) {
transaction {
MessageHistory.find { MessageHistories.original eq m.id }.forEach { it.delete() }
m.delete()
}
}
}
}
}