diff --git a/lib/discordrb/api/server.rb b/lib/discordrb/api/server.rb index 0b44657a7..02f4dfd4a 100644 --- a/lib/discordrb/api/server.rb +++ b/lib/discordrb/api/server.rb @@ -31,6 +31,36 @@ def update(token, server_id, name, region, icon, afk_channel_id, afk_timeout, sp ) end + # Update the properties of a guild. + # https://discord.com/developers/docs/resources/guild#modify-guild + def update!(token, server_id, name: :undef, region: :undef, verification_level: :undef, default_message_notifications: :undef, explicit_content_filter: :undef, afk_channel_id: :undef, afk_timeout: :undef, icon: :undef, splash: :undef, discovery_splash: :undef, banner: :undef, system_channel_id: :undef, system_channel_flags: :undef, rules_channel_id: :undef, public_updates_channel_id: :undef, preferred_locale: :undef, features: :undef, description: :undef, premium_progress_bar_enabled: :undef, safety_alerts_channel_id: :undef, reason: nil) + Discordrb::API.request( + :guilds_sid, + server_id, + :patch, + "#{Discordrb::API.api_base}/guilds/#{server_id}", + { name:, region:, verification_level:, default_message_notifications:, explicit_content_filter:, afk_channel_id:, afk_timeout:, icon:, splash:, discovery_splash:, banner:, system_channel_id:, system_channel_flags:, rules_channel_id:, public_updates_channel_id:, preferred_locale:, features:, description:, premium_progress_bar_enabled:, safety_alerts_channel_id: }.reject { |_, value| value == :undef }.to_json, + Authorization: token, + content_type: :json, + 'X-Audit-Log-Reason': reason + ) + end + + # Modify the incident actions for a server. + # https://discord.com/developers/docs/resources/guild#modify-guild-incident-actions + def update_incident_actions(token, server_id, invites_disabled_until: :undef, dms_disabled_until: :undef, reason: nil) + Discordrb::API.request( + :guilds_sid_incidents_actions, + server_id, + :put, + "#{Discordrb::API.api_base}/guilds/#{server_id}/incident-actions", + { invites_disabled_until:, dms_disabled_until: }.reject { |_, value| value == :undef }.to_json, + Authorization: token, + content_type: :json, + 'X-Audit-Log-Reason': reason + ) + end + # Get a server's channels list # https://discord.com/developers/docs/resources/guild#get-guild-channels def channels(token, server_id) diff --git a/lib/discordrb/data/server.rb b/lib/discordrb/data/server.rb index c8f06fb48..1e545a069 100644 --- a/lib/discordrb/data/server.rb +++ b/lib/discordrb/data/server.rb @@ -9,16 +9,16 @@ module ServerAttributes # @return [String] the hexadecimal ID used to identify this server's icon. attr_reader :icon_id - # Utility function to get the URL for the icon image - # @return [String] the URL to the icon image - def icon_url - return nil unless @icon_id - - API.icon_url(@id, @icon_id) + # Utility method to get a server's icon URL. + # @param format [String] The URL will default to `webp`. You can otherwise specify one of `jpg` + # or `png` to override this. + # @return [String, nil] The URL to the server's icon, or `nil` if the server hasn't set an icon. + def icon_url(format: 'webp') + API.icon_url(@id, @icon_id, format) if @icon_id end end - # A server on Discord + # An isolated collection of channels and member's on Discord. class Server include IDObject include ServerAttributes @@ -50,14 +50,63 @@ class Server # @return [Hash VoiceState>] the hash (user ID => voice state) of voice states of members on this server attr_reader :voice_states - # The server's amount of Nitro boosters. - # @return [Integer] the amount of boosters, 0 if no one has boosted. + # @return [Integer] the server's amount of Nitro boosters, 0 if no one has boosted. attr_reader :booster_count - # The server's Nitro boost level. - # @return [Integer] the boost level, 0 if no level. + # @return [Integer] the server's Nitro boost level, 0 if no level. attr_reader :boost_level + # @return [String] the preferred locale of the server. Used in server discovery and notices from Discord. + attr_reader :locale + + # @return [String, nil] the description of the server. Shown in server discovery and external embeds. + attr_reader :description + + # @return [String, nil] the hash of the server's banner image or GIF. + attr_reader :banner_id + + # @return [String, nil] the hash of the server's invite splash image. + attr_reader :splash_id + alias_method :splash_hash, :splash_id + + # @return [Integer] the maximum number of members that can join the server. + attr_reader :max_member_count + + # @return [String, nil] the code of the server's custom vanity invite link. + attr_reader :vanity_invite_code + + # @return [Integer, nil] the maximum number of members that can concurrently be online in the server. + # Always set to `nil` except for the largest of servers. + attr_reader :max_presence_count + + # @return [String, nil] the hash of the server's discovery splash image. + attr_reader :discovery_splash_id + + # @return [Integer] the flags for the server's designated system channel. + attr_reader :system_channel_flags + + # @return [Integer] the maximum number of members that can concurrently watch a stream in a video channel. + attr_reader :max_video_channel_members + + # @return [Integer] the maximum number of members that can concurrently watch a stream in a stage channel. + attr_reader :max_stage_video_channel_members + + # @return [true, false] whether or not the server has the boost progress bar enabled. + attr_reader :boost_progress_bar + alias_method :boost_progress_bar?, :boost_progress_bar + + # @return [Time, nil] the time at when the last raid was detected on the server. + attr_reader :raid_detected_at + + # @return [Time, nil] the time at when DM spam was last detected on the server. + attr_reader :dm_spam_detected_at + + # @return [Time, nil] the time at when invites will be re-enabled on the server. + attr_reader :invites_disabled_until + + # @return [Time, nil] the time at when non-friend direct messages will be re-enabled on the server. + attr_reader :dms_disabled_until + # @!visibility private def initialize(data, bot) @bot = bot @@ -334,9 +383,8 @@ def preview # stylish way. `nil` if the widget is not enabled. def widget_url update_data if @widget_enabled.nil? - return unless @widget_enabled - API.widget_url(@id) + API.widget_url(@id) if @widget_enabled end # @param style [Symbol] The style the picture should have. Possible styles are: @@ -349,38 +397,31 @@ def widget_url # server icon and server name in a stylish way. `nil` if the widget is not enabled. def widget_banner_url(style) update_data if @widget_enabled.nil? - return unless @widget_enabled - API.widget_url(@id, style) + API.widget_url(@id, style) if @widget_enabled end - # @return [String] the hexadecimal ID used to identify this server's splash image for their VIP invite page. - def splash_id - @splash_id ||= JSON.parse(API::Server.resolve(@bot.token, @id))['splash'] + # Utility method to get a server's splash URL. + # @param format [String] The URL will default to `webp`. You can otherwise specify one of `jpg` or `png` to + # override this. + # @return [String, nil] The URL to the server's splash image, or `nil` if the server doesn't have a splash image. + def splash_url(format: 'webp') + API.splash_url(@id, @splash_id, format) if @splash_id end - alias splash_hash splash_id - # @return [String, nil] the splash image URL for the server's VIP invite page. - # `nil` if there is no splash image. - def splash_url - splash_id if @splash_id.nil? - return nil unless @splash_id - - API.splash_url(@id, @splash_id) + # Utility method to get a server's banner URL. + # @param format [String] The URL will default to `webp`. You can otherwise specify one of `jpg` or `png` to + # override this. + # @return [String, nil] The URL to the server's banner image, or `nil` if the server doesn't have a banner image. + def banner_url(format: 'webp') + API.banner_url(@id, @banner_id, format) if @banner_id end - # @return [String] the hexadecimal ID used to identify this server's banner image, shown by the server name. - def banner_id - @banner_id ||= JSON.parse(API::Server.resolve(@bot.token, @id))['banner'] - end - - # @return [String, nil] the banner image URL for the server's banner image, or - # `nil` if there is no banner image. - def banner_url - banner_id if @banner_id.nil? - return unless banner_id - - API.banner_url(@id, @banner_id) + # Utility method to get a server's discovery splash URL. + # @param format [String] The URL will default to `webp`. You can otherwise specify one of `jpg` or `png` to override this. + # @return [String, nil] The URL to the server's discovery splash image, or `nil` if the server doesn't have a discovery splash image. + def discovery_splash_url(format: 'webp') + API.discovery_splash_url(@id, @discovery_splash_id, format) if @discovery_splash_id end # @return [String] a URL that a user can use to navigate to this server in the client @@ -697,7 +738,7 @@ def leave # Sets the server's name. # @param name [String] The new server name. def name=(name) - update_server_data(name: name) + modify(name: name) end # @return [Array] collection of available voice regions to this guild @@ -719,35 +760,31 @@ def region # Moves the server to another region. This will cause a voice interruption of at most a second. # @param region [String] The new region the server should be in. def region=(region) - update_server_data(region: region.to_s) + update_data(JSON.parse(API::Server.update!(@bot.token, @id, region: region.to_s))) end # Sets the server's icon. - # @param icon [String, #read] The new icon, in base64-encoded JPG format. + # @param icon [String, #read, nil] The new icon, in base64-encoded JPG format. def icon=(icon) - if icon.respond_to?(:read) - update_server_data(icon_id: Discordrb.encode64(icon)) - else - update_server_data(icon_id: icon) - end + modify(icon: icon) end # Sets the server's AFK channel. # @param afk_channel [Channel, nil] The new AFK channel, or `nil` if there should be none set. def afk_channel=(afk_channel) - update_server_data(afk_channel_id: afk_channel.resolve_id) + modify(afk_channel: afk_channel) end # Sets the server's system channel. # @param system_channel [Channel, String, Integer, nil] The new system channel, or `nil` should it be disabled. def system_channel=(system_channel) - update_server_data(system_channel_id: system_channel.resolve_id) + modify(system_channel: system_channel) end # Sets the amount of time after which a user gets moved into the AFK channel. # @param afk_timeout [Integer] The AFK timeout, in seconds. def afk_timeout=(afk_timeout) - update_server_data(afk_timeout: afk_timeout) + modify(afk_timeout: afk_timeout) end # A map of possible server verification levels to symbol names @@ -759,17 +796,15 @@ def afk_timeout=(afk_timeout) very_high: 4 }.freeze - # @return [Symbol] the verification level of the server (:none = none, :low = 'Must have a verified email on their Discord account', :medium = 'Has to be registered with Discord for at least 5 minutes', :high = 'Has to be a member of this server for at least 10 minutes', :very_high = 'Must have a verified phone on their Discord account'). + # @return [Symbol] The verification level of the server (:none = none, :low = 'Must have a verified email on their Discord account', :medium = 'Has to be registered with Discord for at least 5 minutes', :high = 'Has to be a member of this server for at least 10 minutes', :very_high = 'Must have a verified phone on their Discord account'). def verification_level - VERIFICATION_LEVELS.key @verification_level + VERIFICATION_LEVELS.key(@verification_level) end # Sets the verification level of the server # @param level [Integer, Symbol] The verification level from 0-4 or Symbol (see {VERIFICATION_LEVELS}) def verification_level=(level) - level = VERIFICATION_LEVELS[level] if level.is_a?(Symbol) - - update_server_data(verification_level: level) + modify(verification_level: level) end # A map of possible message notification levels to symbol names @@ -778,27 +813,19 @@ def verification_level=(level) only_mentions: 1 }.freeze - # @return [Symbol] the default message notifications settings of the server (:all = 'All messages', :mentions = 'Only @mentions'). + # @return [Symbol] The default message notifications settings of the server (:all_messages = 'All messages', :only_mentions = 'Only @mentions'). def default_message_notifications - NOTIFICATION_LEVELS.key @default_message_notifications + NOTIFICATION_LEVELS.key(@default_message_notifications) end # Sets the default message notification level # @param notification_level [Integer, Symbol] The default message notification 0-1 or Symbol (see {NOTIFICATION_LEVELS}) def default_message_notifications=(notification_level) - notification_level = NOTIFICATION_LEVELS[notification_level] if notification_level.is_a?(Symbol) - - update_server_data(default_message_notifications: notification_level) + modify(notification_level: notification_level) end alias_method :notification_level=, :default_message_notifications= - # Sets the server splash - # @param splash_hash [String] The splash hash - def splash=(splash_hash) - update_server_data(splash: splash_hash) - end - # A map of possible content filter levels to symbol names FILTER_LEVELS = { disabled: 0, @@ -806,9 +833,9 @@ def splash=(splash_hash) all_members: 2 }.freeze - # @return [Symbol] the explicit content filter level of the server (:none = 'Don't scan any messages.', :exclude_roles = 'Scan messages for members without a role.', :all = 'Scan messages sent by all members.'). + # @return [Symbol] The explicit content filter level of the server (:disabled = 'Don't scan any messages.', :members_without_roles = 'Scan messages for members without a role.', :all_members = 'Scan messages sent by all members.'). def explicit_content_filter - FILTER_LEVELS.key @explicit_content_filter + FILTER_LEVELS.key(@explicit_content_filter) end alias_method :content_filter_level, :explicit_content_filter @@ -816,9 +843,31 @@ def explicit_content_filter # Sets the server content filter. # @param filter_level [Integer, Symbol] The content filter from 0-2 or Symbol (see {FILTER_LEVELS}) def explicit_content_filter=(filter_level) - filter_level = FILTER_LEVELS[filter_level] if filter_level.is_a?(Symbol) + modify(explicit_content_filter: filter_level) + end - update_server_data(explicit_content_filter: filter_level) + # A map of possible multi-factor authentication levels to symbol names + MFA_LEVELS = { + none: 0, + elevated: 1 + }.freeze + + # @return [Symbol] The multi-factor authentication level of the server (:none = 'no MFA/2FA requirement for moderation actions', :elevated = 'MFA/2FA is required for moderation actions') + def mfa_level + MFA_LEVELS.key @mfa_level + end + + # A map of possible NSFW levels to symbol names + NSFW_LEVELS = { + default: 0, + explicit: 1, + safe: 2, + age_restricted: 3 + }.freeze + + # @return [Symbol] The NSFW level of the server (:default = 'no NSFW level has been set', :explicit = 'the server may contain explicit content', :safe = 'the server does not contain NSFW content', :age_restricted = 'server membership is restricted to adults') + def nsfw_level + NSFW_LEVELS.key @nsfw_level end # @return [true, false] whether this server has any emoji or not. @@ -829,6 +878,41 @@ def any_emoji? alias_method :has_emoji?, :any_emoji? alias_method :emoji?, :any_emoji? + # Create an invite link using the server's vanity code. + # @return [String, nil] The server's vanity invite URL, or `nil` if the server does not have a vanity invite code. + def vanity_invite_url + return unless @vanity_invite_code + + "https://discord.gg/#{@vanity_invite_code}" + end + + alias_method :vanity_invite_link, :vanity_invite_url + + # Check if the auto-moderation system has detected a raid. + # @return [true, false] Whether or not Discord's anti-spam system has detected a raid in the server. + def raid_detected? + !@raid_detected_at.nil? + end + + # Check if the auto-moderation system has detected DM spam. + # @return [true, false] Whether or not Discord's anti-spam system has detected dm-spam in the server. + def dm_spam_detected? + !@dm_spam_detected_at.nil? + end + + # Check if the server has disabled non-friend DMs. + # @return [true, false] Whether or not the server has stopped member's who aren't friends from DMing each other. + def dms_disabled? + !@dms_disabled_until.nil? && @dms_disabled_until > Time.now + end + + # Check if the server has paused invites. + # @return [true, false] Whether or not the server has stopped new members from joining, either via incident actions + # or the `:invites_disabled` feature. + def invites_disabled? + (!@invites_disabled_until.nil? && @invites_disabled_until > Time.now) || @features.include?(:invites_disabled) + end + # Requests a list of Webhooks on the server. # @return [Array] webhooks on the server. def webhooks @@ -918,48 +1002,150 @@ def process_chunk(members, chunk_index, chunk_count) @chunked = true end + # Get the AFK channel of the server. # @return [Channel, nil] the AFK voice channel of this server, or `nil` if none is set. def afk_channel @bot.channel(@afk_channel_id) if @afk_channel_id end - # @return [Channel, nil] the system channel (used for automatic welcome messages) of a server, or `nil` if none is set. + # Get the rules channel of the server. + # @return [Channel, nil] The channel where community servers can display rules or guidelines, or `nil` if none is set. + def rules_channel + @bot.channel(@rules_channel_id) if @rules_channel_id + end + + # Get the system channel of the server. + # @return [Channel, nil] The system channel (used for automatic welcome messages) of a server, or `nil` if none is set. def system_channel @bot.channel(@system_channel_id) if @system_channel_id end + # Get the safety alerts channel of the server. + # @return [Channel, nil] The channel where Community servers receive safety alerts from Discord, or `nil` if none is set. + def safety_alerts_channel + @bot.channel(@safety_alerts_channel_id) if @safety_alerts_channel_id + end + + # Get the public updates channel of the server. + # @return [Channel, nil] The channel where Community servers receive public updates from Discord, or `nil` if none is set. + def public_updates_channel + @bot.channel(@public_updates_channel_id) if @public_updates_channel_id + end + + # Modify the properties of the server. + # @param name [String] The new 2-32 character name of the server. + # @param verification_level [Symbol, Integer, nil] The new verification level of the server. + # @param notification_level [Symbol, Integer, nil] The new default message notification level of the server. + # @param explicit_content_filter [Symbol, Integer, nil] The new explicit content filter level of the server. + # @param afk_channel [Channel, Integer, String, nil] The new AFK voice channel members should be automatically moved to. + # @param afk_timeout [Integer] The new AFK timeout in seconds. Can be set to one of `60`, `300`, `900`, `1800`, or `3600`. + # @param icon [#read, File, nil] The new icon of the server. Should be a file-like object that responds to `#read`. + # @param splash [#read, File, nil] The new invite splash of the server. Should be a file-like object that responds to `#read`. + # @param discovery_splash [#read, File, nil] The new discovery splash of the server. Should be a file-like object that responds to `#read`. + # @param banner [#read, File, nil] The new banner of the server. Should be a file-like object that responds to `#read`. + # @param system_channel [Channel, Integer, String, nil] The new channel where system messages should be sent. + # @param system_channel_flags [Integer] The new system channel flags to set for the server's system channel expressed as a bitfield. + # @param rules_channel [Channel, Integer, String, nil] The new channel where the server displays its rules or guidelines. + # @param public_updates_channel [Channel, Integer, String, nil] The new channel where public updates should be sent. + # @param locale [String, Symbol, nil] The new preferred locale of the server; primarily for community servers. + # @param features [Array] The new features to set for the server. + # @param description [String, nil] The new description of the server. + # @param boost_progress_bar [true, false] Whether or not the server boosting progress bar should be visible. + # @param safety_alerts_channel [Channel, Integer, String, nil] The new channel where safety alerts should be sent. + # @param dms_disabled_until [Time, nil] The time at when non-friend direct messages will be enabled again. + # @param invites_disabled_until [Time, nil] The time at when invites will no longer be disabled. + # @param reason [String, nil] The reason to show in the server's audit log for modifying the server. + # @return [nil] + def modify( + name: :undef, verification_level: :undef, notification_level: :undef, explicit_content_filter: :undef, + afk_channel: :undef, afk_timeout: :undef, icon: :undef, splash: :undef, discovery_splash: :undef, banner: :undef, + system_channel: :undef, system_channel_flags: :undef, rules_channel: :undef, public_updates_channel: :undef, + locale: :undef, features: :undef, description: :undef, boost_progress_bar: :undef, safety_alerts_channel: :undef, + dms_disabled_until: :undef, invites_disabled_until: :undef, reason: nil + ) + data = { + name: name, + verification_level: VERIFICATION_LEVELS[verification_level] || verification_level, + default_message_notifications: NOTIFICATION_LEVELS[notification_level] || notification_level, + explicit_content_filter: FILTER_LEVELS[explicit_content_filter] || explicit_content_filter, + afk_channel_id: afk_channel == :undef ? afk_channel : afk_channel&.resolve_id, + afk_timeout: afk_timeout, + icon: icon.respond_to?(:read) ? Discordrb.encode64(icon) : icon, + splash: splash.respond_to?(:read) ? Discordrb.encode64(splash) : splash, + discovery_splash: discovery_splash.respond_to?(:read) ? Discordrb.encode64(discovery_splash) : discovery_splash, + banner: banner.respond_to?(:read) ? Discordrb.encode64(banner) : banner, + system_channel_id: system_channel == :undef ? system_channel : system_channel&.resolve_id, + system_channel_flags: system_channel_flags, + rules_channel_id: rules_channel == :undef ? rules_channel : rules_channel&.resolve_id, + public_updates_channel_id: public_updates_channel == :undef ? public_updates_channel : public_updates_channel&.resolve_id, + preferred_locale: locale, + features: features == :undef ? features : features.map(&:upcase), + description: description, + premium_progress_bar_enabled: boost_progress_bar, + safety_alerts_channel_id: safety_alerts_channel == :undef ? safety_alerts_channel : safety_alerts_channel&.resolve_id + } + + if invites_disabled_until != :undef || dms_disabled_until != :undef + incidents_data = { + dms_disabled_until: dms_disabled_until == :undef ? @dms_disabled_until&.iso8601 : dms_disabled_until&.iso8601, + invites_disabled_until: invites_disabled_until == :undef ? @invites_disabled_until&.iso8601 : invites_disabled_until&.iso8601 + } + + process_incident_actions(JSON.parse(API::Server.update_incident_actions(@bot.token, @id, **incidents_data, reason: reason))) + return unless data.any? { |_, value| value != :undef } + end + + update_data(JSON.parse(API::Server.update!(@bot.token, @id, **data, reason: reason))) + nil + end + # Updates the cached data with new data # @note For internal use only # @!visibility private def update_data(new_data = nil) new_data ||= JSON.parse(API::Server.resolve(@bot.token, @id)) - @name = new_data[:name] || new_data['name'] || @name - @region_id = new_data[:region] || new_data['region'] || @region_id - @icon_id = new_data[:icon] || new_data['icon'] || @icon_id - @afk_timeout = new_data[:afk_timeout] || new_data['afk_timeout'] || @afk_timeout - - afk_channel_id = new_data[:afk_channel_id] || new_data['afk_channel_id'] || @afk_channel - @afk_channel_id = afk_channel_id&.resolve_id - widget_channel_id = new_data[:widget_channel_id] || new_data['widget_channel_id'] || @widget_channel - @widget_channel_id = widget_channel_id&.resolve_id - system_channel_id = new_data[:system_channel_id] || new_data['system_channel_id'] || @system_channel - @system_channel_id = system_channel_id&.resolve_id - - @widget_enabled = new_data[:widget_enabled] || new_data['widget_enabled'] - @splash = new_data[:splash_id] || new_data['splash_id'] || @splash_id - - @verification_level = new_data[:verification_level] || new_data['verification_level'] || @verification_level - @explicit_content_filter = new_data[:explicit_content_filter] || new_data['explicit_content_filter'] || @explicit_content_filter - @default_message_notifications = new_data[:default_message_notifications] || new_data['default_message_notifications'] || @default_message_notifications - - @large = new_data.key?('large') ? new_data['large'] : @large - @member_count = new_data['member_count'] || @member_count || 0 - @splash_id = new_data['splash'] || @splash_id - @banner_id = new_data['banner'] || @banner_id - @features = new_data['features'] ? new_data['features'].map { |element| element.downcase.to_sym } : @features || [] - @booster_count = new_data['premium_subscription_count'] || @booster_count || 0 - @boost_level = new_data['premium_tier'] || @boost_level + @name = new_data['name'] + @icon_id = new_data['icon'] + @splash_id = new_data['splash'] + @discovery_splash_id = new_data['discovery_splash'] @owner_id = new_data['owner_id'].to_i + @region_id = new_data['region'] if new_data.key?('region') + + @afk_timeout = new_data['afk_timeout'] + @afk_channel_id = new_data['afk_channel_id']&.to_i + + @widget_enabled = new_data['widget_enabled'] if new_data.key?('widget_enabled') + @widget_channel_id = new_data['widget_channel_id'] if new_data.key?('widget_channel_id') + + @system_channel_flags = new_data['system_channel_flags'] + @system_channel_id = new_data['system_channel_id']&.to_i + + @rules_channel_id = new_data['rules_channel_id']&.to_i + @public_updates_channel_id = new_data['public_updates_channel_id']&.to_i + @safety_alerts_channel_id = new_data['safety_alerts_channel_id']&.to_i + + @mfa_level = new_data['mfa_level'] + @nsfw_level = new_data['nsfw_level'] + @verification_level = new_data['verification_level'] + @explicit_content_filter = new_data['explicit_content_filter'] + @default_message_notifications = new_data['default_message_notifications'] + + @features = new_data['features']&.map { |feature| feature.downcase.to_sym } || @features || [] + @max_presence_count = new_data['max_presences'] if new_data.key?('max_presences') + @max_member_count = new_data['max_members'] if new_data.key?('max_members') + @large = new_data.key?('large') ? new_data['large'] : (@large || false) + @member_count = new_data['member_count'] || new_data['approximate_member_count'] || @member_count || 0 + + @vanity_url_code = new_data['vanity_url_code'] + @description = new_data['description'] + @banner_id = new_data['banner'] + @boost_level = new_data['premium_tier'] + @booster_count = new_data['premium_subscription_count'] || @booster_count || 0 + @locale = new_data['preferred_locale'] + + @max_video_channel_members = new_data['max_video_channel_users'] || @max_video_channel_members + @max_stage_video_channel_members = new_data['max_stage_video_channel_users'] || @max_stage_video_channel_members + @boost_progress_bar = new_data['premium_progress_bar_enabled'] process_channels(new_data['channels']) if new_data['channels'] process_roles(new_data['roles']) if new_data['roles'] @@ -968,6 +1154,7 @@ def update_data(new_data = nil) process_presences(new_data['presences']) if new_data['presences'] process_voice_states(new_data['voice_states']) if new_data['voice_states'] process_active_threads(new_data['threads']) if new_data['threads'] + process_incident_actions(new_data['incidents_data']) if new_data.key?('incidents_data') process_scheduled_events(new_data['guild_scheduled_events']) if new_data['guild_scheduled_events'] end @@ -1015,21 +1202,6 @@ def inspect private - def update_server_data(new_data) - response = JSON.parse(API::Server.update(@bot.token, @id, - new_data[:name] || @name, - new_data[:region] || @region_id, - new_data[:icon_id] || @icon_id, - new_data[:afk_channel_id] || @afk_channel_id, - new_data[:afk_timeout] || @afk_timeout, - new_data[:splash] || @splash, - new_data[:default_message_notifications] || @default_message_notifications, - new_data[:verification_level] || @verification_level, - new_data[:explicit_content_filter] || @explicit_content_filter, - new_data[:system_channel_id] || @system_channel_id)) - update_data(response) - end - def process_roles(roles) # Create roles @roles = {} @@ -1111,6 +1283,14 @@ def process_active_threads(threads) end end + def process_incident_actions(incidents) + incidents ||= {} + @raid_detected_at = incidents['raid_detected_at'] ? Time.parse(incidents['raid_detected_at']) : nil + @dms_disabled_until = incidents['dms_disabled_until'] ? Time.parse(incidents['dms_disabled_until']) : nil + @dm_spam_detected_at = incidents['dm_spam_detected_at'] ? Time.parse(incidents['dm_spam_detected_at']) : nil + @invites_disabled_until = incidents['invites_disabled_until'] ? Time.parse(incidents['invites_disabled_until']) : nil + end + def process_scheduled_events(events) @scheduled_events = {}