From 6b491e6c9cef18b78c277fcb7b46bdbd7f1d0ec2 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Mon, 5 Apr 2021 22:38:49 +0300 Subject: [PATCH 1/6] Add webhook execution multiple file support --- .../builder/webhook/ExecuteWebhookBuilder.kt | 19 ++++++++++--------- .../kotlin/json/request/WebhookRequests.kt | 4 ++-- .../src/main/kotlin/service/WebhookService.kt | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/rest/src/main/kotlin/builder/webhook/ExecuteWebhookBuilder.kt b/rest/src/main/kotlin/builder/webhook/ExecuteWebhookBuilder.kt index 64c9b22c4d7..7e4d14015ee 100644 --- a/rest/src/main/kotlin/builder/webhook/ExecuteWebhookBuilder.kt +++ b/rest/src/main/kotlin/builder/webhook/ExecuteWebhookBuilder.kt @@ -11,6 +11,7 @@ import dev.kord.rest.json.request.MultiPartWebhookExecuteRequest import dev.kord.rest.json.request.WebhookExecuteRequest import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import java.io.InputStream import java.nio.file.Files import java.nio.file.Path import kotlin.contracts.ExperimentalContracts @@ -18,7 +19,7 @@ import kotlin.contracts.InvocationKind import kotlin.contracts.contract @KordDsl -class ExecuteWebhookBuilder : RequestBuilder { +class ExecuteWebhookBuilder: RequestBuilder { private var _content: Optional = Optional.Missing() var content: String? by ::_content.delegate() @@ -32,17 +33,17 @@ class ExecuteWebhookBuilder : RequestBuilder { private var _tts: OptionalBoolean = OptionalBoolean.Missing var tts: Boolean? by ::_tts.delegate() - private var file: Pair? = null + val files: MutableList> = mutableListOf() + var embeds: MutableList = mutableListOf() - fun setFile(name: String, content: java.io.InputStream) { - file = name to content + fun addFile(name: String, content: InputStream) { + files += name to content } - suspend fun setFile(path: Path) = withContext(Dispatchers.IO) { - setFile(path.fileName.toString(), Files.newInputStream(path)) + suspend fun addFile(path: Path) = withContext(Dispatchers.IO) { + addFile(path.fileName.toString(), Files.newInputStream(path)) } - @OptIn(ExperimentalContracts::class) inline fun embed(builder: EmbedBuilder.() -> Unit) { contract { @@ -51,8 +52,8 @@ class ExecuteWebhookBuilder : RequestBuilder { embeds.add(EmbedBuilder().apply(builder).toRequest()) } - override fun toRequest(): MultiPartWebhookExecuteRequest = MultiPartWebhookExecuteRequest( - WebhookExecuteRequest(_content, _username, _avatarUrl, _tts, Optional.missingOnEmpty(embeds)), file + override fun toRequest() : MultiPartWebhookExecuteRequest = MultiPartWebhookExecuteRequest( + WebhookExecuteRequest(_content, _username, _avatarUrl, _tts, Optional.missingOnEmpty(embeds)), files ) } diff --git a/rest/src/main/kotlin/json/request/WebhookRequests.kt b/rest/src/main/kotlin/json/request/WebhookRequests.kt index 53117036457..1b39e74f34b 100644 --- a/rest/src/main/kotlin/json/request/WebhookRequests.kt +++ b/rest/src/main/kotlin/json/request/WebhookRequests.kt @@ -30,8 +30,8 @@ data class WebhookExecuteRequest( ) data class MultiPartWebhookExecuteRequest( - val request: WebhookExecuteRequest, - val file: Pair? + val request: WebhookExecuteRequest, + val files: List> = emptyList() ) @Serializable diff --git a/rest/src/main/kotlin/service/WebhookService.kt b/rest/src/main/kotlin/service/WebhookService.kt index 3487961f743..2f4d6be7229 100644 --- a/rest/src/main/kotlin/service/WebhookService.kt +++ b/rest/src/main/kotlin/service/WebhookService.kt @@ -118,7 +118,7 @@ class WebhookService(requestHandler: RequestHandler) : RestService(requestHandle parameter("wait", "$wait") val request = ExecuteWebhookBuilder().apply(builder).toRequest() body(WebhookExecuteRequest.serializer(), request.request) - request.file?.let { file(it) } + request.files.forEach { file(it) } } } From d13200c5b8660d4edd3e3ee20376eead0ac7483e Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Mon, 5 Apr 2021 22:39:45 +0300 Subject: [PATCH 2/6] Add interaction modify multiple file support [publish skip] --- .../main/kotlin/json/request/InteractionsRequests.kt | 10 ++++++++-- rest/src/main/kotlin/service/InteractionService.kt | 5 +++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/rest/src/main/kotlin/json/request/InteractionsRequests.kt b/rest/src/main/kotlin/json/request/InteractionsRequests.kt index 7092bebd174..920985147d6 100644 --- a/rest/src/main/kotlin/json/request/InteractionsRequests.kt +++ b/rest/src/main/kotlin/json/request/InteractionsRequests.kt @@ -9,7 +9,6 @@ import dev.kord.common.entity.optional.Optional import dev.kord.common.entity.optional.OptionalBoolean import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import java.io.InputStream @Serializable @KordPreview @@ -93,4 +92,11 @@ data class FollowupMessageModifyRequest( val embeds: Optional> = Optional.Missing(), @SerialName("allowed_mentions") val allowedMentions: Optional = Optional.Missing(), -) \ No newline at end of file +) + +@KordPreview +data class MultipartFollowupMessageModifyRequest( + val request: FollowupMessageModifyRequest, + val files: List> = emptyList(), + + ) \ No newline at end of file diff --git a/rest/src/main/kotlin/service/InteractionService.kt b/rest/src/main/kotlin/service/InteractionService.kt index b846bfbbb23..1c2f54dffac 100644 --- a/rest/src/main/kotlin/service/InteractionService.kt +++ b/rest/src/main/kotlin/service/InteractionService.kt @@ -168,12 +168,13 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa applicationId: Snowflake, interactionToken: String, messageId: Snowflake, - request: FollowupMessageModifyRequest + request: MultipartFollowupMessageModifyRequest ) = call(Route.FollowupMessageModify) { keys[Route.ApplicationId] = applicationId keys[Route.InteractionToken] = interactionToken keys[Route.MessageId] = messageId - body(FollowupMessageModifyRequest.serializer(), request) + body(FollowupMessageModifyRequest.serializer(), request.request) + request.files.forEach { file(it) } } suspend fun getGlobalCommand(applicationId: Snowflake, commandId: Snowflake) = From bf77b10ccfa54fc4e2e3a9196bbde2316b877390 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Sat, 17 Apr 2021 07:01:10 +0300 Subject: [PATCH 3/6] Webhook patch multipart support --- .../webhook/EditWebhookMessageBuilder.kt | 26 ++++++++++++++++--- .../kotlin/json/request/WebhookRequests.kt | 5 ++++ .../src/main/kotlin/service/WebhookService.kt | 3 ++- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/rest/src/main/kotlin/builder/webhook/EditWebhookMessageBuilder.kt b/rest/src/main/kotlin/builder/webhook/EditWebhookMessageBuilder.kt index 0cbdcd13e40..4f1d3a8f7b2 100644 --- a/rest/src/main/kotlin/builder/webhook/EditWebhookMessageBuilder.kt +++ b/rest/src/main/kotlin/builder/webhook/EditWebhookMessageBuilder.kt @@ -5,18 +5,26 @@ import dev.kord.common.entity.optional.Optional import dev.kord.common.entity.optional.delegate.delegate import dev.kord.rest.builder.RequestBuilder import dev.kord.rest.builder.message.EmbedBuilder +import dev.kord.rest.json.request.MultipartWebhookEditMessageRequest import dev.kord.rest.json.request.WebhookEditMessageRequest +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import java.io.InputStream +import java.nio.file.Files +import java.nio.file.Path import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind import kotlin.contracts.contract -class EditWebhookMessageBuilder : RequestBuilder { +class EditWebhookMessageBuilder : RequestBuilder { private var _content: Optional = Optional.Missing() var content: String? by ::_content.delegate() var embeds: MutableList = mutableListOf() + val files: MutableList> = mutableListOf() + private var _allowedMentions: Optional = Optional.Missing() var allowedMentions: AllowedMentions? by ::_allowedMentions.delegate() @@ -28,7 +36,19 @@ class EditWebhookMessageBuilder : RequestBuilder { embeds.add(EmbedBuilder().apply(builder)) } - override fun toRequest(): WebhookEditMessageRequest = WebhookEditMessageRequest( - _content, Optional.missingOnEmpty(embeds.map(EmbedBuilder::toRequest)), _allowedMentions + fun addFile(name: String, content: InputStream) { + files += name to content + } + + suspend fun addFile(path: Path) = withContext(Dispatchers.IO) { + addFile(path.fileName.toString(), Files.newInputStream(path)) + } + + + override fun toRequest(): MultipartWebhookEditMessageRequest = MultipartWebhookEditMessageRequest( + WebhookEditMessageRequest( + _content, Optional.missingOnEmpty(embeds.map(EmbedBuilder::toRequest)), _allowedMentions + ), + files ) } diff --git a/rest/src/main/kotlin/json/request/WebhookRequests.kt b/rest/src/main/kotlin/json/request/WebhookRequests.kt index 1b39e74f34b..618ec531885 100644 --- a/rest/src/main/kotlin/json/request/WebhookRequests.kt +++ b/rest/src/main/kotlin/json/request/WebhookRequests.kt @@ -40,3 +40,8 @@ data class WebhookEditMessageRequest( val embeds: Optional> = Optional.Missing(), val allowedMentions: Optional = Optional.Missing() ) + +data class MultipartWebhookEditMessageRequest( + val request: WebhookEditMessageRequest, + val files: List> = emptyList() +) diff --git a/rest/src/main/kotlin/service/WebhookService.kt b/rest/src/main/kotlin/service/WebhookService.kt index 2f4d6be7229..c6724a44f95 100644 --- a/rest/src/main/kotlin/service/WebhookService.kt +++ b/rest/src/main/kotlin/service/WebhookService.kt @@ -157,7 +157,8 @@ class WebhookService(requestHandler: RequestHandler) : RestService(requestHandle keys[Route.WebhookToken] = token keys[Route.MessageId] = messageId val body = EditWebhookMessageBuilder().apply(builder).toRequest() - body(WebhookEditMessageRequest.serializer(), body) + body(WebhookEditMessageRequest.serializer(), body.request) + body.files.onEach { file(it) } } } } \ No newline at end of file From 4f8240c6824654838721c7e6d2213b9eed909df7 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Sat, 17 Apr 2021 17:55:50 +0300 Subject: [PATCH 4/6] allow multipart public follow-up message edits --- .../interaction/FollowupMessageBuilders.kt | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/rest/src/main/kotlin/builder/interaction/FollowupMessageBuilders.kt b/rest/src/main/kotlin/builder/interaction/FollowupMessageBuilders.kt index f5b3fa8a265..3d5152158e3 100644 --- a/rest/src/main/kotlin/builder/interaction/FollowupMessageBuilders.kt +++ b/rest/src/main/kotlin/builder/interaction/FollowupMessageBuilders.kt @@ -6,15 +6,11 @@ import dev.kord.common.entity.AllowedMentions import dev.kord.common.entity.optional.Optional import dev.kord.common.entity.optional.OptionalBoolean import dev.kord.common.entity.optional.delegate.delegate -import dev.kord.common.entity.optional.map import dev.kord.common.entity.optional.mapList import dev.kord.rest.builder.RequestBuilder import dev.kord.rest.builder.message.AllowedMentionsBuilder import dev.kord.rest.builder.message.EmbedBuilder -import dev.kord.rest.json.request.EmbedRequest -import dev.kord.rest.json.request.FollowupMessageCreateRequest -import dev.kord.rest.json.request.FollowupMessageModifyRequest -import dev.kord.rest.json.request.MultipartFollowupMessageCreateRequest +import dev.kord.rest.json.request.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.io.InputStream @@ -27,13 +23,16 @@ import kotlin.contracts.contract @KordPreview @KordDsl class PublicFollowupMessageModifyBuilder : - RequestBuilder { + RequestBuilder { private var _content: Optional = Optional.Missing() var content: String? by ::_content.delegate() private var _embeds: Optional> = Optional.Missing() var embeds: MutableList? by ::_embeds.delegate() + val files: MutableList> = mutableListOf() + + private var _allowedMentions: Optional = Optional.Missing() var allowedMentions: AllowedMentions? by ::_allowedMentions.delegate() @@ -44,6 +43,15 @@ class PublicFollowupMessageModifyBuilder : embeds!! += EmbedBuilder().apply(builder) } + + fun addFile(name: String, content: InputStream) { + files += name to content + } + + suspend fun addFile(path: Path) = withContext(Dispatchers.IO) { + addFile(path.fileName.toString(), Files.newInputStream(path)) + } + @OptIn(ExperimentalContracts::class) inline fun allowedMentions(builder: AllowedMentionsBuilder.() -> Unit) { contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } @@ -51,11 +59,14 @@ class PublicFollowupMessageModifyBuilder : } - override fun toRequest(): FollowupMessageModifyRequest { - return FollowupMessageModifyRequest( - _content, - _embeds.mapList { it.toRequest() }, - _allowedMentions + override fun toRequest(): MultipartFollowupMessageModifyRequest { + return MultipartFollowupMessageModifyRequest( + FollowupMessageModifyRequest( + _content, + _embeds.mapList { it.toRequest() }, + _allowedMentions + ), + files ) } } From 1382e69e6d97bc783da3cc5ef7c2d2475acf6f03 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Sat, 17 Apr 2021 18:17:41 +0300 Subject: [PATCH 5/6] Fix compilation errors --- .../kotlin/json/request/InteractionsRequests.kt | 1 + rest/src/main/kotlin/service/InteractionService.kt | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/rest/src/main/kotlin/json/request/InteractionsRequests.kt b/rest/src/main/kotlin/json/request/InteractionsRequests.kt index 920985147d6..0b0f42811d2 100644 --- a/rest/src/main/kotlin/json/request/InteractionsRequests.kt +++ b/rest/src/main/kotlin/json/request/InteractionsRequests.kt @@ -9,6 +9,7 @@ import dev.kord.common.entity.optional.Optional import dev.kord.common.entity.optional.OptionalBoolean import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import java.io.InputStream @Serializable @KordPreview diff --git a/rest/src/main/kotlin/service/InteractionService.kt b/rest/src/main/kotlin/service/InteractionService.kt index 1c2f54dffac..0614b3c6322 100644 --- a/rest/src/main/kotlin/service/InteractionService.kt +++ b/rest/src/main/kotlin/service/InteractionService.kt @@ -177,6 +177,19 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa request.files.forEach { file(it) } } + + suspend fun modifyFollowupMessage( + applicationId: Snowflake, + interactionToken: String, + messageId: Snowflake, + request: FollowupMessageModifyRequest + ) = call(Route.FollowupMessageModify) { + keys[Route.ApplicationId] = applicationId + keys[Route.InteractionToken] = interactionToken + keys[Route.MessageId] = messageId + body(FollowupMessageModifyRequest.serializer(), request) + } + suspend fun getGlobalCommand(applicationId: Snowflake, commandId: Snowflake) = call(Route.GlobalApplicationCommandGet) { keys[Route.ApplicationId] = applicationId From 7bdf4539b95a33049c3c2fed2e0ac064fd41de19 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Sat, 17 Apr 2021 18:43:23 +0300 Subject: [PATCH 6/6] format files --- rest/src/main/kotlin/builder/webhook/ExecuteWebhookBuilder.kt | 1 + rest/src/main/kotlin/json/request/InteractionsRequests.kt | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rest/src/main/kotlin/builder/webhook/ExecuteWebhookBuilder.kt b/rest/src/main/kotlin/builder/webhook/ExecuteWebhookBuilder.kt index 7e4d14015ee..67b8fc7e8c6 100644 --- a/rest/src/main/kotlin/builder/webhook/ExecuteWebhookBuilder.kt +++ b/rest/src/main/kotlin/builder/webhook/ExecuteWebhookBuilder.kt @@ -44,6 +44,7 @@ class ExecuteWebhookBuilder: RequestBuilder { suspend fun addFile(path: Path) = withContext(Dispatchers.IO) { addFile(path.fileName.toString(), Files.newInputStream(path)) } + @OptIn(ExperimentalContracts::class) inline fun embed(builder: EmbedBuilder.() -> Unit) { contract { diff --git a/rest/src/main/kotlin/json/request/InteractionsRequests.kt b/rest/src/main/kotlin/json/request/InteractionsRequests.kt index 0b0f42811d2..2d613e0d610 100644 --- a/rest/src/main/kotlin/json/request/InteractionsRequests.kt +++ b/rest/src/main/kotlin/json/request/InteractionsRequests.kt @@ -99,5 +99,4 @@ data class FollowupMessageModifyRequest( data class MultipartFollowupMessageModifyRequest( val request: FollowupMessageModifyRequest, val files: List> = emptyList(), - - ) \ No newline at end of file +) \ No newline at end of file