discord: add function to register all commands.
* Add a `DiscordSlashCommand.register_slash_commands!` method to register all slash commands with the Discord API. * Allow registering global commands. * Refactor slash commands to use class attributes for the command name, description, and options.
This commit is contained in:
@@ -3,23 +3,26 @@ class DiscordApiClient
|
|||||||
|
|
||||||
BASE_URL = "https://discord.com/api/v8"
|
BASE_URL = "https://discord.com/api/v8"
|
||||||
|
|
||||||
attr_reader :application_id, :guild_id, :bot_token, :http
|
attr_reader :application_id, :bot_token, :http
|
||||||
|
|
||||||
def initialize(application_id: Danbooru.config.discord_application_client_id, guild_id: Danbooru.config.discord_guild_id, bot_token: Danbooru.config.discord_bot_token, http: Danbooru::Http.new)
|
def initialize(application_id: Danbooru.config.discord_application_client_id, bot_token: Danbooru.config.discord_bot_token, http: Danbooru::Http.new)
|
||||||
@application_id = application_id
|
@application_id = application_id
|
||||||
@guild_id = guild_id
|
|
||||||
@bot_token = bot_token
|
@bot_token = bot_token
|
||||||
@http = http
|
@http = http
|
||||||
end
|
end
|
||||||
|
|
||||||
def register_slash_command(name:, description:, options: [])
|
def register_slash_command(name:, description:, options: [], guild_id: nil)
|
||||||
json = {
|
json = {
|
||||||
name: name,
|
name: name,
|
||||||
description: description,
|
description: description,
|
||||||
options: options
|
options: options
|
||||||
}
|
}
|
||||||
|
|
||||||
post("/applications/#{application_id}/guilds/#{guild_id}/commands", json)
|
if guild_id.present?
|
||||||
|
post("/applications/#{application_id}/guilds/#{guild_id}/commands", json)
|
||||||
|
else
|
||||||
|
post("/applications/#{application_id}/commands", json)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_channel(channel_id, **options)
|
def get_channel(channel_id, **options)
|
||||||
|
|||||||
@@ -1,14 +1,6 @@
|
|||||||
class DiscordSlashCommand
|
class DiscordSlashCommand
|
||||||
class WebhookVerificationError < StandardError; end
|
class WebhookVerificationError < StandardError; end
|
||||||
|
|
||||||
COMMANDS = {
|
|
||||||
count: DiscordSlashCommand::CountCommand,
|
|
||||||
posts: DiscordSlashCommand::PostsCommand,
|
|
||||||
random: DiscordSlashCommand::RandomCommand,
|
|
||||||
time: DiscordSlashCommand::TimeCommand,
|
|
||||||
wiki: DiscordSlashCommand::WikiCommand,
|
|
||||||
}
|
|
||||||
|
|
||||||
# https://discord.com/developers/docs/interactions/slash-commands#interaction-interactiontype
|
# https://discord.com/developers/docs/interactions/slash-commands#interaction-interactiontype
|
||||||
module InteractionType
|
module InteractionType
|
||||||
Ping = 1
|
Ping = 1
|
||||||
@@ -21,6 +13,16 @@ class DiscordSlashCommand
|
|||||||
Integer = 4
|
Integer = 4
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The name of the slash command.
|
||||||
|
class_attribute :name
|
||||||
|
|
||||||
|
# A description of the slash command.
|
||||||
|
class_attribute :description
|
||||||
|
|
||||||
|
# The parameters of the slash command.
|
||||||
|
# https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoption
|
||||||
|
class_attribute :options, default: []
|
||||||
|
|
||||||
attr_reader :data, :discord
|
attr_reader :data, :discord
|
||||||
|
|
||||||
# `data` is the the interaction data sent to us by Discord for the command.
|
# `data` is the the interaction data sent to us by Discord for the command.
|
||||||
@@ -30,22 +32,6 @@ class DiscordSlashCommand
|
|||||||
@discord = discord
|
@discord = discord
|
||||||
end
|
end
|
||||||
|
|
||||||
# The name of the slash command.
|
|
||||||
def name
|
|
||||||
raise NotImplementedError
|
|
||||||
end
|
|
||||||
|
|
||||||
# A description of the slash command.
|
|
||||||
def description
|
|
||||||
raise NotImplementedError
|
|
||||||
end
|
|
||||||
|
|
||||||
# The parameters of the slash command.
|
|
||||||
# https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoption
|
|
||||||
def options
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Should return the response to the command.
|
# Should return the response to the command.
|
||||||
def call
|
def call
|
||||||
# respond_with("message")
|
# respond_with("message")
|
||||||
@@ -81,10 +67,27 @@ class DiscordSlashCommand
|
|||||||
discord.get_channel(data[:channel_id], cache: 1.minute)
|
discord.get_channel(data[:channel_id], cache: 1.minute)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Register the command with the Discord API (replacing it if it already exists).
|
class_methods do
|
||||||
# https://discord.com/developers/docs/interactions/slash-commands#registering-a-command
|
# Register all commands with Discord.
|
||||||
def register_slash_command
|
def register_slash_commands!
|
||||||
discord.register_slash_command(name: name, description: description, options: options)
|
slash_commands.values.each(&:register_slash_command!)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Register the command with Discord (replacing it if it already exists).
|
||||||
|
# https://discord.com/developers/docs/interactions/slash-commands#registering-a-command
|
||||||
|
def register_slash_command!(discord: DiscordApiClient.new, guild_id: Danbooru.config.discord_guild_id)
|
||||||
|
discord.register_slash_command(name: name, description: description, options: options, guild_id: guild_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def slash_commands
|
||||||
|
{
|
||||||
|
count: DiscordSlashCommand::CountCommand,
|
||||||
|
posts: DiscordSlashCommand::PostsCommand,
|
||||||
|
random: DiscordSlashCommand::RandomCommand,
|
||||||
|
time: DiscordSlashCommand::TimeCommand,
|
||||||
|
wiki: DiscordSlashCommand::WikiCommand,
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -101,7 +104,7 @@ class DiscordSlashCommand
|
|||||||
{ type: InteractionType::Ping }
|
{ type: InteractionType::Ping }
|
||||||
when InteractionType::ApplicationCommand
|
when InteractionType::ApplicationCommand
|
||||||
name = data.dig(:data, :name)
|
name = data.dig(:data, :name)
|
||||||
klass = COMMANDS.fetch(name&.to_sym)
|
klass = slash_commands.fetch(name&.to_sym)
|
||||||
klass.new(data: data).call
|
klass.new(data: data).call
|
||||||
else
|
else
|
||||||
raise NotImplementedError, "unknown Discord interaction type #{data[:type]}"
|
raise NotImplementedError, "unknown Discord interaction type #{data[:type]}"
|
||||||
|
|||||||
@@ -1,21 +1,13 @@
|
|||||||
class DiscordSlashCommand
|
class DiscordSlashCommand
|
||||||
class CountCommand < DiscordSlashCommand
|
class CountCommand < DiscordSlashCommand
|
||||||
def name
|
self.name = "count"
|
||||||
"count"
|
self.description = "Do a tag search and return the number of results"
|
||||||
end
|
self.options = [{
|
||||||
|
name: "tags",
|
||||||
def description
|
description: "The tags to search",
|
||||||
"Do a tag search and return the number of results"
|
required: true,
|
||||||
end
|
type: ApplicationCommandOptionType::String
|
||||||
|
}]
|
||||||
def options
|
|
||||||
[{
|
|
||||||
name: "tags",
|
|
||||||
description: "The tags to search",
|
|
||||||
required: true,
|
|
||||||
type: ApplicationCommandOptionType::String
|
|
||||||
}]
|
|
||||||
end
|
|
||||||
|
|
||||||
def call
|
def call
|
||||||
tags = params[:tags]
|
tags = params[:tags]
|
||||||
|
|||||||
@@ -2,28 +2,21 @@ class DiscordSlashCommand
|
|||||||
class PostsCommand < DiscordSlashCommand
|
class PostsCommand < DiscordSlashCommand
|
||||||
extend Memoist
|
extend Memoist
|
||||||
|
|
||||||
def name
|
self.name = "posts"
|
||||||
"posts"
|
self.description = "Do a tag search"
|
||||||
end
|
|
||||||
|
|
||||||
def description
|
self.options = [
|
||||||
"Do a tag search"
|
{
|
||||||
end
|
name: "tags",
|
||||||
|
description: "The tags to search",
|
||||||
def options
|
type: ApplicationCommandOptionType::String
|
||||||
[
|
},
|
||||||
{
|
{
|
||||||
name: "tags",
|
name: "limit",
|
||||||
description: "The tags to search",
|
description: "The number of posts to show (max 10)",
|
||||||
type: ApplicationCommandOptionType::String
|
type: ApplicationCommandOptionType::Integer
|
||||||
},
|
}
|
||||||
{
|
]
|
||||||
name: "limit",
|
|
||||||
description: "The number of posts to show (max 10)",
|
|
||||||
type: ApplicationCommandOptionType::Integer
|
|
||||||
}
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
def call
|
def call
|
||||||
tags = params[:tags]
|
tags = params[:tags]
|
||||||
|
|||||||
@@ -1,27 +1,19 @@
|
|||||||
class DiscordSlashCommand
|
class DiscordSlashCommand
|
||||||
class RandomCommand < DiscordSlashCommand
|
class RandomCommand < DiscordSlashCommand
|
||||||
def name
|
self.name = "random"
|
||||||
"random"
|
self.description = "Show a random post"
|
||||||
end
|
self.options = [
|
||||||
|
{
|
||||||
def description
|
name: "tags",
|
||||||
"Show a random post"
|
description: "The tags to search",
|
||||||
end
|
type: ApplicationCommandOptionType::String
|
||||||
|
},
|
||||||
def options
|
{
|
||||||
[
|
name: "limit",
|
||||||
{
|
description: "The number of posts to show (max 10)",
|
||||||
name: "tags",
|
type: ApplicationCommandOptionType::Integer
|
||||||
description: "The tags to search",
|
}
|
||||||
type: ApplicationCommandOptionType::String
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "limit",
|
|
||||||
description: "The number of posts to show (max 10)",
|
|
||||||
type: ApplicationCommandOptionType::Integer
|
|
||||||
}
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
def call
|
def call
|
||||||
tags = params[:tags]
|
tags = params[:tags]
|
||||||
|
|||||||
@@ -1,21 +1,13 @@
|
|||||||
class DiscordSlashCommand
|
class DiscordSlashCommand
|
||||||
class TimeCommand < DiscordSlashCommand
|
class TimeCommand < DiscordSlashCommand
|
||||||
def name
|
self.name = "time"
|
||||||
"time"
|
self.description = "Show the current time around the world"
|
||||||
end
|
self.options = [{
|
||||||
|
name: "name",
|
||||||
def description
|
description: "The name of the country to show",
|
||||||
"Show the current time around the world"
|
required: false,
|
||||||
end
|
type: ApplicationCommandOptionType::String
|
||||||
|
}]
|
||||||
def options
|
|
||||||
[{
|
|
||||||
name: "name",
|
|
||||||
description: "The name of the country to show",
|
|
||||||
required: false,
|
|
||||||
type: ApplicationCommandOptionType::String
|
|
||||||
}]
|
|
||||||
end
|
|
||||||
|
|
||||||
def call
|
def call
|
||||||
name = params[:name]
|
name = params[:name]
|
||||||
|
|||||||
@@ -2,24 +2,16 @@ class DiscordSlashCommand
|
|||||||
class WikiCommand < DiscordSlashCommand
|
class WikiCommand < DiscordSlashCommand
|
||||||
extend Memoist
|
extend Memoist
|
||||||
|
|
||||||
def name
|
self.name = "wiki"
|
||||||
"wiki"
|
self.description = "Show a wiki page"
|
||||||
end
|
self.options = [
|
||||||
|
{
|
||||||
def description
|
name: "name",
|
||||||
"Show a wiki page"
|
description: "The name of the wiki page",
|
||||||
end
|
required: true,
|
||||||
|
type: ApplicationCommandOptionType::String
|
||||||
def options
|
},
|
||||||
[
|
]
|
||||||
{
|
|
||||||
name: "name",
|
|
||||||
description: "The name of the wiki page",
|
|
||||||
required: true,
|
|
||||||
type: ApplicationCommandOptionType::String
|
|
||||||
},
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
def call
|
def call
|
||||||
if wiki_page.nil?
|
if wiki_page.nil?
|
||||||
|
|||||||
Reference in New Issue
Block a user