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", System.getenv("JDBC_USER") ?: "", System.getenv("JDBC_PASSWORD") ?: "" ) 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() } } } } }