diff --git a/README.md b/README.md index 6865834c..e191d442 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,11 @@ For environment variables, convert property names to uppercase and replace `.`/` These are bound from `discord-mod-bot.*` and the application will fail to start if they are missing. -| Property | Environment Variable | Required | Description | -|-----------------------------|-----------------------------|----------|------------------------------------------------------------------| -| `discord-mod-bot.owner-id` | `DISCORD_MOD_BOT_OWNER_ID` | Yes | Discord user ID for the bot owner (used for owner-only actions). | -| `discord-mod-bot.bot-token` | `DISCORD_MOD_BOT_BOT_TOKEN` | Yes | Discord bot token used to connect to the Discord gateway. | +| Property | Environment Variable | Required | Description | +|-------------------------------------------|----------------------------------------------|----------|------------------------------------------------------------------| +| `discord-mod-bot.owner-id` | `DISCORD_MOD_BOT_OWNER_ID` | Yes | Discord user ID for the bot owner (used for owner-only actions). | +| `discord-mod-bot.bot-token` | `DISCORD_MOD_BOT_BOT_TOKEN` | Yes | Discord bot token used to connect to the Discord gateway. | +| `discord-mod-bot.attachment-cache.channel-id` | `DISCORD_MOD_BOT_ATTACHMENT_CACHE_CHANNEL_ID` | Yes | Discord text channel used to cache attachments. | ### Default runtime properties @@ -44,6 +45,7 @@ These defaults are defined in `src/main/resources/application.properties`. ```bash export DISCORD_MOD_BOT_OWNER_ID=123456789012345678 export DISCORD_MOD_BOT_BOT_TOKEN=your-token-here +export DISCORD_MOD_BOT_ATTACHMENT_CACHE_CHANNEL_ID=310006048595509248 export SPRING_DATASOURCE_URL=jdbc:mariadb://127.0.0.1:3306/discordmodbot export SPRING_DATASOURCE_USERNAME=spring export SPRING_DATASOURCE_PASSWORD=test diff --git a/src/main/kotlin/be/duncanc/discordmodbot/logging/AttachmentCacheProperties.kt b/src/main/kotlin/be/duncanc/discordmodbot/logging/AttachmentCacheProperties.kt new file mode 100644 index 00000000..fa2b0c03 --- /dev/null +++ b/src/main/kotlin/be/duncanc/discordmodbot/logging/AttachmentCacheProperties.kt @@ -0,0 +1,12 @@ +package be.duncanc.discordmodbot.logging + +import jakarta.validation.constraints.Positive +import org.springframework.boot.context.properties.ConfigurationProperties +import org.springframework.validation.annotation.Validated + +@ConfigurationProperties("discord-mod-bot.attachment-cache") +@Validated +class AttachmentCacheProperties( + @field:Positive + val channelId: Long = throw IllegalStateException("attachment cache channel ID not configured") +) diff --git a/src/main/kotlin/be/duncanc/discordmodbot/logging/AttachmentProxyCreator.kt b/src/main/kotlin/be/duncanc/discordmodbot/logging/AttachmentProxyCreator.kt index d848928c..707f2cc8 100644 --- a/src/main/kotlin/be/duncanc/discordmodbot/logging/AttachmentProxyCreator.kt +++ b/src/main/kotlin/be/duncanc/discordmodbot/logging/AttachmentProxyCreator.kt @@ -21,10 +21,10 @@ import java.util.concurrent.TimeUnit */ @Component class AttachmentProxyCreator( - private val attachmentProxyRepository: AttachmentProxyRepository + private val attachmentProxyRepository: AttachmentProxyRepository, + private val attachmentCacheProperties: AttachmentCacheProperties ) { companion object { - private const val CACHE_CHANNEL = 310006048595509248L private val LOG = LoggerFactory.getLogger(AttachmentProxyCreator::class.java) } @@ -50,36 +50,44 @@ class AttachmentProxyCreator( var hadFailures = false val originalMessage = event.message - originalMessage.attachments.forEach { attachment -> - try { - if (attachment.size < 8 shl 20) { //8MB - attachment.proxy.download().get(30, TimeUnit.SECONDS).let { inputStream: InputStream -> - val outputStream = ByteArrayOutputStream() - IOUtils.copy(inputStream, outputStream) + val channel = event.jda.getTextChannelById(attachmentCacheProperties.channelId) + if (channel == null) { + LOG.error( + "The configured attachment cache channel could not be found: {}", + attachmentCacheProperties.channelId + ) + hadFailures = true + } else { + originalMessage.attachments.forEach { attachment -> + try { + if (attachment.size < 8 shl 20) { //8MB + attachment.proxy.download().get(30, TimeUnit.SECONDS).let { inputStream: InputStream -> + val outputStream = ByteArrayOutputStream() + IOUtils.copy(inputStream, outputStream) - event.jda.getTextChannelById(CACHE_CHANNEL) - ?.sendFiles( + channel.sendFiles( FileUpload.fromData(outputStream.toByteArray(), attachment.fileName) ) - ?.addContent(originalMessage.jumpUrl) - ?.map { message -> - message.attachments.map { messageAttachment -> - "[${messageAttachment.fileName}](${messageAttachment.url})" + .addContent(originalMessage.jumpUrl) + .map { message -> + message.attachments.map { messageAttachment -> + "[${messageAttachment.fileName}](${messageAttachment.url})" + } } - } - ?.submit() - ?.get(30, TimeUnit.SECONDS) - ?.let { - attachments.addAll(it) - } + .submit() + .get(30, TimeUnit.SECONDS) + .let { + attachments.addAll(it) + } + } + } else { + LOG.warn("The file was larger than 8MB.") + hadFailures = true } - } else { - LOG.warn("The file was larger than 8MB.") + } catch (e: Exception) { + LOG.info("An exception occurred when retrieving one of the attachments", e) hadFailures = true } - } catch (e: Exception) { - LOG.info("An exception occurred when retrieving one of the attachments", e) - hadFailures = true } } val attachmentProxy = when { diff --git a/src/test/kotlin/be/duncanc/discordmodbot/logging/AttachmentCachePropertiesTest.kt b/src/test/kotlin/be/duncanc/discordmodbot/logging/AttachmentCachePropertiesTest.kt new file mode 100644 index 00000000..970489f3 --- /dev/null +++ b/src/test/kotlin/be/duncanc/discordmodbot/logging/AttachmentCachePropertiesTest.kt @@ -0,0 +1,27 @@ +package be.duncanc.discordmodbot.logging + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.boot.test.context.runner.ApplicationContextRunner +import org.springframework.context.annotation.Configuration + +class AttachmentCachePropertiesTest { + + private val contextRunner = ApplicationContextRunner() + .withUserConfiguration(AttachmentCachePropertiesConfiguration::class.java) + + @Test + fun `custom channel ID is bound from properties`() { + contextRunner + .withPropertyValues("discord-mod-bot.attachment-cache.channel-id=123456789012345678") + .run { context -> + val properties = context.getBean(AttachmentCacheProperties::class.java) + assertEquals(123456789012345678L, properties.channelId) + } + } + + @Configuration + @EnableConfigurationProperties(AttachmentCacheProperties::class) + class AttachmentCachePropertiesConfiguration +}