diff --git a/build.gradle.kts b/build.gradle.kts index 40bcf26..8a428a1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -44,6 +44,7 @@ dependencies { implementation(libs.zxing.javase) implementation(libs.logback.classic) implementation(libs.slf4j.api) + implementation(libs.aws.s3.sdk) } tasks.build { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9154156..99ca3a8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,6 +13,7 @@ nashornVersion = "15.4" zxingVersion = "3.5.3" logbackClassicVersion = "1.5.8" sl4jVersion = "2.0.16" +awsS3SDKVersion = "2.28.18" [libraries] ronebot = { group = "cn.rtast", name = "ROneBot", version.ref = "ronebotVersion" } @@ -29,6 +30,7 @@ zxing-core = { group = "com.google.zxing", name = "core", version.ref = "zxingVe zxing-javase = { group = "com.google.zxing", name = "javase", version.ref = "zxingVersion" } logback-classic = { group = "ch.qos.logback", name = "logback-classic", version.ref = "logbackClassicVersion" } slf4j-api = { group = "org.slf4j", name = "slf4j-api", version.ref = "sl4jVersion" } +aws-s3-sdk = { group = "software.amazon.awssdk", name = "s3", version.ref = "awsS3SDKVersion" } [bundles] diff --git a/src/main/kotlin/cn/rtast/fancybot/Const.kt b/src/main/kotlin/cn/rtast/fancybot/Const.kt index 4de5803..1645dca 100644 --- a/src/main/kotlin/cn/rtast/fancybot/Const.kt +++ b/src/main/kotlin/cn/rtast/fancybot/Const.kt @@ -22,6 +22,7 @@ import cn.rtast.fancybot.commands.misc.JrrpCommand import cn.rtast.fancybot.commands.niuzi.NiuziRedeemCommand import cn.rtast.fancybot.commands.misc.ShortLinkCommand import cn.rtast.fancybot.entity.Config +import cn.rtast.fancybot.enums.ImageBedType import cn.rtast.fancybot.enums.ImageType import cn.rtast.fancybot.enums.WSType import cn.rtast.fancybot.items.* @@ -70,7 +71,13 @@ val DEFAULT_CONFIG = Config( selfId = 114514L, tianXingApiKey = "1145141919810", githubUser = "RTAkland", - githubImageRepo = "Static-Images" + githubImageRepo = "Static-Images", + imageBedType = ImageBedType.Github, + cloudflareAccountId = "111", + cloudflareR2AccessKeyId = "11111", + cloudflareR2SecretKey = "222", + cloudflareR2BucketName = "fancybot", + cloudflareR2PublicUrl = "https://pub-2df243c8ff83452c9dcdd42c87b662a7.r2.dev" ) val configManager = ConfigManager() diff --git a/src/main/kotlin/cn/rtast/fancybot/commands/parse/ImageURLCommand.kt b/src/main/kotlin/cn/rtast/fancybot/commands/parse/ImageURLCommand.kt index 5ec6a92..0bf8899 100644 --- a/src/main/kotlin/cn/rtast/fancybot/commands/parse/ImageURLCommand.kt +++ b/src/main/kotlin/cn/rtast/fancybot/commands/parse/ImageURLCommand.kt @@ -21,8 +21,8 @@ object ImageURLCommand { try { val images = mutableListOf() message.message.forEach { - if (it.type == ArrayMessageType.image) images.add(it.data.url!!) - if (it.type == ArrayMessageType.mface) images.add(it.data.file!!) + if (it.type == ArrayMessageType.image) images.add(it.data.file!!) + if (it.type == ArrayMessageType.mface) images.add(it.data.url!!) } return images } catch (_: NullPointerException) { diff --git a/src/main/kotlin/cn/rtast/fancybot/entity/Config.kt b/src/main/kotlin/cn/rtast/fancybot/entity/Config.kt index 513128a..65173e9 100644 --- a/src/main/kotlin/cn/rtast/fancybot/entity/Config.kt +++ b/src/main/kotlin/cn/rtast/fancybot/entity/Config.kt @@ -7,6 +7,7 @@ package cn.rtast.fancybot.entity +import cn.rtast.fancybot.enums.ImageBedType import cn.rtast.fancybot.enums.ImageType import cn.rtast.fancybot.enums.WSType @@ -38,4 +39,10 @@ data class Config( val tianXingApiKey: String, val githubUser: String, val githubImageRepo: String, + val imageBedType: ImageBedType, + val cloudflareAccountId: String, + val cloudflareR2AccessKeyId: String, + val cloudflareR2SecretKey: String, + val cloudflareR2BucketName: String, + val cloudflareR2PublicUrl: String ) \ No newline at end of file diff --git a/src/main/kotlin/cn/rtast/fancybot/enums/ImageBedType.kt b/src/main/kotlin/cn/rtast/fancybot/enums/ImageBedType.kt new file mode 100644 index 0000000..c793c64 --- /dev/null +++ b/src/main/kotlin/cn/rtast/fancybot/enums/ImageBedType.kt @@ -0,0 +1,12 @@ +/* + * Copyright © 2024 RTAkland + * Author: RTAkland + * Date: 2024/10/9 + */ + + +package cn.rtast.fancybot.enums + +enum class ImageBedType { + Github, CloudflareR2 +} \ No newline at end of file diff --git a/src/main/kotlin/cn/rtast/fancybot/util/file/ConfigManager.kt b/src/main/kotlin/cn/rtast/fancybot/util/file/ConfigManager.kt index d843d51..86275c7 100644 --- a/src/main/kotlin/cn/rtast/fancybot/util/file/ConfigManager.kt +++ b/src/main/kotlin/cn/rtast/fancybot/util/file/ConfigManager.kt @@ -8,6 +8,7 @@ package cn.rtast.fancybot.util.file import cn.rtast.fancybot.entity.Config +import cn.rtast.fancybot.enums.ImageBedType import cn.rtast.fancybot.util.str.JsonFileHandler class ConfigManager : JsonFileHandler("config.json") { @@ -39,4 +40,10 @@ class ConfigManager : JsonFileHandler("config.json") { val tianXingApiKey = config.tianXingApiKey val githubUser = config.githubUser val githubImageRepo = config.githubImageRepo + val imageBedType = config.imageBedType + val cloudflareAccountId = config.cloudflareAccountId + val cloudflareR2AccessKey = config.cloudflareR2AccessKeyId + val cloudflareR2SecretKey = config.cloudflareR2SecretKey + val cloudflareR2BucketName = config.cloudflareR2BucketName + val cloudflareR2PublicUrl = config.cloudflareR2PublicUrl } \ No newline at end of file diff --git a/src/main/kotlin/cn/rtast/fancybot/util/misc/ImageBed.kt b/src/main/kotlin/cn/rtast/fancybot/util/misc/ImageBed.kt index ed1c26b..f22808d 100644 --- a/src/main/kotlin/cn/rtast/fancybot/util/misc/ImageBed.kt +++ b/src/main/kotlin/cn/rtast/fancybot/util/misc/ImageBed.kt @@ -10,10 +10,18 @@ package cn.rtast.fancybot.util.misc import cn.rtast.fancybot.configManager import cn.rtast.fancybot.entity.github.UploadContentPayload import cn.rtast.fancybot.entity.github.UploadContentResponse +import cn.rtast.fancybot.enums.ImageBedType import cn.rtast.fancybot.util.Http import cn.rtast.fancybot.util.str.encodeToBase64 import cn.rtast.fancybot.util.str.proxy import cn.rtast.fancybot.util.str.toJson +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider +import software.amazon.awssdk.core.sync.RequestBody +import software.amazon.awssdk.regions.Region +import software.amazon.awssdk.services.s3.S3Client +import software.amazon.awssdk.services.s3.model.PutObjectRequest +import java.net.URI import java.util.UUID object ImageBed { @@ -21,12 +29,37 @@ object ImageBed { private val imageBedUrl = "https://api.github.com/repos/${configManager.githubUser}/${configManager.githubImageRepo}/contents".proxy + private val s3Client = this.createS3Client() + + private fun createS3Client(): S3Client { + val credentials = AwsBasicCredentials.create( + configManager.cloudflareR2AccessKey, + configManager.cloudflareR2SecretKey + ) + return S3Client.builder() + .region(Region.US_EAST_1) + .credentialsProvider(StaticCredentialsProvider.create(credentials)) + .endpointOverride(URI.create("https://${configManager.cloudflareAccountId}.r2.cloudflarestorage.com")) + .build() + } + fun upload(file: ByteArray, fileType: String = ""): String { - val body = UploadContentPayload("uploadImage", file.encodeToBase64()).toJson() - val response = Http.put( - "$imageBedUrl/${UUID.randomUUID()}${if (fileType.isNotBlank()) ".$fileType" else ""}", body, - mapOf("Authorization" to "Bearer ${configManager.githubKey}") - ).content.name - return "https://raw.githubusercontent.com/${configManager.githubUser}/${configManager.githubImageRepo}/refs/heads/main/$response".proxy + val randomUUID = UUID.randomUUID().toString() + if (configManager.imageBedType == ImageBedType.CloudflareR2) { + val key = "$randomUUID${if (fileType.isNotBlank()) ".$fileType" else ""}" + val putObjectRequest = PutObjectRequest.builder() + .bucket(configManager.cloudflareR2BucketName) + .key(key) + .build() + s3Client.putObject(putObjectRequest, RequestBody.fromBytes(file)) + return "${configManager.cloudflareR2PublicUrl}/$key" + } else { + val body = UploadContentPayload("uploadImage", file.encodeToBase64()).toJson() + val response = Http.put( + "$imageBedUrl/${randomUUID}${if (fileType.isNotBlank()) ".$fileType" else ""}", body, + mapOf("Authorization" to "Bearer ${configManager.githubKey}") + ).content.name + return "https://raw.githubusercontent.com/${configManager.githubUser}/${configManager.githubImageRepo}/refs/heads/main/$response".proxy + } } } \ No newline at end of file diff --git a/src/main/resources/config.json b/src/main/resources/config.json index b821c00..f805003 100644 --- a/src/main/resources/config.json +++ b/src/main/resources/config.json @@ -30,5 +30,11 @@ "selfId": 114514, "tianXingApiKey": "1145141919810", "githubUser": "RTAkland", - "githubImageRepo": "Static-Images" + "githubImageRepo": "Static-Images", + "imageBedType": "Github", + "cloudflareAccountId": "111", + "cloudflareR2AccessKeyId": "11111", + "cloudflareR2SecretKey": "222", + "cloudflareR2BucketName": "fancybot", + "cloudflareR2PublicUrl": "https://pub-2df243c8ff83452c9dcdd42c87b662a7.r2.dev" } \ No newline at end of file