diff --git a/lib/async/discord/application.rb b/lib/async/discord/application.rb new file mode 100644 index 0000000..b0e45b8 --- /dev/null +++ b/lib/async/discord/application.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require_relative "representation" +require_relative "application_commands" + +module Async + module Discord + # Represents an application. + class Application < Representation + # The unique identifier for this application. + def id + self.value[:id] + end + + # The name of this application. + def name + self.value[:name] + end + + # The global commands for this application. + def commands + path = @resource.path.gsub("@me", id) + "/commands" + ApplicationCommands.new(@resource.with(path: path)) + end + end + end +end diff --git a/lib/async/discord/application_commands.rb b/lib/async/discord/application_commands.rb new file mode 100644 index 0000000..15402dd --- /dev/null +++ b/lib/async/discord/application_commands.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Async + module Discord + # Represents an application command. + class ApplicationCommand < Representation + # The unique identifier for this application command. + def id + self.value[:id] + end + + # The name of this application command. + def name + self.value[:name] + end + + # Update this application command. + def update(payload) + self.class.patch(@resource, payload) + end + + # Delete this application command. + def delete + self.class.delete(@resource) + end + end + + # Represents a collection of application commands. + class ApplicationCommands < Representation + # Create a new application command. + def create(payload) + ApplicationCommand.post(@resource, payload) + end + + # Enumerate over each command. + def each(&block) + return to_enum unless block_given? + + self.value.each do |value| + yield ApplicationCommand.new(@resource.with(path: value[:id]), value: value) + end + end + end + end +end diff --git a/lib/async/discord/client.rb b/lib/async/discord/client.rb index 81c8ef9..5a10fc9 100644 --- a/lib/async/discord/client.rb +++ b/lib/async/discord/client.rb @@ -7,6 +7,7 @@ require_relative "guilds" require_relative "gateway" +require_relative "application" module Async module Discord @@ -14,10 +15,10 @@ module Discord class Client < Async::REST::Resource # The default endpoint for Discord. ENDPOINT = Async::HTTP::Endpoint.parse("https://discord.com/api/v10/") - + # The default user agent for this client. USER_AGENT = "#{self.name} (https://github.com/socketry/async-discord, v#{Async::Discord::VERSION})" - + # Authenticate the client, either with a bot or bearer token. # # @parameter bot [String] The bot token. @@ -25,9 +26,9 @@ class Client < Async::REST::Resource # @returns [Client] a new client with the given authentication. def authenticated(bot: nil, bearer: nil) headers = {} - + headers["user-agent"] ||= USER_AGENT - + if bot headers["authorization"] = "Bot #{bot}" elsif bearer @@ -35,24 +36,34 @@ def authenticated(bot: nil, bearer: nil) else raise ArgumentError, "You must provide either a bot or bearer token!" end - + return self.with(headers: headers) end - + # @returns [Guilds] a collection of guilds the bot is a member of. def guilds Guilds.new(self.with(path: "users/@me/guilds")) end - + # @returns [Gateway] the gateway for the bot. def gateway Gateway.new(self.with(path: "gateway/bot")) end - + # @returns [Channel] a channel by its unique identifier. def channel(id) Channel.new(self.with(path: "channels/#{id}")) end + + # @returns [Application] the application. + def application(id) + Application.new(self.with(path: "applications/#{id}")) + end + + # @returns [Application] the application which is currently authenticated. + def current_application + application("@me") + end end end end diff --git a/test/async/discord/client.rb b/test/async/discord/client.rb index 8cbe255..90b9526 100644 --- a/test/async/discord/client.rb +++ b/test/async/discord/client.rb @@ -7,13 +7,22 @@ describe Async::Discord::Client do include Async::Discord::ClientContext - + with "#guilds" do it "can list guilds" do guilds = client.guilds - + expect(guilds).to be_a(Async::Discord::Guilds) expect(guilds).not.to be(:empty?) end end + + with "#current_application" do + it "can get the current application" do + application = client.current_application + + expect(application).to be_a(Async::Discord::Application) + expect(application.id).to be_kind_of(Integer) + end + end end