mirror of
https://codeberg.org/godmaire/sergei.git
synced 2024-09-19 15:58:26 +00:00
refactor: move commands && add queue subcommands
This commit is contained in:
parent
da0f899eac
commit
7d57478dda
4 changed files with 158 additions and 133 deletions
129
lib/sergei/commands.ex
Normal file
129
lib/sergei/commands.ex
Normal file
|
@ -0,0 +1,129 @@
|
|||
defmodule Sergei.Commands do
|
||||
require Logger
|
||||
|
||||
# Translate params to list of maps
|
||||
opt = fn type, name, desc, opts ->
|
||||
%{type: type, name: name, description: desc}
|
||||
|> Map.merge(Enum.into(opts, %{}))
|
||||
end
|
||||
|
||||
@play_opts [
|
||||
opt.(3, "url", "URL of the audio to play", [])
|
||||
]
|
||||
|
||||
@queue_add_opts [
|
||||
opt.(3, "url", "URL of the audio to queue", required: true)
|
||||
]
|
||||
|
||||
@queue_opts [
|
||||
opt.(1, "add", "Add a song to the queue", options: @queue_add_opts)
|
||||
]
|
||||
|
||||
@slash_commands [
|
||||
{"ping", "Pong", []},
|
||||
{"play", "Play a song or resume playback", @play_opts},
|
||||
{"queue", "Manage the song queue", @queue_opts},
|
||||
{"pause", "Pause media playback", []},
|
||||
{"stop", "Stop media playback and leave the voice channel", []},
|
||||
{"song", "What song is currently playing?", []}
|
||||
]
|
||||
|
||||
def commands() do
|
||||
Enum.map(@slash_commands, fn {name, description, options} ->
|
||||
%{
|
||||
name: name,
|
||||
description: description,
|
||||
options: options
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
# /ping
|
||||
def do_command(%{data: %{name: "ping"}}) do
|
||||
{:ok, "Pong"}
|
||||
end
|
||||
|
||||
# /play <url>
|
||||
def do_command(%{
|
||||
guild_id: guild_id,
|
||||
user: %{id: invoker_id},
|
||||
data: %{name: "play", options: [%{name: "url", value: url}]}
|
||||
}) do
|
||||
case Sergei.VoiceStateCache.get_state(invoker_id) do
|
||||
%{guild_id: id} = _res when guild_id != id ->
|
||||
{:error, "You're not connected to a voice channel in this server."}
|
||||
|
||||
%{channel_id: channel_id} = _res ->
|
||||
Sergei.Player.play(guild_id, channel_id, url)
|
||||
|
||||
nil ->
|
||||
{:error, "You are not in a voice channel."}
|
||||
end
|
||||
end
|
||||
|
||||
# /play
|
||||
def do_command(%{guild_id: guild_id, data: %{name: "play"}}) do
|
||||
case Sergei.Player.resume(guild_id) do
|
||||
:ok ->
|
||||
{:ok, "Resuming playback..."}
|
||||
|
||||
:not_playing ->
|
||||
{:ok, "I'm not playing anything right now."}
|
||||
|
||||
{:error, err} ->
|
||||
Logger.error("Failed to resume media: #{err}")
|
||||
{:error, "This is embarrasing..."}
|
||||
end
|
||||
end
|
||||
|
||||
# /queue <subcommand>
|
||||
def do_command(%{
|
||||
guild_id: guild_id,
|
||||
data: %{name: "queue", options: opts}
|
||||
}) do
|
||||
subcommand = List.first(opts)
|
||||
|
||||
Sergei.Commands.Queue.handle(guild_id, subcommand.name, subcommand.options)
|
||||
end
|
||||
|
||||
# /pause
|
||||
def do_command(%{guild_id: guild_id, data: %{name: "pause"}}) do
|
||||
case Sergei.Player.pause(guild_id) do
|
||||
:ok ->
|
||||
{:ok, "Pausing..."}
|
||||
|
||||
:not_playing ->
|
||||
{:ok, "I'm not playing anything right now."}
|
||||
|
||||
{:error, err} ->
|
||||
Logger.error("Failed to pause media: #{err}")
|
||||
{:error, "This is embarrasing..."}
|
||||
end
|
||||
end
|
||||
|
||||
# /stop
|
||||
def do_command(%{guild_id: guild_id, data: %{name: "stop"}}) do
|
||||
case Sergei.Player.stop(guild_id) do
|
||||
:ok ->
|
||||
{:ok, "Bye!"}
|
||||
|
||||
:not_playing ->
|
||||
{:ok, "I'm not playing anything right now."}
|
||||
|
||||
{:error, err} ->
|
||||
Logger.error("Failed to stop media: #{err}")
|
||||
{:error, "This is embarrasing..."}
|
||||
end
|
||||
end
|
||||
|
||||
# /song
|
||||
def do_command(%{guild_id: guild_id, data: %{name: "song"}}) do
|
||||
case Sergei.Player.get_current_song(guild_id) do
|
||||
:not_playing ->
|
||||
{:ok, "I'm not playing anything right now."}
|
||||
|
||||
url ->
|
||||
{:ok, url}
|
||||
end
|
||||
end
|
||||
end
|
23
lib/sergei/commands/queue.ex
Normal file
23
lib/sergei/commands/queue.ex
Normal file
|
@ -0,0 +1,23 @@
|
|||
defmodule Sergei.Commands.Queue do
|
||||
require Logger
|
||||
|
||||
@spec handle(integer(), String.t(), [%{name: String.t(), value: String.t()}]) ::
|
||||
{:ok, String.t()} | {:err, String.t()}
|
||||
def handle(guild_id, "add", opts) do
|
||||
[
|
||||
%{name: "url", value: url}
|
||||
] = opts
|
||||
|
||||
case Sergei.Player.queue_add(guild_id, url) do
|
||||
:ok ->
|
||||
{:ok, "Song queued."}
|
||||
|
||||
:not_playing ->
|
||||
{:ok, "I'm not playing anything right now."}
|
||||
|
||||
{:error, err} ->
|
||||
Logger.error("Failed to queue media: #{err}")
|
||||
{:error, "This is embarassing..."}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -4,42 +4,12 @@ defmodule Sergei.Consumer do
|
|||
require Logger
|
||||
alias Nostrum.Api
|
||||
|
||||
# Translate params to list of maps
|
||||
opt = fn type, name, desc, opts ->
|
||||
%{type: type, name: name, description: desc}
|
||||
|> Map.merge(Enum.into(opts, %{}))
|
||||
end
|
||||
|
||||
@play_opts [
|
||||
opt.(3, "url", "URL of the audio to play", [])
|
||||
]
|
||||
|
||||
@queue_opts [
|
||||
opt.(3, "url", "URL of the audio to queue", required: true)
|
||||
]
|
||||
|
||||
@slash_commands [
|
||||
{"ping", "Pong", []},
|
||||
{"play", "Play a song or resume playback", @play_opts},
|
||||
{"queue", "Queue a song to play next", @queue_opts},
|
||||
{"pause", "Pause media playback", []},
|
||||
{"stop", "Stop media playback and leave the voice channel", []},
|
||||
{"song", "What song is currently playing?", []}
|
||||
]
|
||||
|
||||
# Initialization of the Discord Client
|
||||
def handle_event({:READY, %{guilds: guilds} = _event, _ws_state}) do
|
||||
# Playing some tunes
|
||||
Api.update_status(:online, "some tunes", 0)
|
||||
|
||||
commands =
|
||||
Enum.map(@slash_commands, fn {name, description, options} ->
|
||||
%{
|
||||
name: name,
|
||||
description: description,
|
||||
options: options
|
||||
}
|
||||
end)
|
||||
commands = Sergei.Commands.commands()
|
||||
|
||||
case Application.get_env(:sergei, :env) do
|
||||
:prod ->
|
||||
|
@ -72,7 +42,7 @@ defmodule Sergei.Consumer do
|
|||
# Handle interactions
|
||||
def handle_event({:INTERACTION_CREATE, interaction, _ws_state}) do
|
||||
response =
|
||||
case do_command(interaction) do
|
||||
case Sergei.Commands.do_command(interaction) do
|
||||
{:ok, msg} ->
|
||||
%{type: 4, data: %{content: msg, flags: 2 ** 6}}
|
||||
|
||||
|
@ -93,101 +63,4 @@ defmodule Sergei.Consumer do
|
|||
def handle_event(_event) do
|
||||
:noop
|
||||
end
|
||||
|
||||
# /ping
|
||||
def do_command(%{data: %{name: "ping"}}) do
|
||||
{:ok, "Pong"}
|
||||
end
|
||||
|
||||
# /play <url>
|
||||
def do_command(%{
|
||||
guild_id: guild_id,
|
||||
user: %{id: invoker_id},
|
||||
data: %{name: "play", options: [%{name: "url", value: url}]}
|
||||
}) do
|
||||
case Sergei.VoiceStateCache.get_state(invoker_id) do
|
||||
%{guild_id: id} = _res when guild_id != id ->
|
||||
{:error, "You're not connected to a voice channel in this server."}
|
||||
|
||||
%{channel_id: channel_id} = _res ->
|
||||
Sergei.Player.play(guild_id, channel_id, url)
|
||||
|
||||
nil ->
|
||||
{:error, "You are not in a voice channel."}
|
||||
end
|
||||
end
|
||||
|
||||
# /play
|
||||
def do_command(%{guild_id: guild_id, data: %{name: "play"}}) do
|
||||
case Sergei.Player.resume(guild_id) do
|
||||
:ok ->
|
||||
{:ok, "Resuming playback..."}
|
||||
|
||||
:not_playing ->
|
||||
{:ok, "I'm not playing anything right now."}
|
||||
|
||||
{:error, err} ->
|
||||
Logger.error("Failed to resume media: #{err}")
|
||||
{:error, "This is embarrasing..."}
|
||||
end
|
||||
end
|
||||
|
||||
# /queue <url>
|
||||
def do_command(%{
|
||||
guild_id: guild_id,
|
||||
data: %{name: "queue", options: [%{name: "url", value: url}]}
|
||||
}) do
|
||||
case Sergei.Player.queue(guild_id, url) do
|
||||
:ok ->
|
||||
{:ok, "Song queued."}
|
||||
|
||||
:not_playing ->
|
||||
{:ok, "I'm not playing anything right now."}
|
||||
|
||||
{:error, err} ->
|
||||
Logger.error("Failed to queue media: #{err}")
|
||||
{:error, "This is embarassing..."}
|
||||
end
|
||||
end
|
||||
|
||||
# /pause
|
||||
def do_command(%{guild_id: guild_id, data: %{name: "pause"}}) do
|
||||
case Sergei.Player.pause(guild_id) do
|
||||
:ok ->
|
||||
{:ok, "Pausing..."}
|
||||
|
||||
:not_playing ->
|
||||
{:ok, "I'm not playing anything right now."}
|
||||
|
||||
{:error, err} ->
|
||||
Logger.error("Failed to pause media: #{err}")
|
||||
{:error, "This is embarrasing..."}
|
||||
end
|
||||
end
|
||||
|
||||
# /stop
|
||||
def do_command(%{guild_id: guild_id, data: %{name: "stop"}}) do
|
||||
case Sergei.Player.stop(guild_id) do
|
||||
:ok ->
|
||||
{:ok, "Bye!"}
|
||||
|
||||
:not_playing ->
|
||||
{:ok, "I'm not playing anything right now."}
|
||||
|
||||
{:error, err} ->
|
||||
Logger.error("Failed to stop media: #{err}")
|
||||
{:error, "This is embarrasing..."}
|
||||
end
|
||||
end
|
||||
|
||||
# /song
|
||||
def do_command(%{guild_id: guild_id, data: %{name: "song"}}) do
|
||||
case Sergei.Player.get_current_song(guild_id) do
|
||||
:not_playing ->
|
||||
{:ok, "I'm not playing anything right now."}
|
||||
|
||||
url ->
|
||||
{:ok, url}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,9 +24,9 @@ defmodule Sergei.Player do
|
|||
GenServer.call(__MODULE__, {:play, guild_id, channel_id, url})
|
||||
end
|
||||
|
||||
@spec queue(integer(), String.t()) :: :ok | :not_playing | {:error, String.t()}
|
||||
def queue(guild_id, url) do
|
||||
GenServer.call(__MODULE__, {:queue, guild_id, url})
|
||||
@spec queue_add(integer(), String.t()) :: :ok | :not_playing | {:error, String.t()}
|
||||
def queue_add(guild_id, url) do
|
||||
GenServer.call(__MODULE__, {:queue_add, guild_id, url})
|
||||
end
|
||||
|
||||
@spec pause(integer()) :: :ok | :not_playing | {:error, String.t()}
|
||||
|
@ -128,7 +128,7 @@ defmodule Sergei.Player do
|
|||
|
||||
# Queue
|
||||
@impl true
|
||||
def handle_call({:queue, guild_id, url}, _from, state) do
|
||||
def handle_call({:queue_add, guild_id, url}, _from, state) do
|
||||
%{queue: queue} = Map.fetch!(state, guild_id)
|
||||
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue