Skip to content

Commit

Permalink
Merge pull request #34 from kshannoninnes/feature/bulk-register-commands
Browse files Browse the repository at this point in the history
Change from many create_*_application_command requests to a single bulk_overwrite_*_application_commands request
  • Loading branch information
jchristgit authored Apr 27, 2024
2 parents 0148c70 + 1aaf165 commit a6db8c6
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
31 changes: 31 additions & 0 deletions lib/nosedrum/storage.ex
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,29 @@ defmodule Nosedrum.Storage do
| {:error, :unknown_command}
| Nostrum.Api.error()

@doc """
Queues a new command to be registered under the given name or application command path. Queued commands are
added to the internal dispatch storage, and will be registered in bulk upon calling process_queue/1
If any command already exists, it will be overwritten.
## Return value
Returns `:ok` if successful, and `{:error, reason}` otherwise.
"""
@callback queue_command(
name_or_path :: String.t() | application_command_path,
command_module :: module,
name_or_pid
) :: :ok | {:error, Nostrum.Error.ApiError.t()}

@doc """
Add a new command under the given name or application command path.
If the command already exists, it will be overwritten.
When adding many commands, it is recommended to use queue_command, and to call process_queue once all
commands are queued for registration.
## Return value
Returns `:ok` if successful, and `{:error, reason}` otherwise.
"""
Expand All @@ -115,6 +133,19 @@ defmodule Nosedrum.Storage do
name_or_pid
) :: :ok | {:error, Nostrum.Error.ApiError.t()}

@doc """
Register all currently queued commands to discord, making them available for use
Global commands can take up to 1 hour to be made available. Guild commands are available immediately.
## Return value
Returns `:ok` if successful, and `{:error, reason}` otherwise.
"""
@callback process_queue(
scope :: command_scope,
name_or_pid
) :: :ok | {:error, Nostrum.Error.ApiError.t()}

@doc """
Responds to an Interaction with the given `t:Nosedrum.ApplicationCommand.response/0`.
Expand Down
55 changes: 55 additions & 0 deletions lib/nosedrum/storage/dispatcher.ex
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,26 @@ defmodule Nosedrum.Storage.Dispatcher do
end
end

@impl true
def process_queue(scope, id \\ __MODULE__) do
GenServer.call(id, {:process_queue, scope})
end

@impl true
def queue_command(path, command, id \\ __MODULE__) do
command_name =
if is_binary(path) do
path
else
path
|> Enum.take(1)
|> List.first()
|> unwrap_key()
end

GenServer.call(id, {:queue, command_name, command})
end

@impl true
def add_command(path, command, scope, id \\ __MODULE__) do
payload = build_payload(path, command)
Expand Down Expand Up @@ -76,6 +96,41 @@ defmodule Nosedrum.Storage.Dispatcher do
{:ok, init_arg}
end

def handle_call({:process_queue, :global}, _from, commands) do
command_list =
Enum.map(commands, fn {p, c} ->
build_payload(p, c)
end)

case Nostrum.Api.bulk_overwrite_global_application_commands(command_list) do
{:ok, _} = response ->
{:reply, response, commands}

error ->
{:reply, {:error, error}, commands}
end
end

def handle_call({:process_queue, guild_id}, _from, commands) do
command_list =
Enum.map(commands, fn {p, c} ->
build_payload(p, c)
end)

case Nostrum.Api.bulk_overwrite_guild_application_commands(guild_id, command_list) do
{:ok, _} = response ->
{:reply, response, commands}

error ->
{:reply, {:error, error}, commands}
end
end

@impl true
def handle_call({:queue, name, command}, _from, commands) do
{:reply, :ok, Map.put(commands, name, command)}
end

@impl true
def handle_call({:add, payload, name, command, :global}, _from, commands) do
case Nostrum.Api.create_global_application_command(payload) do
Expand Down

0 comments on commit a6db8c6

Please sign in to comment.