diff --git a/src/grom.gleam b/src/grom.gleam index 2c9183b..fe1ba9d 100644 --- a/src/grom.gleam +++ b/src/grom.gleam @@ -21472,3 +21472,309 @@ pub fn get_guild_commands_response( ) -> Result(List(Command), RestError) { handle_response(response:, decode_with: decode.list(of: command_decoder())) } + +pub opaque type CreateGuildSlashCommand { + CreateGuildSlashCommand( + name: String, + name_localizations: Option(Dict(Locale, String)), + description: String, + description_localizations: Option(Dict(Locale, String)), + required_permissions: Option(List(Permission)), + options: List(SlashCommandOption), + is_nsfw: Bool, + ) +} + +pub fn create_guild_slash_command_to_json( + create: CreateGuildSlashCommand, +) -> Json { + // if discord adds another integration type ever im gonna be angwy + [ + Ok(#("type", json.int(1))), + Ok(#("name", json.string(create.name))), + optional_to_json(create.name_localizations, "name_localizations", json.dict( + _, + locale_to_string, + json.string, + )), + Ok(#("description", json.string(create.description))), + optional_to_json( + create.description_localizations, + "description_localizations", + json.dict(_, locale_to_string, json.string), + ), + Ok(#("options", json.array(create.options, slash_command_option_to_json))), + optional_to_json( + create.required_permissions, + "default_member_permissions", + flags_to_string_json(_, bits_permissions()), + ), + Ok(#("nsfw", json.bool(create.is_nsfw))), + ] + |> list_to_json_object +} + +/// Name must be between 1 and 32 characters. +/// +/// Description must be between 1 and 100 characters. +pub fn new_guild_slash_command( + named name: String, + with_description description: String, +) -> CreateGuildSlashCommand { + CreateGuildSlashCommand( + name:, + name_localizations: None, + description:, + description_localizations: None, + required_permissions: None, + options: [], + is_nsfw: False, + ) +} + +/// Name must be between 1 and 32 characters. +pub fn new_guild_slash_command_with_name_localizations( + create: CreateGuildSlashCommand, + localizations: Dict(Locale, String), +) -> CreateGuildSlashCommand { + CreateGuildSlashCommand(..create, name_localizations: Some(localizations)) +} + +/// Description must be between 1 and 100 characters. +pub fn new_guild_slash_command_with_description_localizations( + create: CreateGuildSlashCommand, + localizations: Dict(Locale, String), +) -> CreateGuildSlashCommand { + CreateGuildSlashCommand( + ..create, + description_localizations: Some(localizations), + ) +} + +/// Not using this function (default in `new`), will enable the command for everyone. +/// +/// Passing an empty list will disable the command for everyone. +/// +/// Passing a list with at least one permission will require those permissions to use the command. +pub fn new_guild_slash_command_with_required_permissions( + create: CreateGuildSlashCommand, + permissions: List(Permission), +) -> CreateGuildSlashCommand { + CreateGuildSlashCommand(..create, required_permissions: Some(permissions)) +} + +/// There is a limit of 25 options per command. +pub fn new_guild_slash_command_with_options( + create: CreateGuildSlashCommand, + options: List(SlashCommandOption), +) -> CreateGuildSlashCommand { + CreateGuildSlashCommand(..create, options:) +} + +/// This will only make the command usable in NSFW contexts. +pub fn new_nsfw_guild_slash_command( + create: CreateGuildSlashCommand, +) -> CreateGuildSlashCommand { + CreateGuildSlashCommand(..create, is_nsfw: True) +} + +/// Creating a command with the same name as an existing one will overwrite that command. +pub fn new_guild_slash_command_request( + token token: Token, + current_application_id application_id: Snowflake(Application), + guild_id guild_id: Snowflake(Guild), + using create: CreateGuildSlashCommand, +) -> Request(String) { + let body = create |> create_guild_slash_command_to_json |> json.to_string + + new_request( + token:, + to: "/applications/" + <> snowflake_to_string(application_id) + <> "/guilds/" + <> snowflake_to_string(guild_id) + <> "/commands", + method: http.Post, + ) + |> request.set_body(body) +} + +pub opaque type CreateGuildUserCommand { + CreateGuildUserCommand( + name: String, + name_localizations: Option(Dict(Locale, String)), + required_permissions: Option(List(Permission)), + is_nsfw: Bool, + ) +} + +pub fn create_guild_user_command_to_json( + create: CreateGuildUserCommand, +) -> Json { + // if discord adds another integration type ever im gonna be angwy + [ + Ok(#("type", json.int(2))), + Ok(#("name", json.string(create.name))), + optional_to_json(create.name_localizations, "name_localizations", json.dict( + _, + locale_to_string, + json.string, + )), + optional_to_json( + create.required_permissions, + "default_member_permissions", + flags_to_string_json(_, bits_permissions()), + ), + Ok(#("nsfw", json.bool(create.is_nsfw))), + ] + |> list_to_json_object +} + +/// Name must be between 1 and 32 characters. +pub fn new_guild_user_command(named name: String) -> CreateGuildUserCommand { + CreateGuildUserCommand( + name:, + name_localizations: None, + required_permissions: None, + is_nsfw: False, + ) +} + +/// Name must be between 1 and 32 characters. +pub fn new_guild_user_command_with_name_localizations( + create: CreateGuildUserCommand, + localizations: Dict(Locale, String), +) -> CreateGuildUserCommand { + CreateGuildUserCommand(..create, name_localizations: Some(localizations)) +} + +/// Not using this function (default in `new`), will enable the command for everyone. +/// +/// Passing an empty list will disable the command for everyone. +/// +/// Passing a list with at least one permission will require those permissions to use the command. +pub fn new_guild_user_command_with_required_permissions( + create: CreateGuildUserCommand, + permissions: List(Permission), +) -> CreateGuildUserCommand { + CreateGuildUserCommand(..create, required_permissions: Some(permissions)) +} + +/// This will only make the command usable in NSFW contexts. +pub fn new_nsfw_guild_user_command( + create: CreateGuildUserCommand, +) -> CreateGuildUserCommand { + CreateGuildUserCommand(..create, is_nsfw: True) +} + +/// Creating a command with the same name as an existing one will overwrite that command. +pub fn new_guild_user_command_request( + token token: Token, + current_application_id application_id: Snowflake(Application), + guild_id guild_id: Snowflake(Guild), + using create: CreateGuildUserCommand, +) -> Request(String) { + let body = create |> create_guild_user_command_to_json |> json.to_string + + new_request( + token:, + to: "/applications/" + <> snowflake_to_string(application_id) + <> "/guilds/" + <> snowflake_to_string(guild_id) + <> "/commands", + method: http.Post, + ) + |> request.set_body(body) +} + +pub opaque type CreateGuildMessageCommand { + CreateGuildMessageCommand( + name: String, + name_localizations: Option(Dict(Locale, String)), + required_permissions: Option(List(Permission)), + is_nsfw: Bool, + ) +} + +pub fn create_guild_message_command_to_json( + create: CreateGuildMessageCommand, +) -> Json { + // if discord adds another integration type ever im gonna be angwy + [ + Ok(#("type", json.int(3))), + Ok(#("name", json.string(create.name))), + optional_to_json(create.name_localizations, "name_localizations", json.dict( + _, + locale_to_string, + json.string, + )), + optional_to_json( + create.required_permissions, + "default_member_permissions", + flags_to_string_json(_, bits_permissions()), + ), + Ok(#("nsfw", json.bool(create.is_nsfw))), + ] + |> list_to_json_object +} + +/// Name must be between 1 and 32 characters. +pub fn new_guild_message_command( + named name: String, +) -> CreateGuildMessageCommand { + CreateGuildMessageCommand( + name:, + name_localizations: None, + required_permissions: None, + is_nsfw: False, + ) +} + +/// Name must be between 1 and 32 characters. +pub fn new_guild_message_command_with_name_localizations( + create: CreateGuildMessageCommand, + localizations: Dict(Locale, String), +) -> CreateGuildMessageCommand { + CreateGuildMessageCommand(..create, name_localizations: Some(localizations)) +} + +/// Not using this function (default in `new`), will enable the command for everyone. +/// +/// Passing an empty list will disable the command for everyone. +/// +/// Passing a list with at least one permission will require those permissions to use the command. +pub fn new_guild_message_command_with_required_permissions( + create: CreateGuildMessageCommand, + permissions: List(Permission), +) -> CreateGuildMessageCommand { + CreateGuildMessageCommand(..create, required_permissions: Some(permissions)) +} + +/// This will only make the command usable in NSFW contexts. +pub fn new_nsfw_guild_message_command( + create: CreateGuildMessageCommand, +) -> CreateGuildMessageCommand { + CreateGuildMessageCommand(..create, is_nsfw: True) +} + +/// Creating a command with the same name as an existing one will overwrite that command. +pub fn new_guild_message_command_request( + token token: Token, + current_application_id application_id: Snowflake(Application), + guild_id guild_id: Snowflake(Guild), + using create: CreateGuildMessageCommand, +) -> Request(String) { + let body = create |> create_guild_message_command_to_json |> json.to_string + + new_request( + token:, + to: "/applications/" + <> snowflake_to_string(application_id) + <> "/guilds/" + <> snowflake_to_string(guild_id) + <> "/commands", + method: http.Post, + ) + |> request.set_body(body) +}