From f0c8f1ad01bcffb685bf24c931d9907fa728727e Mon Sep 17 00:00:00 2001 From: fhoffmann Date: Wed, 16 Sep 2026 22:12:11 +0200 Subject: [PATCH] responding to message component interactions --- src/grom.gleam | 130 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/src/grom.gleam b/src/grom.gleam index 4d7c86c..b447664 100644 --- a/src/grom.gleam +++ b/src/grom.gleam @@ -26250,3 +26250,133 @@ pub fn new_default_selected_modal_checkbox( ) -> CreateModalCheckbox { CreateModalCheckbox(..create, is_default_selected: True) } + +pub opaque type MessageComponentInteractionResponse { + MessageComponentInteractionResponseMessage( + message: InteractionResponseMessage, + ) + MessageComponentInteractionResponseDeferMessage(is_ephemeral: Bool) + MessageComponentInteractionResponseDeferMessageUpdate + MessageComponentInteractionResponseMessageUpdate( + message: InteractionResponseMessage, + ) + MessageComponentInteractionResponseModal(modal: InteractionResponseModal) +} + +pub fn message_component_interaction_response_to_json( + response: MessageComponentInteractionResponse, +) -> Json { + case response { + MessageComponentInteractionResponseMessage(message:) -> + [ + #("type", json.int(4)), + #("data", interaction_response_message_to_json(message)), + ] + |> json.object + MessageComponentInteractionResponseDeferMessage(is_ephemeral:) -> + [ + Ok(#("type", json.int(5))), + case is_ephemeral { + True -> + Ok(#( + "data", + json.object([#("flags", json.int(int.bitwise_shift_left(1, 6)))]), + )) + False -> Error(Nil) + }, + ] + |> list_to_json_object + MessageComponentInteractionResponseDeferMessageUpdate -> + [#("type", json.int(6))] + |> json.object + MessageComponentInteractionResponseMessageUpdate(message:) -> + [ + #("type", json.int(7)), + #("data", interaction_response_message_to_json(message)), + ] + |> json.object + MessageComponentInteractionResponseModal(modal:) -> + [ + #("type", json.int(9)), + #("data", interaction_response_modal_to_json(modal)), + ] + |> json.object + } +} + +/// Responds by replying to the original component's message. +pub fn respond_to_message_component_interaction_with_message( + message: InteractionResponseMessage, +) -> MessageComponentInteractionResponse { + MessageComponentInteractionResponseMessage(message:) +} + +/// Responds by replying to the original component's message with a "thinking" state. +/// +/// Gives you 15 minutes to edit the response, will create a reply message after editing. +pub fn defer_message_component_interaction_message_response( + is_ephemeral is_ephemeral: Bool, +) -> MessageComponentInteractionResponse { + MessageComponentInteractionResponseDeferMessage(is_ephemeral:) +} + +/// Responds by acknowledging the interaction and pledging to edit the original message within 15 minutes. +pub fn defer_message_component_interaction_message_update_response() -> MessageComponentInteractionResponse { + MessageComponentInteractionResponseDeferMessageUpdate +} + +/// Responds by editing the original component's message. +pub fn respond_to_message_component_interaction_with_message_update( + message: InteractionResponseMessage, +) -> MessageComponentInteractionResponse { + MessageComponentInteractionResponseMessageUpdate(message:) +} + +pub fn respond_to_message_component_interaction_with_modal( + modal: InteractionResponseModal, +) -> MessageComponentInteractionResponse { + MessageComponentInteractionResponseModal(modal:) +} + +pub fn respond_to_message_component_interaction_request( + token token: Token, + id interaction_id: Snowflake(Interaction), + interaction_token interaction_token: MessageComponentInteractionToken, + with response: MessageComponentInteractionResponse, +) -> Request(BitArray) { + let json = + response |> message_component_interaction_response_to_json |> json.to_string + + let request = + new_request( + token:, + to: "/interactions/" + <> snowflake_to_string(interaction_id) + <> "/" + <> interaction_token.token + <> "/callback", + method: http.Post, + ) + |> request.set_body(json) + |> request.map(bit_array.from_string) + + case response { + MessageComponentInteractionResponseMessage(message:) + | MessageComponentInteractionResponseMessageUpdate(message:) -> + case message.attachments { + Some(attachments) -> + request + |> multipart_request(json:, attachments:) + None -> request + } + MessageComponentInteractionResponseDeferMessage(_) + | MessageComponentInteractionResponseDeferMessageUpdate + | MessageComponentInteractionResponseModal(_) -> request + } +} + +pub fn respond_to_message_component_interaction_response( + response: Response(BitArray), +) -> Result(Nil, RestError) { + handle_no_content_response_bits(response) +} -- 2.51.2