Skip to content

Commit

Permalink
Add New webhook endpoints (#217)
Browse files Browse the repository at this point in the history
* Add New webhook endpoints (discord/discord-api-docs#2243)
Relates to #121

* Make EditWebhookMessageBuilder.embeds a list of builders

* Remove webhookId from behavior

* Remove inapropriate docs

* Formatting

* Fix some formatting

* Fix some more  formatting

* Fix style issue in Route.kt

* Add test
  • Loading branch information
DRSchlaubi authored Apr 16, 2021
1 parent ce7f0a1 commit 5eb7aa2
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 8 deletions.
36 changes: 35 additions & 1 deletion core/src/main/kotlin/behavior/MessageBehavior.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import dev.kord.core.supplier.getChannelOf
import dev.kord.core.supplier.getChannelOfOrNull
import dev.kord.rest.builder.message.MessageCreateBuilder
import dev.kord.rest.builder.message.MessageModifyBuilder
import dev.kord.rest.builder.webhook.EditWebhookMessageBuilder
import dev.kord.rest.request.RestRequestException
import dev.kord.rest.service.RestClient
import kotlinx.coroutines.flow.Flow
Expand Down Expand Up @@ -217,13 +218,46 @@ fun MessageBehavior(
* @return The edited [Message].
*
* @throws [RestRequestException] if something went wrong during the request.
* @see editWebhookMessage
*/
@OptIn(ExperimentalContracts::class)
suspend inline fun MessageBehavior.edit(builder: MessageModifyBuilder.() -> Unit): Message {
contract {
callsInPlace(builder, InvocationKind.EXACTLY_ONCE)
}
val response = kord.rest.channel.editMessage(channelId = channelId, messageId = id, builder = builder)

val response =
kord.rest.channel.editMessage(channelId = channelId, messageId = id, builder = builder)
val data = MessageData.from(response)

return Message(data, kord)
}

/**
* Requests to edit this message.
*
* @return The edited [Message].
*
* @throws [RestRequestException] if something went wrong during the request.
* @see edit
*/
@OptIn(ExperimentalContracts::class)
suspend inline fun MessageBehavior.editWebhookMessage(
webhookId: Snowflake,
token: String,
builder: EditWebhookMessageBuilder.() -> Unit
): Message {
contract {
callsInPlace(builder, InvocationKind.EXACTLY_ONCE)
}

val response =
kord.rest.webhook.editWebhookMessage(
webhookId = webhookId,
messageId = id,
token = token,
builder = builder
)
val data = MessageData.from(response)

return Message(data, kord)
Expand Down
1 change: 0 additions & 1 deletion core/src/main/kotlin/entity/channel/MessageChannel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import dev.kord.core.behavior.channel.MessageChannelBehavior
import dev.kord.core.entity.Message
import dev.kord.core.supplier.EntitySupplyStrategy
import dev.kord.core.toInstant
import dev.kord.core.toSnowflakeOrNull
import java.time.Instant

/**
Expand Down
14 changes: 11 additions & 3 deletions core/src/test/kotlin/rest/RestTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,14 @@ class RestServiceTest {
content = "hello world!"
}

val message = webhook.execute(webhook.token!!) {
content = "a"
}

message.editWebhookMessage(webhook.id, webhook.token!!) {
content = "b"
}

webhook.delete(reason = "test")
Unit
}
Expand Down Expand Up @@ -438,16 +446,16 @@ class RestServiceTest {
val textChannel = guild.createTextChannel("move me to a category")

guild.swapChannelPositions {
move(textChannel.id){ parentId = category.id }
move(textChannel.id) { parentId = category.id }
}

val currentTextChannel = guild.getChannelOf<TextChannel>(textChannel.id)
assertEquals(category.id,currentTextChannel.categoryId)
assertEquals(category.id, currentTextChannel.categoryId)
}

@OptIn(KordPreview::class)
fun `guild application commands`(): Unit = runBlocking {
val command = guild.createApplicationCommand("test", "automated test"){
val command = guild.createApplicationCommand("test", "automated test") {
group("test-group", "automated test") {
subCommand("test-sub-command", "automated test") {
int("integer", "test choice") {
Expand Down
34 changes: 34 additions & 0 deletions rest/src/main/kotlin/builder/webhook/EditWebhookMessageBuilder.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package dev.kord.rest.builder.webhook

import dev.kord.common.entity.AllowedMentions
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.WebhookEditMessageRequest
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract

class EditWebhookMessageBuilder : RequestBuilder<WebhookEditMessageRequest> {

private var _content: Optional<String> = Optional.Missing()
var content: String? by ::_content.delegate()

var embeds: MutableList<EmbedBuilder> = mutableListOf()

private var _allowedMentions: Optional<AllowedMentions> = Optional.Missing()
var allowedMentions: AllowedMentions? by ::_allowedMentions.delegate()

@OptIn(ExperimentalContracts::class)
inline fun embed(builder: EmbedBuilder.() -> Unit) {
contract {
callsInPlace(builder, InvocationKind.EXACTLY_ONCE)
}
embeds.add(EmbedBuilder().apply(builder))
}

override fun toRequest(): WebhookEditMessageRequest = WebhookEditMessageRequest(
_content, Optional.missingOnEmpty(embeds.map(EmbedBuilder::toRequest)), _allowedMentions
)
}
2 changes: 1 addition & 1 deletion rest/src/main/kotlin/json/request/MessageRequests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ data class EmbedFieldRequest(
data class MessageEditPatchRequest(
val content: Optional<String?> = Optional.Missing(),
val embed: Optional<EmbedRequest?> = Optional.Missing(),
val flags: Optional<UserFlags?> = Optional.Missing(),
val flags: Optional<MessageFlags?> = Optional.Missing(),
@SerialName("allowed_mentions")
val allowedMentions: Optional<AllowedMentions?> = Optional.Missing(),
)
Expand Down
9 changes: 8 additions & 1 deletion rest/src/main/kotlin/json/request/WebhookRequests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,11 @@ data class WebhookExecuteRequest(
data class MultiPartWebhookExecuteRequest(
val request: WebhookExecuteRequest,
val file: Pair<String, java.io.InputStream>?
)
)

@Serializable
data class WebhookEditMessageRequest(
val content: Optional<String> = Optional.Missing(),
val embeds: Optional<List<EmbedRequest>> = Optional.Missing(),
val allowedMentions: Optional<AllowedMentions> = Optional.Missing()
)
7 changes: 6 additions & 1 deletion rest/src/main/kotlin/route/Route.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import dev.kord.common.annotation.KordExperimental
import dev.kord.common.annotation.KordPreview
import dev.kord.common.entity.*
import dev.kord.rest.json.optional
import dev.kord.rest.json.request.MessageEditPatchRequest
import dev.kord.rest.json.response.*
import io.ktor.http.*
import kotlinx.serialization.DeserializationStrategy
Expand Down Expand Up @@ -427,6 +426,12 @@ sealed class Route<T>(
object ExecuteGithubWebhookPost
: Route<Unit>(HttpMethod.Post, "/webhooks/$WebhookId/$WebhookToken", NoStrategy)

object EditWebhookMessage : Route<DiscordMessage>(
HttpMethod.Patch,
"/webhooks/$WebhookId/$WebhookToken/messages/$MessageId",
DiscordMessage.serializer()
)

object VoiceRegionsGet
: Route<List<DiscordVoiceRegion>>(
HttpMethod.Get,
Expand Down
23 changes: 23 additions & 0 deletions rest/src/main/kotlin/service/WebhookService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import dev.kord.common.annotation.KordExperimental
import dev.kord.common.entity.DiscordMessage
import dev.kord.common.entity.DiscordWebhook
import dev.kord.common.entity.Snowflake
import dev.kord.rest.builder.webhook.EditWebhookMessageBuilder
import dev.kord.rest.builder.webhook.ExecuteWebhookBuilder
import dev.kord.rest.builder.webhook.WebhookCreateBuilder
import dev.kord.rest.builder.webhook.WebhookModifyBuilder
import dev.kord.rest.json.request.WebhookCreateRequest
import dev.kord.rest.json.request.WebhookEditMessageRequest
import dev.kord.rest.json.request.WebhookExecuteRequest
import dev.kord.rest.json.request.WebhookModifyRequest
import dev.kord.rest.request.RequestHandler
Expand Down Expand Up @@ -137,4 +139,25 @@ class WebhookService(requestHandler: RequestHandler) : RestService(requestHandle
parameter("wait", "$wait")
body(JsonObject.serializer(), body)
}

@OptIn(ExperimentalContracts::class)
suspend inline fun editWebhookMessage(
webhookId: Snowflake,
token: String,
messageId: Snowflake,
builder: EditWebhookMessageBuilder.() -> Unit
): DiscordMessage {
contract {
callsInPlace(builder, InvocationKind.EXACTLY_ONCE)
}

return call(Route.EditWebhookMessage) {

keys[Route.WebhookId] = webhookId
keys[Route.WebhookToken] = token
keys[Route.MessageId] = messageId
val body = EditWebhookMessageBuilder().apply(builder).toRequest()
body(WebhookEditMessageRequest.serializer(), body)
}
}
}

0 comments on commit 5eb7aa2

Please sign in to comment.