Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add New webhook endpoints #217

Merged
merged 10 commits into from
Apr 16, 2021
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
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)
}
}
}