diff --git a/lib/nosedrum/application_command.ex b/lib/nosedrum/application_command.ex index 478f96d..4b6912f 100644 --- a/lib/nosedrum/application_command.ex +++ b/lib/nosedrum/application_command.ex @@ -289,5 +289,36 @@ defmodule Nosedrum.ApplicationCommand do """ @callback command(interaction :: Interaction.t()) :: response + + @typedoc """ + Application command optional properties. + See [official Discord documentation](https://discord.com/developers/docs/interactions/application-commands#application-command-object) + """ + @type application_command :: %{ + optional(:description_localizations) => map(), + optional(:default_member_permissions) => non_neg_integer() | [Nostrum.Permission.t], + optional(:dm_permission) => boolean(), # only for globally-scoped commands + optional(:default_permission) => boolean(), #Not recommended for use as field will soon be deprecated. + optional(:nsfw) => boolean() + } + + @doc """ + An optional callback that returns a map contains optioanl properties of slash application command. + Used when registering the command with Discord. Only valid for + CHAT_INPUT application commands, aka slash commands. + + Read more in the official + [Application Command documentation](https://discord.com/developers/docs/interactions/application-commands#application-command-object). + + ## Example + ```elixir + def command_schema_options(), do: + %{ + default_member_permissions: 8 + } + ``` + """ + @callback command_schema_options() :: application_command() + @optional_callbacks [options: 0] end diff --git a/lib/nosedrum/storage/dispatcher.ex b/lib/nosedrum/storage/dispatcher.ex index 13c15f7..682d499 100644 --- a/lib/nosedrum/storage/dispatcher.ex +++ b/lib/nosedrum/storage/dispatcher.ex @@ -170,13 +170,31 @@ defmodule Nosedrum.Storage.Dispatcher do [] end + command_schema_options = + if function_exported?(command, :command_schema_options, 0) do + command.command_schema_options() + |> handle_default_member_permissions() + else + %{} + end + %{ type: parse_type(command.type()), name: name } |> put_type_specific_fields(command, options) + |> Map.merge(command_schema_options) end + defp handle_default_member_permissions(%{default_member_permissions: default_member_permissions} = data) + when is_list(default_member_permissions), do: + %{data | default_member_permissions: Nostrum.Permission.to_bitset(default_member_permissions)} + + defp handle_default_member_permissions(%{default_member_permissions: default_member_permissions} = data) + when is_integer(default_member_permissions), do: data + + defp handle_default_member_permissions(data), do: data + # This seems like a hacky way to unwrap the outer list... defp build_payload(path, command) do build_payload({path, command})