Class: Discordrb::Bot
- Inherits:
-
Object
- Object
- Discordrb::Bot
- Includes:
- Cache, EventContainer
- Defined in:
- lib/discordrb/bot.rb
Overview
Represents a Discord bot, including servers, users, etc.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#awaits ⇒ Hash<Symbol => Await>
readonly
The list of registered Awaits.
-
#event_threads ⇒ Array<Thread>
readonly
The list of currently running threads used to parse and call events.
-
#gateway ⇒ Gateway
readonly
The gateway connection is an internal detail that is useless to most people.
-
#name ⇒ String
The bot's name which discordrb sends to Discord when making any request, so Discord can identify bots with the same codebase.
-
#shard_key ⇒ Array(Integer, Integer)
readonly
The current shard key.
-
#should_parse_self ⇒ true, false
Whether or not the bot should parse its own messages.
-
#voices ⇒ Hash<Integer => VoiceBot>
readonly
The voice connections this bot currently has, by the server ID to which they are connected.
Instance Method Summary collapse
-
#accept_invite(invite) ⇒ Object
Makes the bot join an invite to a server.
-
#add_await(key, type, attributes = {}) {|event| ... } ⇒ Await
deprecated
Deprecated.
Will be changed to blocking behavior in v4.0. Use #add_await! instead.
-
#add_await!(type, attributes = {}) {|event| ... } ⇒ Event?
Awaits an event, blocking the current thread until a response is received.
-
#add_thread_member(channel, member) ⇒ Object
Add a member to a thread.
-
#application_command_permissions(server_id:) ⇒ Array<ApplicationCommand::Permission>
Get the permissions for all of the application commands in a specific server.
-
#application_emoji(emoji_id) ⇒ Emoji
Fetches a single application emoji from its ID.
-
#application_emojis ⇒ Array<Emoji>
Fetches all the application emojis that the bot can use.
-
#bot_application ⇒ Application
(also: #bot_app, #application)
The bot's OAuth application.
-
#competing=(name) ⇒ String
Sets the currently competing status to the specified name.
-
#connected? ⇒ true, false
Whether or not the bot is currently connected to Discord.
-
#create_application_emoji(name:, image:) ⇒ Emoji
Creates a new custom emoji that can be used by this application.
-
#create_oauth_application(name, redirect_uris) ⇒ Array(String, String)
Creates a new application to do OAuth authorization with.
- #debug(message) ⇒ Object
-
#debug=(new_debug) ⇒ Object
Sets debug mode.
-
#delete_application_command(command_id, server_id: nil) ⇒ Object
Remove an application command from the commands registered with discord.
-
#delete_application_emoji(emoji_id) ⇒ Object
Deletes an existing application emoji.
-
#delete_invite(code) ⇒ Object
Revokes an invite to a server.
-
#dispatch(type, data) ⇒ Object
Dispatches an event to this bot.
-
#dnd ⇒ Object
Sets the bot's status to DnD (red icon).
- #edit_application_command(command_id, server_id: nil, name: nil, description: nil, default_permission: nil, type: :chat_input, default_member_permissions: nil, contexts: nil, nsfw: nil, integration_types: nil) {|, | ... } ⇒ Object
- #edit_application_command_permissions(command_id, server_id, permissions = [], bearer_token = nil) {|builder| ... } ⇒ Object
-
#edit_application_emoji(emoji_id, name:) ⇒ Emoji
Edits an existing application emoji.
- #emoji(id = nil) ⇒ Object (also: #emojis, #all_emoji)
-
#find_emoji(name) ⇒ GlobalEmoji?
Finds an emoji by its name.
-
#game=(name) ⇒ String
(also: #playing=)
Sets the currently playing game to the specified game.
-
#get_application_command(command_id, server_id: nil) ⇒ Object
Get an application command by ID.
-
#get_application_commands(server_id: nil) ⇒ Array<ApplicationCommand>
Get all application commands.
-
#idle ⇒ Object
(also: #away)
Sets status to idle.
-
#ignore_user(user) ⇒ Object
Add a user to the list of ignored users.
-
#ignored?(user) ⇒ true, false
Checks whether a user is being ignored.
-
#initialize(log_mode: :normal, token: nil, client_id: nil, type: nil, name: '', fancy_log: false, suppress_ready: false, parse_self: false, shard_id: nil, num_shards: nil, redact_token: true, ignore_bots: false, compress_mode: :large, intents: :all) ⇒ Bot
constructor
Makes a new bot with the given authentication data.
-
#invisible ⇒ Object
Sets the bot's status to invisible (appears offline).
-
#invite_url(server: nil, permission_bits: nil, redirect_uri: nil, scopes: ['bot']) ⇒ String
Creates an OAuth invite URL that can be used to invite this bot to a particular server.
-
#join ⇒ Object
(also: #sync)
Joins the bot's connection thread with the current thread.
-
#join_thread(channel) ⇒ Object
Join a thread.
-
#leave_thread(channel) ⇒ Object
Leave a thread.
-
#listening=(name) ⇒ String
Sets the current listening status to the specified name.
- #log_exception(e) ⇒ Object
-
#mode=(new_mode) ⇒ Object
Sets the logging mode.
-
#online ⇒ Object
(also: #on)
Sets status to online.
-
#parse_mention(mention, server = nil) ⇒ User, ...
Gets the user, channel, role or emoji from a string.
-
#parse_mentions(mentions, server = nil) ⇒ Array<User, Channel, Role, Emoji>
Gets the users, channels, roles and emoji from a string.
-
#profile ⇒ Profile
(also: #bot_user)
The bot's user profile.
-
#prune_empty_groups ⇒ Object
Makes the bot leave any groups with no recipients remaining.
-
#raise_heartbeat_event ⇒ Object
Raises a heartbeat event.
-
#raw_token ⇒ String
The raw token, without any prefix.
- #register_application_command(name, description, server_id: nil, default_permission: nil, type: :chat_input, default_member_permissions: nil, contexts: nil, nsfw: false, integration_types: nil) {|, | ... } ⇒ Object
-
#remove_thread_member(channel, member) ⇒ Object
Remove a member from a thread.
-
#role_connection_metadata_records ⇒ Array<RoleConnectionMetadata>
Get the role connection metadata records associated with this application.
-
#run(background = false) ⇒ Object
Runs the bot, which logs into Discord and connects the WebSocket.
-
#send_file(channel, file, caption: nil, tts: false, filename: nil, spoiler: nil) ⇒ Object
Sends a file to a channel.
-
#send_message(channel, content, tts = false, embeds = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0, nonce = nil, enforce_nonce = false, poll = nil) ⇒ Message
Sends a text message to a channel given its ID and the message's content.
-
#send_temporary_message(channel, content, timeout, tts = false, embeds = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0, nonce = nil, enforce_nonce = false, poll = nil) ⇒ Object
Sends a text message to a channel given its ID and the message's content, then deletes it after the specified timeout in seconds.
-
#servers ⇒ Hash<Integer => Server>
The list of servers the bot is currently in.
-
#stop(_no_sync = nil) ⇒ Object
Stops the bot gracefully, disconnecting the websocket without immediately killing the thread.
-
#stream(name, url) ⇒ String
Sets the currently online stream to the specified name and Twitch URL.
-
#suppress_ready_debug ⇒ Object
Prevents the READY packet from being printed regardless of debug mode.
-
#thread_members ⇒ Hash<Integer => Hash<Integer => Hash<String => Object>>]
The list of members in threads the bot can see.
-
#token ⇒ String
The Discord API token received when logging in.
-
#unignore_user(user) ⇒ Object
Remove a user from the ignore list.
-
#update_oauth_application(name, redirect_uris, description = '', icon = nil) ⇒ Object
Changes information about your OAuth application.
-
#update_status(status, activity, url, since = 0, afk = false, activity_type = 0) ⇒ Object
Updates presence status.
-
#users ⇒ Hash<Integer => User>
The list of users the bot shares a server with.
-
#voice(thing) ⇒ Voice::VoiceBot?
Gets the voice bot for a particular server or channel.
-
#voice_connect(chan, encrypted = true) ⇒ Voice::VoiceBot
Connects to a voice channel, initializes network connections and returns the Voice::VoiceBot over which audio data can then be sent.
-
#voice_destroy(server, destroy_vws = true) ⇒ Object
Disconnects the client from a specific voice connection given the server ID.
-
#watching=(name) ⇒ String
Sets the current watching status to the specified name.
Methods included from Cache
#channel, #ensure_channel, #ensure_server, #ensure_thread_member, #ensure_user, #find_channel, #find_user, #init_cache, #invite, #member, #pm_channel, #request_chunks, #resolve_invite_code, #server, #server_preview, #user, #voice_regions
Methods included from EventContainer
#add_handler, #application_command, #application_command_permissions_update, #audit_log_entry, #autocomplete, #await, #button, #channel_create, #channel_delete, #channel_pins_update, #channel_recipient_add, #channel_recipient_remove, #channel_select, #channel_update, class_from_string, #clear!, #disconnected, event_class, handler_class, #heartbeat, #include_events, #integration_create, #integration_delete, #integration_update, #interaction_create, #invite_create, #invite_delete, #member_join, #member_leave, #member_update, #mention, #mentionable_select, #message, #message_delete, #message_edit, #message_update, #modal_submit, #playing, #pm, #poll_vote_add, #poll_vote_remove, #presence, #raw, #reaction_add, #reaction_remove, #reaction_remove_all, #reaction_remove_emoji, #ready, #remove_application_command_handler, #remove_handler, #role_select, #scheduled_event_create, #scheduled_event_delete, #scheduled_event_update, #scheduled_event_user_add, #scheduled_event_user_remove, #server_create, #server_delete, #server_emoji, #server_emoji_create, #server_emoji_delete, #server_emoji_update, #server_role_create, #server_role_delete, #server_role_update, #server_update, #string_select, #typing, #unknown, #user_ban, #user_select, #user_unban, #voice_server_update, #voice_state_update, #webhook_update
Methods included from Events
Constructor Details
#initialize(log_mode: :normal, token: nil, client_id: nil, type: nil, name: '', fancy_log: false, suppress_ready: false, parse_self: false, shard_id: nil, num_shards: nil, redact_token: true, ignore_bots: false, compress_mode: :large, intents: :all) ⇒ Bot
Makes a new bot with the given authentication data. It will be ready to be added event handlers to and can eventually be run with #run.
As support for logging in using username and password has been removed in version 3.0.0, only a token login is
possible. Be sure to specify the type parameter as :user if you're logging in as a user.
Simply creating a bot won't be enough to start sending messages etc. with, only a limited set of methods can be used after logging in. If you want to do something when the bot has connected successfully, either do it in the EventContainer#ready event, or use the #run method with the :async parameter and do the processing after that.
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/discordrb/bot.rb', line 117 def initialize( log_mode: :normal, token: nil, client_id: nil, type: nil, name: '', fancy_log: false, suppress_ready: false, parse_self: false, shard_id: nil, num_shards: nil, redact_token: true, ignore_bots: false, compress_mode: :large, intents: :all ) LOGGER.mode = log_mode LOGGER.token = token if redact_token @should_parse_self = parse_self @client_id = client_id @type = type || :bot @name = name @shard_key = num_shards ? [shard_id, num_shards] : nil LOGGER.fancy = fancy_log @prevent_ready = suppress_ready @compress_mode = compress_mode raise 'Token string is empty or nil' if token.nil? || token.empty? @intents = case intents when :all ALL_INTENTS when :unprivileged UNPRIVILEGED_INTENTS when :none NO_INTENTS else calculate_intents(intents) end @token = process_token(@type, token) @gateway = Gateway.new(self, @token, @shard_key, @compress_mode, @intents) init_cache @voices = {} @should_connect_to_voice = {} @ignored_ids = Set.new @ignore_bots = ignore_bots @event_threads = [] @current_thread = 0 @status = :online @application_commands = {} @request_members_rl = {} end |
Instance Attribute Details
#awaits ⇒ Hash<Symbol => Await> (readonly)
Returns the list of registered Awaits.
66 67 68 |
# File 'lib/discordrb/bot.rb', line 66 def awaits @awaits end |
#event_threads ⇒ Array<Thread> (readonly)
The list of currently running threads used to parse and call events.
The threads will have a local variable :discordrb_name in the format of et-1234, where
"et" stands for "event thread" and the number is a continually incrementing number representing
how many events were executed before.
52 53 54 |
# File 'lib/discordrb/bot.rb', line 52 def event_threads @event_threads end |
#gateway ⇒ Gateway (readonly)
The gateway connection is an internal detail that is useless to most people. It is however essential while debugging or developing discordrb itself, or while writing very custom bots.
71 72 73 |
# File 'lib/discordrb/bot.rb', line 71 def gateway @gateway end |
#name ⇒ String
The bot's name which discordrb sends to Discord when making any request, so Discord can identify bots with the same codebase. Not required but I recommend setting it anyway.
60 61 62 |
# File 'lib/discordrb/bot.rb', line 60 def name @name end |
#shard_key ⇒ Array(Integer, Integer) (readonly)
Returns the current shard key.
63 64 65 |
# File 'lib/discordrb/bot.rb', line 63 def shard_key @shard_key end |
#should_parse_self ⇒ true, false
Returns whether or not the bot should parse its own messages. Off by default.
55 56 57 |
# File 'lib/discordrb/bot.rb', line 55 def should_parse_self @should_parse_self end |
#voices ⇒ Hash<Integer => VoiceBot> (readonly)
Returns the voice connections this bot currently has, by the server ID to which they are connected.
344 345 346 |
# File 'lib/discordrb/bot.rb', line 344 def voices @voices end |
Instance Method Details
#accept_invite(invite) ⇒ Object
Makes the bot join an invite to a server.
318 319 320 321 |
# File 'lib/discordrb/bot.rb', line 318 def accept_invite(invite) resolved = invite(invite).code API::Invite.accept(token, resolved) end |
#add_await(key, type, attributes = {}) {|event| ... } ⇒ Await
Will be changed to blocking behavior in v4.0. Use #add_await! instead.
Add an await the bot should listen to. For information on awaits, see Await.
702 703 704 705 706 707 708 |
# File 'lib/discordrb/bot.rb', line 702 def add_await(key, type, attributes = {}, &block) raise "You can't await an AwaitEvent!" if type == Discordrb::Events::AwaitEvent await = Await.new(self, key, type, attributes, block) @awaits ||= {} @awaits[key] = await end |
#add_await!(type, attributes = {}) {|event| ... } ⇒ Event?
Awaits an event, blocking the current thread until a response is received.
718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 |
# File 'lib/discordrb/bot.rb', line 718 def add_await!(type, attributes = {}) raise "You can't await an AwaitEvent!" if type == Discordrb::Events::AwaitEvent timeout = attributes[:timeout] raise ArgumentError, 'Timeout must be a number > 0' if timeout.is_a?(Numeric) && !timeout.positive? mutex = Mutex.new cv = ConditionVariable.new response = nil block = lambda do |event| mutex.synchronize do response = event if block_given? result = yield(event) cv.signal if result.is_a?(TrueClass) else cv.signal end end end handler = register_event(type, attributes, block) if timeout Thread.new do sleep timeout mutex.synchronize { cv.signal } end end mutex.synchronize { cv.wait(mutex) } remove_handler(handler) raise 'ConditionVariable was signaled without returning an event!' if response.nil? && timeout.nil? response end |
#add_thread_member(channel, member) ⇒ Object
Add a member to a thread
665 666 667 668 |
# File 'lib/discordrb/bot.rb', line 665 def add_thread_member(channel, member) API::Channel.add_thread_member(@token, channel.resolve_id, member.resolve_id) nil end |
#application_command_permissions(server_id:) ⇒ Array<ApplicationCommand::Permission>
Get the permissions for all of the application commands in a specific server.
931 932 933 934 |
# File 'lib/discordrb/bot.rb', line 931 def (server_id:) response = API::Application.(@token, profile.id, server_id.resolve_id) JSON.parse(response).flat_map { |data| data['permissions'].map { |inner| ApplicationCommand::Permission.new(inner, data, self) } } end |
#application_emoji(emoji_id) ⇒ Emoji
Fetches a single application emoji from its ID.
946 947 948 949 |
# File 'lib/discordrb/bot.rb', line 946 def application_emoji(emoji_id) response = API::Application.get_application_emoji(@token, profile.id, emoji_id.resolve_id) Emoji.new(JSON.parse(response), self) end |
#application_emojis ⇒ Array<Emoji>
Fetches all the application emojis that the bot can use.
938 939 940 941 |
# File 'lib/discordrb/bot.rb', line 938 def application_emojis response = API::Application.list_application_emojis(@token, profile.id) JSON.parse(response)['items'].map { |emoji| Emoji.new(emoji, self) } end |
#bot_application ⇒ Application Also known as: bot_app, application
The bot's OAuth application.
246 247 248 249 |
# File 'lib/discordrb/bot.rb', line 246 def bot_application response = API.oauth_application(token) Application.new(JSON.parse(response), self) end |
#competing=(name) ⇒ String
Sets the currently competing status to the specified name.
615 616 617 618 |
# File 'lib/discordrb/bot.rb', line 615 def competing=(name) gateway_check update_status(@status, name, nil, nil, nil, 5) end |
#connected? ⇒ true, false
Returns whether or not the bot is currently connected to Discord.
312 313 314 |
# File 'lib/discordrb/bot.rb', line 312 def connected? @gateway.open? end |
#create_application_emoji(name:, image:) ⇒ Emoji
Creates a new custom emoji that can be used by this application.
955 956 957 958 959 |
# File 'lib/discordrb/bot.rb', line 955 def create_application_emoji(name:, image:) image = image.respond_to?(:read) ? Discordrb.encode64(image) : image response = API::Application.create_application_emoji(@token, profile.id, name, image) Emoji.new(JSON.parse(response), self) end |
#create_oauth_application(name, redirect_uris) ⇒ Array(String, String)
Creates a new application to do OAuth authorization with. This allows you to use OAuth to authorize users using Discord. For information how to use this, see the docs: https://discord.com/developers/docs/topics/oauth2
495 496 497 498 |
# File 'lib/discordrb/bot.rb', line 495 def create_oauth_application(name, redirect_uris) response = JSON.parse(API.create_oauth_application(@token, name, redirect_uris)) [response['id'], response['secret']] end |
#debug(message) ⇒ Object
778 779 780 |
# File 'lib/discordrb/bot.rb', line 778 def debug() LOGGER.debug() end |
#debug=(new_debug) ⇒ Object
Sets debug mode. If debug mode is on, many things will be outputted to STDOUT.
679 680 681 |
# File 'lib/discordrb/bot.rb', line 679 def debug=(new_debug) LOGGER.debug = new_debug end |
#delete_application_command(command_id, server_id: nil) ⇒ Object
Remove an application command from the commands registered with discord.
905 906 907 908 909 910 911 |
# File 'lib/discordrb/bot.rb', line 905 def delete_application_command(command_id, server_id: nil) if server_id API::Application.delete_guild_command(@token, profile.id, server_id, command_id) else API::Application.delete_global_command(@token, profile.id, command_id) end end |
#delete_application_emoji(emoji_id) ⇒ Object
Deletes an existing application emoji.
972 973 974 |
# File 'lib/discordrb/bot.rb', line 972 def delete_application_emoji(emoji_id) API::Application.delete_application_emoji(@token, profile.id, emoji_id.resolve_id) end |
#delete_invite(code) ⇒ Object
Revokes an invite to a server. Will fail unless you have the Manage Server permission. It is recommended that you use Invite#delete instead.
408 409 410 411 |
# File 'lib/discordrb/bot.rb', line 408 def delete_invite(code) invite = resolve_invite_code(code) API::Invite.delete(token, invite) end |
#dispatch(type, data) ⇒ Object
Dispatches an event to this bot. Called by the gateway connection handler used internally.
788 789 790 |
# File 'lib/discordrb/bot.rb', line 788 def dispatch(type, data) handle_dispatch(type, data) end |
#dnd ⇒ Object
Sets the bot's status to DnD (red icon).
637 638 639 640 |
# File 'lib/discordrb/bot.rb', line 637 def dnd gateway_check update_status(:dnd, @activity, nil) end |
#edit_application_command(command_id, server_id: nil, name: nil, description: nil, default_permission: nil, type: :chat_input, default_member_permissions: nil, contexts: nil, nsfw: nil, integration_types: nil) {|, | ... } ⇒ Object
874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 |
# File 'lib/discordrb/bot.rb', line 874 def edit_application_command(command_id, server_id: nil, name: nil, description: nil, default_permission: nil, type: :chat_input, default_member_permissions: nil, contexts: nil, nsfw: nil, integration_types: nil) type = ApplicationCommand::TYPES[type] || type contexts = contexts&.map { |context| Interaction::CONTEXTS[context] || context } integration_types = integration_types&.map { |type| Interaction::INTEGRATION_TYPES[type] || type } = Permissions.bits() if .is_a?(Array) builder = Interactions::OptionBuilder.new = Interactions::PermissionBuilder.new yield(builder, ) if block_given? resp = if server_id API::Application.edit_guild_command(@token, profile.id, server_id, command_id, name, description, builder.to_a, , type, &.to_s, contexts, nsfw) else API::Application.edit_global_command(@token, profile.id, command_id, name, description, builder.to_a, , type, &.to_s, contexts, nsfw, integration_types) end cmd = ApplicationCommand.new(JSON.parse(resp), self, server_id) if .to_a.any? raise ArgumentError, 'Permissions can only be set for guild commands' unless server_id (cmd.id, server_id, .to_a) end cmd end |
#edit_application_command_permissions(command_id, server_id, permissions = [], bearer_token = nil) {|builder| ... } ⇒ Object
917 918 919 920 921 922 923 924 925 926 |
# File 'lib/discordrb/bot.rb', line 917 def (command_id, server_id, = [], bearer_token = nil) builder = Interactions::PermissionBuilder.new yield builder if block_given? raise ArgumentError, 'This method requires a valid bearer token to be provided' unless bearer_token += builder.to_a bearer_token = "Bearer #{bearer_token.delete_prefix('Bearer ')}" API::Application.(bearer_token, profile.id, server_id, command_id, ) end |
#edit_application_emoji(emoji_id, name:) ⇒ Emoji
Edits an existing application emoji.
965 966 967 968 |
# File 'lib/discordrb/bot.rb', line 965 def edit_application_emoji(emoji_id, name:) response = API::Application.edit_application_emoji(@token, profile.id, emoji_id.resolve_id, name) Emoji.new(JSON.parse(response), self) end |
#emoji(id) ⇒ Emoji? #emoji ⇒ Array<Emoji> Also known as: emojis, all_emoji
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/discordrb/bot.rb', line 205 def emoji(id = nil) if (id = id&.resolve_id) @servers.each_value do |server| emoji = server.emojis[id] return emoji if emoji end else hash = {} @servers.each_value do |server| hash.merge!(server.emojis) end hash end end |
#find_emoji(name) ⇒ GlobalEmoji?
Finds an emoji by its name.
227 228 229 230 |
# File 'lib/discordrb/bot.rb', line 227 def find_emoji(name) LOGGER.out("Resolving emoji #{name}") emoji.find { |element| element.name == name } end |
#game=(name) ⇒ String Also known as: playing=
Sets the currently playing game to the specified game.
579 580 581 582 |
# File 'lib/discordrb/bot.rb', line 579 def game=(name) gateway_check update_status(@status, name, nil) end |
#get_application_command(command_id, server_id: nil) ⇒ Object
Get an application command by ID.
822 823 824 825 826 827 828 829 |
# File 'lib/discordrb/bot.rb', line 822 def get_application_command(command_id, server_id: nil) resp = if server_id API::Application.get_guild_command(@token, profile.id, server_id, command_id) else API::Application.get_global_command(@token, profile.id, command_id) end ApplicationCommand.new(JSON.parse(resp), self, server_id) end |
#get_application_commands(server_id: nil) ⇒ Array<ApplicationCommand>
Get all application commands.
807 808 809 810 811 812 813 814 815 816 817 |
# File 'lib/discordrb/bot.rb', line 807 def get_application_commands(server_id: nil) resp = if server_id API::Application.get_guild_commands(@token, profile.id, server_id) else API::Application.get_global_commands(@token, profile.id) end JSON.parse(resp).map do |command_data| ApplicationCommand.new(command_data, self, server_id) end end |
#idle ⇒ Object Also known as: away
Sets status to idle.
629 630 631 632 |
# File 'lib/discordrb/bot.rb', line 629 def idle gateway_check update_status(:idle, @activity, nil) end |
#ignore_user(user) ⇒ Object
Ignoring a user only prevents any message events (including mentions, commands etc.) from them! Typing and presence and any other events will still be received.
Add a user to the list of ignored users. Those users will be ignored in message events at event processing level.
760 761 762 |
# File 'lib/discordrb/bot.rb', line 760 def ignore_user(user) @ignored_ids << user.resolve_id end |
#ignored?(user) ⇒ true, false
Checks whether a user is being ignored.
773 774 775 |
# File 'lib/discordrb/bot.rb', line 773 def ignored?(user) @ignored_ids.include?(user.resolve_id) end |
#invisible ⇒ Object
Sets the bot's status to invisible (appears offline).
643 644 645 646 |
# File 'lib/discordrb/bot.rb', line 643 def invisible gateway_check update_status(:invisible, @activity, nil) end |
#invite_url(server: nil, permission_bits: nil, redirect_uri: nil, scopes: ['bot']) ⇒ String
Creates an OAuth invite URL that can be used to invite this bot to a particular server.
329 330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/discordrb/bot.rb', line 329 def invite_url(server: nil, permission_bits: nil, redirect_uri: nil, scopes: ['bot']) @client_id ||= bot_application.id query = URI.encode_www_form({ client_id: @client_id, guild_id: server&.id, permissions: , redirect_uri: redirect_uri, scope: scopes.join(' ') }.compact) "https://discord.com/oauth2/authorize?#{query}" end |
#join ⇒ Object Also known as: sync
Joins the bot's connection thread with the current thread. This blocks execution until the websocket stops, which should only happen manually triggered. or due to an error. This is necessary to have a continuously running bot.
299 300 301 |
# File 'lib/discordrb/bot.rb', line 299 def join @gateway.sync end |
#join_thread(channel) ⇒ Object
Join a thread
650 651 652 653 |
# File 'lib/discordrb/bot.rb', line 650 def join_thread(channel) API::Channel.join_thread(@token, channel.resolve_id) nil end |
#leave_thread(channel) ⇒ Object
Leave a thread
657 658 659 660 |
# File 'lib/discordrb/bot.rb', line 657 def leave_thread(channel) API::Channel.leave_thread(@token, channel.resolve_id) nil end |
#listening=(name) ⇒ String
Sets the current listening status to the specified name.
589 590 591 592 |
# File 'lib/discordrb/bot.rb', line 589 def listening=(name) gateway_check update_status(@status, name, nil, nil, nil, 2) end |
#log_exception(e) ⇒ Object
783 784 785 |
# File 'lib/discordrb/bot.rb', line 783 def log_exception(e) LOGGER.log_exception(e) end |
#mode=(new_mode) ⇒ Object
Sets the logging mode
685 686 687 |
# File 'lib/discordrb/bot.rb', line 685 def mode=(new_mode) LOGGER.mode = new_mode end |
#online ⇒ Object Also known as: on
Sets status to online.
621 622 623 624 |
# File 'lib/discordrb/bot.rb', line 621 def online gateway_check update_status(:online, @activity, @streamurl) end |
#parse_mention(mention, server = nil) ⇒ User, ...
Gets the user, channel, role or emoji from a string.
548 549 550 |
# File 'lib/discordrb/bot.rb', line 548 def parse_mention(mention, server = nil) parse_mentions(mention, server).first end |
#parse_mentions(mentions, server = nil) ⇒ Array<User, Channel, Role, Emoji>
Gets the users, channels, roles and emoji from a string.
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 |
# File 'lib/discordrb/bot.rb', line 514 def parse_mentions(mentions, server = nil) array_to_return = [] # While possible mentions may be in message while mentions.include?('<') && mentions.include?('>') # Removing all content before the next possible mention mentions = mentions.split('<', 2)[1] # Locate the first valid mention enclosed in `<...>`, otherwise advance to the next open `<` next unless mentions.split('>', 2).first.length < mentions.split('<', 2).first.length # Store the possible mention value to be validated with RegEx mention = mentions.split('>', 2).first if /@!?(?<id>\d+)/ =~ mention array_to_return << user(id) unless user(id).nil? elsif /#(?<id>\d+)/ =~ mention array_to_return << channel(id, server) unless channel(id, server).nil? elsif /@&(?<id>\d+)/ =~ mention if server array_to_return << server.role(id) unless server.role(id).nil? else @servers.each_value do |element| array_to_return << element.role(id) unless element.role(id).nil? end end elsif /(?<animated>^a|^${0}):(?<name>\w+):(?<id>\d+)/ =~ mention array_to_return << (emoji(id) || Emoji.new({ 'animated' => animated != '', 'name' => name, 'id' => id }, self, nil)) end end array_to_return end |
#profile ⇒ Profile Also known as: bot_user
The bot's user profile. This special user object can be used to edit user data like the current username (see Profile#username=).
235 236 237 238 239 240 |
# File 'lib/discordrb/bot.rb', line 235 def profile return @profile if @profile response = Discordrb::API::User.profile(@token) @profile = Profile.new(JSON.parse(response), self) end |
#prune_empty_groups ⇒ Object
Makes the bot leave any groups with no recipients remaining
798 799 800 801 802 |
# File 'lib/discordrb/bot.rb', line 798 def prune_empty_groups @channels.each_value do |channel| channel.leave_group if channel.group? && channel.recipients.empty? end end |
#raise_heartbeat_event ⇒ Object
Raises a heartbeat event. Called by the gateway connection handler used internally.
793 794 795 |
# File 'lib/discordrb/bot.rb', line 793 def raise_heartbeat_event raise_event(HeartbeatEvent.new(self)) end |
#raw_token ⇒ String
Returns the raw token, without any prefix.
271 272 273 |
# File 'lib/discordrb/bot.rb', line 271 def raw_token @token.split(' ').last end |
#register_application_command(name, description, server_id: nil, default_permission: nil, type: :chat_input, default_member_permissions: nil, contexts: nil, nsfw: false, integration_types: nil) {|, | ... } ⇒ Object
845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 |
# File 'lib/discordrb/bot.rb', line 845 def register_application_command(name, description, server_id: nil, default_permission: nil, type: :chat_input, default_member_permissions: nil, contexts: nil, nsfw: false, integration_types: nil) type = ApplicationCommand::TYPES[type] || type contexts = contexts&.map { |context| Interaction::CONTEXTS[context] || context } integration_types = integration_types&.map { |type| Interaction::INTEGRATION_TYPES[type] || type } = Permissions.bits() if .is_a?(Array) builder = Interactions::OptionBuilder.new = Interactions::PermissionBuilder.new yield(builder, ) if block_given? resp = if server_id API::Application.create_guild_command(@token, profile.id, server_id, name, description, builder.to_a, , type, &.to_s, contexts, nsfw) else API::Application.create_global_command(@token, profile.id, name, description, builder.to_a, , type, &.to_s, contexts, nsfw, integration_types) end cmd = ApplicationCommand.new(JSON.parse(resp), self, server_id) if .to_a.any? raise ArgumentError, 'Permissions can only be set for guild commands' unless server_id (cmd.id, server_id, .to_a) end cmd end |
#remove_thread_member(channel, member) ⇒ Object
Remove a member from a thread
673 674 675 676 |
# File 'lib/discordrb/bot.rb', line 673 def remove_thread_member(channel, member) API::Channel.remove_thread_member(@token, channel.resolve_id, member.resolve_id) nil end |
#role_connection_metadata_records ⇒ Array<RoleConnectionMetadata>
Get the role connection metadata records associated with this application.
256 257 258 259 |
# File 'lib/discordrb/bot.rb', line 256 def response = API::Application.(@bot.token, @id) JSON.parse(response).map { |role_connection| RoleConnectionMetadata.new(role_connection, @bot) } end |
#run(background = false) ⇒ Object
Running the bot in the background means that you can call some methods that require a gateway connection before that connection is established. In most cases an exception will be raised if you try to do this. If you need a way to safely run code after the bot is fully connected, use a EventContainer#ready event handler instead.
Runs the bot, which logs into Discord and connects the WebSocket. This
prevents all further execution unless it is executed with
background = true.
287 288 289 290 291 292 293 |
# File 'lib/discordrb/bot.rb', line 287 def run(background = false) @gateway.run_async return if background debug('Oh wait! Not exiting yet as run was run synchronously.') @gateway.sync end |
#send_file(channel, file, caption: nil, tts: false, filename: nil, spoiler: nil) ⇒ Object
This executes in a blocking way, so if you're sending long files, be wary of delays.
Sends a file to a channel. If it is an image, it will automatically be embedded.
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 |
# File 'lib/discordrb/bot.rb', line 474 def send_file(channel, file, caption: nil, tts: false, filename: nil, spoiler: nil) if file.respond_to?(:read) if spoiler filename ||= File.basename(file.path) filename = "SPOILER_#{filename}" unless filename.start_with? 'SPOILER_' end # https://github.com/rest-client/rest-client/blob/v2.0.2/lib/restclient/payload.rb#L160 file.define_singleton_method(:original_filename) { filename } if filename file.define_singleton_method(:path) { filename } if filename end channel = channel.resolve_id response = API::Channel.upload_file(token, channel, file, caption: caption, tts: tts) Message.new(JSON.parse(response), self) end |
#send_message(channel, content, tts = false, embeds = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0, nonce = nil, enforce_nonce = false, poll = nil) ⇒ Message
Sends a text message to a channel given its ID and the message's content.
426 427 428 429 430 431 432 433 434 435 |
# File 'lib/discordrb/bot.rb', line 426 def (channel, content, tts = false, = nil, = nil, allowed_mentions = nil, = nil, components = nil, flags = 0, nonce = nil, enforce_nonce = false, poll = nil) channel = channel.resolve_id debug("Sending message to #{channel} with content '#{content}'") allowed_mentions = { parse: [] } if allowed_mentions == false = { message_id: .resolve_id } if .respond_to?(:resolve_id) = (.instance_of?(Array) ? .map(&:to_hash) : [&.to_hash]).compact response = API::Channel.(token, channel, content, tts, , nonce, , allowed_mentions&.to_hash, , components, flags, enforce_nonce, poll&.to_h) Message.new(JSON.parse(response), self) end |
#send_temporary_message(channel, content, timeout, tts = false, embeds = nil, attachments = nil, allowed_mentions = nil, message_reference = nil, components = nil, flags = 0, nonce = nil, enforce_nonce = false, poll = nil) ⇒ Object
Sends a text message to a channel given its ID and the message's content, then deletes it after the specified timeout in seconds.
452 453 454 455 456 457 458 459 460 461 462 |
# File 'lib/discordrb/bot.rb', line 452 def (channel, content, timeout, tts = false, = nil, = nil, allowed_mentions = nil, = nil, components = nil, flags = 0, nonce = nil, enforce_nonce = false, poll = nil) Thread.new do Thread.current[:discordrb_name] = "#{@current_thread}-temp-msg" = (channel, content, tts, , , allowed_mentions, , components, flags, nonce, enforce_nonce, poll) sleep(timeout) .delete end nil end |
#servers ⇒ Hash<Integer => Server>
The list of servers the bot is currently in.
184 185 186 187 188 |
# File 'lib/discordrb/bot.rb', line 184 def servers gateway_check unavailable_servers_check @servers end |
#stop(_no_sync = nil) ⇒ Object
This method no longer takes an argument as of 3.4.0
Stops the bot gracefully, disconnecting the websocket without immediately killing the thread. This means that Discord is immediately aware of the closed connection and makes the bot appear offline instantly.
307 308 309 |
# File 'lib/discordrb/bot.rb', line 307 def stop(_no_sync = nil) @gateway.stop end |
#stream(name, url) ⇒ String
Sets the currently online stream to the specified name and Twitch URL.
606 607 608 609 610 |
# File 'lib/discordrb/bot.rb', line 606 def stream(name, url) gateway_check update_status(@status, name, url) name end |
#suppress_ready_debug ⇒ Object
Prevents the READY packet from being printed regardless of debug mode.
690 691 692 |
# File 'lib/discordrb/bot.rb', line 690 def suppress_ready_debug @prevent_ready = true end |
#thread_members ⇒ Hash<Integer => Hash<Integer => Hash<String => Object>>]
The list of members in threads the bot can see.
192 193 194 195 196 |
# File 'lib/discordrb/bot.rb', line 192 def thread_members gateway_check unavailable_servers_check @thread_members end |
#token ⇒ String
The Discord API token received when logging in. Useful to explicitly call API methods.
264 265 266 267 |
# File 'lib/discordrb/bot.rb', line 264 def token API.bot_name = @name @token end |
#unignore_user(user) ⇒ Object
Remove a user from the ignore list.
766 767 768 |
# File 'lib/discordrb/bot.rb', line 766 def unignore_user(user) @ignored_ids.delete(user.resolve_id) end |
#update_oauth_application(name, redirect_uris, description = '', icon = nil) ⇒ Object
Changes information about your OAuth application
506 507 508 |
# File 'lib/discordrb/bot.rb', line 506 def update_oauth_application(name, redirect_uris, description = '', icon = nil) API.update_oauth_application(@token, name, redirect_uris, description, icon) end |
#update_status(status, activity, url, since = 0, afk = false, activity_type = 0) ⇒ Object
Updates presence status.
561 562 563 564 565 566 567 568 569 570 571 572 573 574 |
# File 'lib/discordrb/bot.rb', line 561 def update_status(status, activity, url, since = 0, afk = false, activity_type = 0) gateway_check @activity = activity @status = status @streamurl = url type = url ? 1 : activity_type activity_obj = activity || url ? { 'name' => activity, 'url' => url, 'type' => type } : nil @gateway.send_status_update(status, since, activity_obj, afk) # Update the status in the cache profile.update_presence('status' => status.to_s, 'activities' => [activity_obj].compact) end |
#users ⇒ Hash<Integer => User>
The list of users the bot shares a server with.
176 177 178 179 180 |
# File 'lib/discordrb/bot.rb', line 176 def users gateway_check unavailable_servers_check @users end |
#voice(thing) ⇒ Voice::VoiceBot?
Gets the voice bot for a particular server or channel. You can connect to a new channel using the #voice_connect method.
350 351 352 353 354 355 356 357 358 359 |
# File 'lib/discordrb/bot.rb', line 350 def voice(thing) id = thing.resolve_id return @voices[id] if @voices[id] channel = channel(id) return nil unless channel server_id = channel.server.id return @voices[server_id] if @voices[server_id] end |
#voice_connect(chan, encrypted = true) ⇒ Voice::VoiceBot
Connects to a voice channel, initializes network connections and returns the Voice::VoiceBot over which audio data can then be sent. After connecting, the bot can also be accessed using #voice. If the bot is already connected to voice, the existing connection will be terminated - you don't have to call Voice::VoiceBot#destroy before calling this method.
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
# File 'lib/discordrb/bot.rb', line 369 def voice_connect(chan, encrypted = true) raise ArgumentError, 'Unencrypted voice connections are no longer supported.' unless encrypted chan = channel(chan.resolve_id) server_id = chan.server.id if @voices[chan.id] debug('Voice bot exists already! Destroying it') @voices[chan.id].destroy @voices.delete(chan.id) end debug("Got voice channel: #{chan}") @should_connect_to_voice[server_id] = chan @gateway.send_voice_state_update(server_id.to_s, chan.id.to_s, false, false) debug('Voice channel init packet sent! Now waiting.') sleep(0.05) until @voices[server_id] debug('Voice connect succeeded!') @voices[server_id] end |
#voice_destroy(server, destroy_vws = true) ⇒ Object
Disconnects the client from a specific voice connection given the server ID. Usually it's more convenient to use Voice::VoiceBot#destroy rather than this.
398 399 400 401 402 403 |
# File 'lib/discordrb/bot.rb', line 398 def voice_destroy(server, destroy_vws = true) server = server.resolve_id @gateway.send_voice_state_update(server.to_s, nil, false, false) @voices[server].destroy if @voices[server] && destroy_vws @voices.delete(server) end |
#watching=(name) ⇒ String
Sets the current watching status to the specified name.
597 598 599 600 |
# File 'lib/discordrb/bot.rb', line 597 def watching=(name) gateway_check update_status(@status, name, nil, nil, nil, 3) end |