Add self-configuration feature

This commit is contained in:
Wieland Schöbl
2020-08-17 20:22:27 +02:00
parent e58f4dc0c5
commit 5969a2f221
10 changed files with 222 additions and 51 deletions

View File

@@ -49,7 +49,7 @@ object Admin {
kotlin.io.println("Connected to ${admin!!.name}. No further errors will be printed here.")
}
}
private var admin: User? = null
var admin: User? = null
fun println(msg: String) {
sendDevMessage(
@@ -71,12 +71,19 @@ object Admin {
)
}
fun error(msg: String, error: String) {
fun error(msg: String, error: String, author: User? = null) {
sendDevMessage(
EmbedBuilder()
.setTitle(msg)
.setDescription(error)
.setColor(Color.RED)
.run {
if (author == null) {
this
} else {
this.setAuthor(author.asTag, author.avatarUrl, author.avatarUrl)
}
}
.build()
, "$msg\n\n${error}"
)

View File

@@ -8,7 +8,7 @@ import net.dv8tion.jda.api.events.ExceptionEvent
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent
import kotlin.system.exitProcess
class Cli : ListenerAdapter() {
class AdminCli : ListenerAdapter() {
override fun onPrivateMessageReceived(event: PrivateMessageReceivedEvent) {
val msg = event.message.contentRaw
if (event.author.idLong != Admin.userId ||

View File

@@ -8,6 +8,7 @@ import net.dv8tion.jda.api.JDA
import net.dv8tion.jda.api.Permission
import net.dv8tion.jda.api.entities.MessageEmbed
import net.dv8tion.jda.api.entities.TextChannel
import net.dv8tion.jda.api.exceptions.ErrorResponseException
object Channels {
var jda: JDA? = null
@@ -23,20 +24,24 @@ object Channels {
return
for (channel_pair in channels) {
val channel = jda!!.getTextChannelById(channel_pair.id) ?: continue
try {
val channel = jda!!.getTextChannelById(channel_pair.id) ?: continue
if (channel_pair.mentionedRole != null) {
val message = if (channel_pair.mentionedRole == "everyone") {
"New Blogpost @everyone"
} else {
"New Blogpost <@&${channel_pair.mentionedRole}>"
if (channel_pair.mentionedRole != null) {
val message = if (channel_pair.mentionedRole == "everyone") {
"New Blogpost @everyone"
} else {
"New Blogpost <@&${channel_pair.mentionedRole}>"
}
channel.sendMessage(message).queue()
}
channel.sendMessage(message).queue()
}
channel.sendMessage(messageEmbed).queue {
if (channel_pair.autoPublish) {
it.crosspost().queue()
channel.sendMessage(messageEmbed).queue {
if (channel_pair.autoPublish) {
it.crosspost().queue()
}
}
} catch (e: ErrorResponseException) {
Admin.error("Error in server", e.message ?: e.localizedMessage)
}
}
}
@@ -66,11 +71,11 @@ object Channels {
).toMutableList()
}
fun getServerNames(): List<String> {
fun getServerNames(server: Long? = null): List<String> {
if (jda == null)
return listOf()
return channels.map {
return channels.filter { server == null || (jda!!.getTextChannelById(it.id)?.guild?.idLong == server) }.map {
val channel = jda!!.getTextChannelById(it.id)
if (channel == null) {
Admin.warning("Channel ${it.id} is no longer active!")
@@ -80,7 +85,7 @@ object Channels {
val role = when (it.mentionedRole) {
null -> ""
"everyone" -> " @everyone"
else -> " @${channel.guild.getRoleById(it.mentionedRole)?.name}"
else -> " @${channel.guild.getRoleById(it.mentionedRole ?: "")?.name}"
}
"**${channel.guild.name}**\n#${channel.name}${role}"
}
@@ -90,12 +95,17 @@ object Channels {
return jda?.getTextChannelById(id)
}
fun addChannel(id: Long, role: String?) {
channels.add(DiscordChannel(id, role))
fun addChannel(id: Long, role: String?): DiscordChannel? {
if (channels.find { it.id == id } != null) {
return null
}
val out = DiscordChannel(id, role)
channels.add(out)
saveChannels()
return out
}
private fun saveChannels() {
fun saveChannels() {
SERVERS_FILE.writeText(
json.stringify(
DiscordChannel.serializer().list,

View File

@@ -6,8 +6,8 @@ import java.io.File
@Serializable
data class DiscordChannel(
val id: Long,
val mentionedRole: String? = null,
val autoPublish: Boolean = false
var mentionedRole: String? = null,
var autoPublish: Boolean = false
)
@Serializable

View File

@@ -13,8 +13,9 @@ fun main() {
.setActivity(Activity.watching("for new Blogposts"))
.build()
builder.addEventListener(Cli())
builder.addEventListener(AdminCli())
builder.addEventListener(ErrorHandler())
builder.addEventListener(OwnerCli())
builder.awaitReady()
Channels.jda = builder

View File

@@ -0,0 +1,131 @@
package de.wulkanat
import net.dv8tion.jda.api.EmbedBuilder
import net.dv8tion.jda.api.Permission
import net.dv8tion.jda.api.events.message.MessageReceivedEvent
import net.dv8tion.jda.api.hooks.ListenerAdapter
import java.awt.Color
class OwnerCli : ListenerAdapter() {
private val prefix = "%!"
override fun onMessageReceived(event: MessageReceivedEvent) {
val msg = event.message.contentRaw
// Only accept admin requests
if (event.message.member?.hasPermission(Permission.ADMINISTRATOR) != true || !msg.startsWith(prefix)) {
return
}
val command = msg.removePrefix(prefix).split(Regex("\\s+"))
val channelId = event.message.channel.idLong
when (command.first()) {
"add" -> {
val result = Channels.addChannel(channelId, null)
if (result == null) {
event.message.channel.sendMessage("Already added.").queue()
} else {
event.message.channel.sendMessage("Added.").queue()
Admin.info()
}
}
"remove" -> {
val result = Channels.channels.removeAll { it.id == channelId }
Channels.saveChannels()
if (result) {
event.message.channel.sendMessage("Removed.").queue()
} else {
event.message.channel.sendMessage("This channel is not registered.").queue()
}
}
"publish" -> {
val result = Channels.channels.find { it.id == channelId }
if (result != null) {
if (command.size > 1 && listOf("on", "off").contains(command[1])) {
result.autoPublish = command[1] == "on"
Channels.saveChannels()
event.message.channel.sendMessage("Auto publish is now ${command[1]}").queue()
} else {
event.message.channel.sendMessage("Usage: `${prefix}publish [on|off]`")
}
} else {
event.message.channel.sendMessage("Added.").queue()
}
}
"ping" -> {
val result = Channels.channels.find { it.id == channelId }
if (result != null) {
if (command.size > 1) {
val roles = event.message.guild.getRolesByName(command[1], false)
result.mentionedRole = when {
command[1] == "everyone" -> {
event.message.channel.sendMessage("Now pinging everyone.").queue()
"everyone"
}
command[1] == "none" -> {
event.message.channel.sendMessage("Now pinging none.").queue()
null
}
roles.firstOrNull() != null -> {
event.message.channel.sendMessage("Now pinging ${roles.first().name}").queue()
roles.first().id
}
else -> {
event.message.channel.sendMessage("Unknown role.").queue()
result.mentionedRole
}
}
Channels.saveChannels()
} else {
event.message.channel.sendMessage("Usage: `${prefix}ping [everyone|none|roleName]`")
}
} else {
event.message.channel.sendMessage("Channel is not registered.").queue()
}
}
"info" -> {
event.message.channel.sendMessage(EmbedBuilder()
.setTitle("Server overview")
.setColor(Color.GREEN)
.setDescription(Channels.getServerNames(event.message.guild.idLong).joinToString("\n"))
.setAuthor(Admin.admin?.name, Admin.admin?.avatarUrl, Admin.admin?.avatarUrl)
.build()).queue()
}
"report" -> {
val errorReport = event.message.contentRaw.removePrefix("${prefix}report")
Admin.error(event.message.guild.name, errorReport, event.author)
event.message.channel.sendMessage(EmbedBuilder()
.setTitle("Error Report Received")
.setColor(Color.RED)
.setDescription(errorReport)
.setAuthor(Admin.admin?.name, Admin.admin?.avatarUrl, Admin.admin?.avatarUrl)
.build()).queue()
}
"help" -> {
event.message.channel.sendMessage(EmbedBuilder()
.setTitle("Help")
.setColor(Color.YELLOW)
.setAuthor(Admin.admin?.name, Admin.admin?.avatarUrl, Admin.admin?.avatarUrl)
.setDescription(
"""
**${prefix}add**
Add this channel to the notified list
**${prefix}remove**
Remove this channel to the notified list
**${prefix}publish [on|off]**
[Community|Partner|Verified only] Auto publish the message if in an announcement channel
**${prefix}ping [none|everyone|roleName]**
What role to ping
**${prefix}info**
Show an overview about all channels registered on this server
**${prefix}report**
Report an issue to the Bot Admin (this will share your user name so they can contact you)
**${prefix}help**
Show this message
""".trimIndent())
.build()).queue()
}
}
}
}

View File

@@ -10,8 +10,6 @@ object SiteWatcher {
var newestBlog: BlogPostPreview? = null
fun hasNewBlogPost(): Boolean {
Admin.silent("Updating...")
try {
val doc = Jsoup.connect(BLOG_INDEX_URL).get()
val newBlog = BlogPostParser.getFistBlog(doc)