discorb 0.12.4 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/discorb/event.rb CHANGED
@@ -1,35 +1,276 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Discorb
4
- #
5
- # Represents a event.
6
- # This class shouldn't be instantiated directly.
7
- # Use {Client#on} instead.
8
- #
9
- class Event
10
- # @return [Proc] the block to be called.
11
- attr_reader :block
12
- # @return [Symbol] the event id.
2
+ class ScheduledEvent < DiscordModel
3
+ @privacy_level = {
4
+ 2 => :guild_only,
5
+ }
6
+ @status = {
7
+ 1 => :scheduled,
8
+ 2 => :active,
9
+ 3 => :completed,
10
+ 4 => :canceled,
11
+ }
12
+ @entity_type = {
13
+ 1 => :stage_instance,
14
+ 2 => :voice,
15
+ 3 => :external,
16
+ }
17
+
18
+ # @!visibility private
19
+ def initialize(client, data)
20
+ @client = client
21
+ @data = data
22
+ _set_data(data)
23
+ end
24
+
25
+ #
26
+ # Represents the metadata of the event.
27
+ #
28
+ class Metadata
29
+ # @return [String, nil] The location of the event. Only present if the event is a external event.
30
+ attr_reader :location
31
+ # @!visibility private
32
+ def initialize(data)
33
+ @location = data[:location]
34
+ end
35
+ end
36
+
37
+ # @return [Discorb::Snowflake] The ID of the event.
13
38
  attr_reader :id
14
- # @return [Hash] the event metadata.
39
+ # @return [String] The name of the event.
40
+ attr_reader :name
41
+ # @return [String] The description of the event.
42
+ attr_reader :description
43
+
44
+ # @return [Time] The time the event starts.
45
+ attr_reader :scheduled_start_time
46
+ alias start_time scheduled_start_time
47
+ alias start_at scheduled_start_time
48
+ # @return [Time] The time the event ends.
49
+ attr_reader :scheduled_end_time
50
+ alias end_time scheduled_end_time
51
+ alias end_at scheduled_end_time
52
+ # @return [:guild_only] The privacy level of the event.
53
+ attr_reader :privacy_level
54
+ # @return [:scheduled, :active, :completed, :canceled] The status of the event.
55
+ attr_reader :status
56
+ # @return [:stage_instance, :voice, :external] The type of the event.
57
+ attr_reader :entity_type
58
+ # @return [Discorb::Snowflake] The ID of the entity the event is for.
59
+ attr_reader :entity_id
60
+ # @return [Discorb::ScheduledEvent::Metadata] The metadata of the event.
15
61
  attr_reader :metadata
16
- # @return [Boolean] whether the event is once or not.
17
- attr_reader :once
18
- alias once? once
62
+ # @return [Integer] The user count of the event.
63
+ attr_reader :user_count
64
+
65
+ # @!attribute [r] guild
66
+ # @return [Discorb::Guild, nil] The guild of the event.
67
+ # @!attribute [r] channel
68
+ # @return [Discorb::Channel, nil] The channel of the event.
69
+ # Only present if the event will do in stage instance or voice channel.
70
+ # @!attribute [r] creator
71
+ # @return [Discorb::User] The user who created the event.#
72
+ # @!attribute [r] time
73
+ # @return [Range<Time>] The time range of the event.
74
+
75
+ def guild
76
+ @client.guilds[@guild_id]
77
+ end
78
+
79
+ def channel
80
+ @client.channels[@channel_id]
81
+ end
82
+
83
+ def creator
84
+ @creator || @client.users[@creator_id]
85
+ end
86
+
87
+ def time
88
+ @scheduled_start_time..@scheduled_end_time
89
+ end
90
+
91
+ #
92
+ # Create a scheduled event for the guild.
93
+ # @macro async
94
+ # @macro http
95
+ #
96
+ # @param [:stage_instance, :voice, :external] type The type of event to create.
97
+ # @param [String] name The name of the event.
98
+ # @param [String] description The description of the event.
99
+ # @param [Time] start_time The start time of the event.
100
+ # @param [Time, nil] end_time The end time of the event. Defaults to `nil`.
101
+ # @param [Discorb::Channel, Discorb::Snowflake, nil] channel The channel to run the event in.
102
+ # @param [String, nil] location The location of the event. Defaults to `nil`.
103
+ # @param [:guild_only] privacy_level The privacy level of the event. This must be `:guild_only`.
104
+ # @param [:active, :completed, :canceled] status The status of the event.
105
+ #
106
+ # @see Event#start
107
+ # @see Event#cancel
108
+ # @see Event#complete
109
+ #
110
+ def edit(
111
+ type: Discorb::Unset,
112
+ name: Discorb::Unset,
113
+ description: Discorb::Unset,
114
+ start_time: Discorb::Unset,
115
+ end_time: Discorb::Unset,
116
+ privacy_level: Discorb::Unset,
117
+ location: Discorb::Unset,
118
+ channel: Discorb::Unset,
119
+ status: Discorb::Unset
120
+ )
121
+ Async do
122
+ payload = case (type == Discorb::Unset) ? @entity_type : type
123
+ when :stage_instance
124
+ raise ArgumentError, "channel must be provided for stage_instance events" unless channel
125
+ {
126
+ name: name,
127
+ description: description,
128
+ scheduled_start_time: start_time.iso8601,
129
+ scheduled_end_time: end_time&.iso8601,
130
+ privacy_level: Discorb::ScheduledEvent.privacy_level.key(privacy_level) || Discorb::Unset,
131
+ channel_id: channel&.id,
132
+ entity_type: Discorb::ScheduledEvent.entity_type.key(:stage_instance),
133
+ status: Discorb::ScheduledEvent.status.key(status) || Discorb::Unset,
134
+ }.reject { |_, v| v == Discorb::Unset }
135
+ when :voice
136
+ raise ArgumentError, "channel must be provided for voice events" unless channel
137
+ {
138
+ name: name,
139
+ description: description,
140
+ scheduled_start_time: start_time.iso8601,
141
+ scheduled_end_time: end_time&.iso8601,
142
+ privacy_level: Discorb::ScheduledEvent.privacy_level.key(privacy_level) || Discorb::Unset,
143
+ channel_id: channel&.id,
144
+ entity_type: Discorb::ScheduledEvent.entity_type.key(:voice),
145
+ status: Discorb::ScheduledEvent.status.key(status) || Discorb::Unset,
146
+ }.reject { |_, v| v == Discorb::Unset }
147
+ when :external
148
+ raise ArgumentError, "location must be provided for external events" unless location
149
+ raise ArgumentError, "end_time must be provided for external events" unless end_time
150
+ {
151
+ name: name,
152
+ description: description,
153
+ channel_id: nil,
154
+ scheduled_start_time: start_time.iso8601,
155
+ scheduled_end_time: end_time.iso8601,
156
+ privacy_level: Discorb::ScheduledEvent.privacy_level.key(privacy_level) || Discorb::Unset,
157
+ entity_type: Discorb::ScheduledEvent.entity_type.key(:external),
158
+ entity_metadata: {
159
+ location: location,
160
+ },
161
+ status: Discorb::ScheduledEvent.status.key(status) || Discorb::Unset,
162
+ }.reject { |_, v| v == Discorb::Unset }
163
+ else
164
+ raise ArgumentError, "Invalid scheduled event type: #{type}"
165
+ end
166
+ @client.http.patch("/guilds/#{@guild_id}/scheduled-events/#{@id}", payload).wait
167
+ end
168
+ end
169
+
170
+ alias modify edit
19
171
 
20
- def initialize(block, id, metadata)
21
- @block = block
22
- @id = id
23
- @once = metadata.fetch(:once, false)
24
- @metadata = metadata
25
- @rescue = nil
172
+ #
173
+ # Starts the event. Shortcut for `edit(status: :active)`.
174
+ #
175
+ def start
176
+ edit(status: :active)
26
177
  end
27
178
 
28
179
  #
29
- # Calls the block associated with the event.
180
+ # Completes the event. Shortcut for `edit(status: :completed)`.
181
+ #
182
+ def complete
183
+ edit(status: :completed)
184
+ end
185
+
186
+ alias finish complete
187
+
188
+ #
189
+ # Cancels the event. Shortcut for `edit(status: :canceled)`.
30
190
  #
31
- def call(...)
32
- @block.call(...)
191
+ def cancel
192
+ edit(status: :canceled)
193
+ end
194
+
195
+ #
196
+ # Deletes the event.
197
+ # @macro async
198
+ # @macro http
199
+ #
200
+ def delete!
201
+ Async do
202
+ @client.http.delete("/guilds/#{@guild_id}/scheduled-events/#{@id}").wait
203
+ end
204
+ end
205
+
206
+ alias destroy! delete!
207
+
208
+ #
209
+ # Fetches the event users.
210
+ # @macro async
211
+ # @macro http
212
+ #
213
+ # @note You can fetch all of members by not specifying a parameter.
214
+ #
215
+ # @param [Integer] limit The maximum number of users to fetch. Defaults to `100`.
216
+ # @param [#to_s] after The ID of the user to start fetching from. Defaults to `nil`.
217
+ # @param [#to_s] before The ID of the user to stop fetching at. Defaults to `nil`.
218
+ # @param [Boolean] with_member Whether to include the member object of the event. Defaults to `false`.
219
+ # This should be used for manual fetching of members.
220
+ #
221
+ # @return [Array<Discorb::Member>] The event users.
222
+ #
223
+ def fetch_users(limit = nil, before: nil, after: nil, with_member: true)
224
+ Async do
225
+ if limit.nil?
226
+ after = 0
227
+ res = []
228
+ while true
229
+ _resp, users = @client.http.get("/guilds/#{@guild_id}/scheduled-events/#{@id}/users?limit=100&after=#{after}&with_member=true").wait
230
+ if users.empty?
231
+ break
232
+ end
233
+ res += users.map { |u| Member.new(@client, @guild_id, u[:user], u[:member]) }
234
+ after = users.last[:user][:id]
235
+ end
236
+ res
237
+ else
238
+ params = {
239
+ limit: limit,
240
+ before: Discorb::Utils.try(after, :id),
241
+ after: Discorb::Utils.try(around, :id),
242
+ with_member: with_member,
243
+ }.filter { |_k, v| !v.nil? }.to_h
244
+ _resp, messages = @client.http.get("/channels/#{channel_id.wait}/messages?#{URI.encode_www_form(params)}").wait
245
+ messages.map { |m| Message.new(@client, m.merge({ guild_id: @guild_id.to_s })) }
246
+ end
247
+ end
248
+ end
249
+
250
+ alias fetch_members fetch_users
251
+
252
+ private
253
+
254
+ def _set_data(data)
255
+ @id = Snowflake.new(data[:id])
256
+ @guild_id = Snowflake.new(data[:guild_id])
257
+ @channel_id = data[:channel_id] && Snowflake.new(data[:channel_id])
258
+ @creator_id = data[:creator_id] && Snowflake.new(data[:creator_id])
259
+ @name = data[:name]
260
+ @description = data[:description]
261
+ @scheduled_start_time = Time.iso8601(data[:scheduled_start_time])
262
+ @scheduled_end_time = data[:scheduled_end_time] && Time.iso8601(data[:scheduled_end_time])
263
+ @privacy_level = :guild_only # data[:privacy_level]
264
+ @status = self.class.status[data[:status]]
265
+ @entity_type = self.class.entity_type[data[:entity_type]]
266
+ @entity_id = data[:entity_id] && Snowflake.new(data[:entity_id])
267
+ @entity_metadata = data[:entity_metadata] && Metadata.new(data[:entity_metadata])
268
+ @creator = @client.users[@creator_id] || (data[:creator] && User.new(@client, data[:creator]))
269
+ @user_count = data[:user_count]
270
+ end
271
+
272
+ class << self
273
+ attr_reader :status, :entity_type, :privacy_level
33
274
  end
34
275
  end
35
276
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a event handler.
6
+ # This class shouldn't be instantiated directly.
7
+ # Use {Client#on} instead.
8
+ #
9
+ class EventHandler
10
+ # @return [Proc] the block to be called.
11
+ attr_reader :block
12
+ # @return [Symbol] the event id.
13
+ attr_reader :id
14
+ # @return [Hash] the event metadata.
15
+ attr_reader :metadata
16
+ # @return [Boolean] whether the event is once or not.
17
+ attr_reader :once
18
+ alias once? once
19
+
20
+ def initialize(block, id, metadata)
21
+ @block = block
22
+ @id = id
23
+ @once = metadata.fetch(:once, false)
24
+ @metadata = metadata
25
+ @rescue = nil
26
+ end
27
+
28
+ def inspect
29
+ "#<#{self.class} @id=#{@id}"
30
+ end
31
+
32
+ #
33
+ # Calls the block associated with the event.
34
+ #
35
+ def call(...)
36
+ @block.call(...)
37
+ end
38
+ end
39
+ end
@@ -17,7 +17,7 @@ module Discorb
17
17
  ret = {}
18
18
  self.class.events.each do |event, handlers|
19
19
  ret[event] = handlers.map do |handler|
20
- Discorb::Event.new(Proc.new { |*args, **kwargs| instance_exec(*args, **kwargs, &handler[2]) }, handler[0], handler[1])
20
+ Discorb::EventHandler.new(Proc.new { |*args, **kwargs| instance_exec(*args, **kwargs, &handler[2]) }, handler[0], handler[1])
21
21
  end
22
22
  end
23
23
  @events = ret
@@ -38,7 +38,7 @@ module Discorb
38
38
  # @param [Symbol] id The id of the event. Used to delete the event.
39
39
  # @param [Hash] metadata Other metadata.
40
40
  #
41
- # @return [Discorb::Event] The event.
41
+ # @return [Discorb::EventHandler] The event.
42
42
  #
43
43
  def event(event_name, id: nil, **metadata, &block)
44
44
  raise ArgumentError, "Event name must be a symbol" unless event_name.is_a?(Symbol)
@@ -57,13 +57,13 @@ module Discorb
57
57
  # @param [Hash] metadata Other metadata.
58
58
  # @param [Proc] block The block to execute when the event is triggered.
59
59
  #
60
- # @return [Discorb::Event] The event.
60
+ # @return [Discorb::EventHandler] The event.
61
61
  #
62
62
  def once_event(event_name, id: nil, **metadata, &block)
63
63
  event(event_name, id: id, once: true, **metadata, &block)
64
64
  end
65
65
 
66
- # @return [Hash{Symbol => Array<Discorb::Event>}] The events of the extension.
66
+ # @return [Hash{Symbol => Array<Discorb::EventHandler>}] The events of the extension.
67
67
  attr_reader :events
68
68
  # @return [Array<Discorb::ApplicationCommand::Command>] The commands of the extension.
69
69
  attr_reader :commands
data/lib/discorb/file.rb CHANGED
@@ -89,5 +89,9 @@ module Discorb
89
89
  filename ||= string.object_id.to_s + ".txt"
90
90
  new(io, filename, content_type: content_type)
91
91
  end
92
+
93
+ def inspect
94
+ "#<#{self.class} filename=#{@filename} content_type=#{@content_type}>"
95
+ end
92
96
  end
93
97
  end
data/lib/discorb/flag.rb CHANGED
@@ -96,6 +96,10 @@ module Discorb
96
96
  self.class.new(~@value)
97
97
  end
98
98
 
99
+ def inspect
100
+ "#<#{self.class}: #{@value}>"
101
+ end
102
+
99
103
  class << self
100
104
  # @return [Hash{Integer => Symbol}] the bits of the flag.
101
105
  attr_reader :bits
@@ -210,6 +210,28 @@ module Discorb
210
210
  end
211
211
  end
212
212
 
213
+ #
214
+ # Represents a `GUILD_SCHEDULED_EVENT_USER_ADD` and `GUILD_SCHEDULED_EVENT_USER_REMOVE` event.
215
+ #
216
+ class ScheduledEventUserEvent < GatewayEvent
217
+ # @return [Discorb::User] The user that triggered the event.
218
+ attr_reader :user
219
+ # @return [Discorb::Guild] The guild the event was triggered in.
220
+ attr_reader :guild
221
+ # @return [Discorb::ScheduledEvent] The scheduled event.
222
+ attr_reader :scheduled_event
223
+ # @private
224
+ def initialize(client, data)
225
+ @client = client
226
+ @scheduled_event_id = Snowflake.new(data[:scheduled_event_id])
227
+ @user_id = Snowflake.new(data[:user_id])
228
+ @guild_id = Snowflake.new(data[:guild_id])
229
+ @guild = client.guilds[data[:guild_id]]
230
+ @scheduled_event = @guild.scheduled_events[@scheduled_event_id]
231
+ @user = client.users[data[:user_id]]
232
+ end
233
+ end
234
+
213
235
  #
214
236
  # Represents a `MESSAGE_UPDATE` event.
215
237
  #
@@ -1042,11 +1064,44 @@ module Discorb
1042
1064
  @log.info("Successfully resumed connection")
1043
1065
  @tasks << handle_heartbeat
1044
1066
  dispatch(:resumed)
1067
+ when "GUILD_SCHEDULED_EVENT_CREATE"
1068
+ @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1069
+ event = ScheduledEvent.new(self, data)
1070
+ guild.scheduled_events[data[:id]] = event
1071
+ dispatch(:scheduled_event_create, event)
1072
+ when "GUILD_SCHEDULED_EVENT_UPDATE"
1073
+ @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1074
+ @log.warn("Unknown scheduled event id #{data[:id]}, ignoring") unless (event = guild.scheduled_events[data[:id]])
1075
+ old = event.dup
1076
+ event.send(:_set_data, data)
1077
+ dispatch(:scheduled_event_update, old, event)
1078
+ if old.status != event.status
1079
+ case event.status
1080
+ when :active
1081
+ dispatch(:scheduled_event_start, event)
1082
+ when :completed
1083
+ dispatch(:scheduled_event_end, event)
1084
+ end
1085
+ else
1086
+ dispatch(:scheduled_event_edit, old, event)
1087
+ end
1088
+ when "GUILD_SCHEDULED_EVENT_DELETE"
1089
+ @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1090
+ @log.warn("Unknown scheduled event id #{data[:id]}, ignoring") unless (event = guild.scheduled_events[data[:id]])
1091
+ guild.scheduled_events.remove(data[:id])
1092
+ dispatch(:scheduled_event_delete, event)
1093
+ dispatch(:scheduled_event_cancel, event)
1094
+ when "GUILD_SCHEDULED_EVENT_USER_ADD"
1095
+ @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1096
+ dispatch(:scheduled_event_user_add, ScheduledEventUserEvent.new(self, data))
1097
+ when "GUILD_SCHEDULED_EVENT_USER_REMOVE"
1098
+ @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1099
+ dispatch(:scheduled_event_user_remove, ScheduledEventUserEvent.new(self, data))
1045
1100
  else
1046
1101
  if respond_to?("event_" + event_name.downcase)
1047
1102
  __send__("event_" + event_name.downcase, data)
1048
1103
  else
1049
- @log.debug "#{event_name}\n#{data.inspect}"
1104
+ @log.debug "Unhandled event: #{event_name}\n#{data.inspect}"
1050
1105
  end
1051
1106
  end
1052
1107
  end
@@ -39,6 +39,10 @@ module Discorb
39
39
  }
40
40
  end
41
41
 
42
+ def inspect
43
+ "#<#{self.class} @type=#{@type}>"
44
+ end
45
+
42
46
  class << self
43
47
  # @private
44
48
  attr_reader :types
data/lib/discorb/guild.rb CHANGED
@@ -96,6 +96,9 @@ module Discorb
96
96
  # @return [Boolean] Whether the guild is available.
97
97
  attr_reader :available
98
98
  alias available? available
99
+ # @return [Dictionary{Discorb::Snowflake => Discorb::ScheduledEvent}] A dictionary of scheduled events in the guild.
100
+ attr_reader :scheduled_events
101
+ alias events scheduled_events
99
102
 
100
103
  # @!attribute [r] afk_channel
101
104
  # @return [Discorb::VoiceChannel] The AFK channel for this guild.
@@ -169,6 +172,113 @@ module Discorb
169
172
  end
170
173
  end
171
174
 
175
+ #
176
+ # Fetch scheduled events for the guild.
177
+ # @macro async
178
+ # @macro http
179
+ #
180
+ # @param [Boolean] with_user_count Whether to include the user count in the events.
181
+ # Defaults to `true`.
182
+ #
183
+ # @return [Array<Discorb::ScheduledEvent>] The events for the guild.
184
+ #
185
+ def fetch_scheduled_events(with_user_count: true)
186
+ Async do
187
+ _resp, events = @client.http.get("/guilds/#{@id}/scheduled-events?with_user_count=#{with_user_count}").wait
188
+ @scheduled_events = events.map { |e| ScheduledEvent.new(@client, e) }
189
+ end
190
+ end
191
+
192
+ #
193
+ # Fetch the scheduled event by ID.
194
+ # @macro async
195
+ # @macro http
196
+ #
197
+ # @param [#to_s] id The ID of the scheduled event.
198
+ #
199
+ # @return [Discorb::ScheduledEvent] The event with the given ID.
200
+ # @return [nil] If no event with the given ID exists.
201
+ #
202
+ def fetch_scheduled_event(id)
203
+ Async do
204
+ _resp, event = @client.http.get("/guilds/#{@id}/scheduled-events/#{id}").wait
205
+ rescue Discorb::NotFoundError
206
+ return nil
207
+ else
208
+ ScheduledEvent.new(@client, event)
209
+ end
210
+ end
211
+
212
+ #
213
+ # Create a scheduled event for the guild.
214
+ #
215
+ # @param [:stage_instance, :voice, :external] type The type of event to create.
216
+ # @param [String] name The name of the event.
217
+ # @param [String] description The description of the event.
218
+ # @param [Time] start_time The start time of the event.
219
+ # @param [Time, nil] end_time The end time of the event. Defaults to `nil`.
220
+ # @param [Discorb::Channel, Discorb::Snowflake, nil] channel The channel to run the event in.
221
+ # @param [String, nil] location The location of the event. Defaults to `nil`.
222
+ # @param [:guild_only] privacy_level The privacy level of the event. This must be `:guild_only`.
223
+ #
224
+ # @return [Discorb::ScheduledEvent] The created event.
225
+ #
226
+ def create_scheduled_event(
227
+ type,
228
+ name,
229
+ description,
230
+ start_time,
231
+ end_time = nil,
232
+ privacy_level: :guild_only,
233
+ location: nil,
234
+ channel: nil
235
+ )
236
+ Async do
237
+ payload = case type
238
+ when :stage_instance
239
+ raise ArgumentError, "channel must be provided for stage_instance events" unless channel
240
+ {
241
+ name: name,
242
+ description: description,
243
+ scheduled_start_time: start_time.iso8601,
244
+ scheduled_end_time: end_time&.iso8601,
245
+ privacy_level: Discorb::ScheduledEvent.privacy_level.key(privacy_level),
246
+ channel_id: channel&.id,
247
+ entity_type: Discorb::ScheduledEvent.entity_type.key(:stage_instance),
248
+ }
249
+ when :voice
250
+ raise ArgumentError, "channel must be provided for voice events" unless channel
251
+ {
252
+ name: name,
253
+ description: description,
254
+ scheduled_start_time: start_time.iso8601,
255
+ scheduled_end_time: end_time&.iso8601,
256
+ privacy_level: Discorb::ScheduledEvent.privacy_level.key(privacy_level),
257
+ channel_id: channel&.id,
258
+ entity_type: Discorb::ScheduledEvent.entity_type.key(:voice),
259
+ }
260
+ when :external
261
+ raise ArgumentError, "location must be provided for external events" unless location
262
+ raise ArgumentError, "end_time must be provided for external events" unless end_time
263
+ {
264
+ name: name,
265
+ description: description,
266
+ scheduled_start_time: start_time.iso8601,
267
+ scheduled_end_time: end_time.iso8601,
268
+ privacy_level: Discorb::ScheduledEvent.privacy_level.key(privacy_level),
269
+ entity_type: Discorb::ScheduledEvent.entity_type.key(:external),
270
+ entity_metadata: {
271
+ location: location,
272
+ },
273
+ }
274
+ else
275
+ raise ArgumentError, "Invalid scheduled event type: #{type}"
276
+ end
277
+ _resp, event = @client.http.post("/guilds/#{@id}/scheduled-events", payload).wait
278
+ Discorb::ScheduledEvent.new(@client, event)
279
+ end
280
+ end
281
+
172
282
  #
173
283
  # Fetch emoji list of the guild.
174
284
  # @macro async
@@ -1143,6 +1253,7 @@ module Discorb
1143
1253
  @presences = Dictionary.new(data[:presences].map { |pr| [Snowflake.new(pr[:user][:id]), Presence.new(@client, pr)] }.to_h)
1144
1254
  @max_presences = data[:max_presences]
1145
1255
  @stage_instances = Dictionary.new(data[:stage_instances].map { |s| [Snowflake.new(s[:id]), StageInstance.new(@client, s)] }.to_h)
1256
+ @scheduled_events = Dictionary.new(data[:guild_scheduled_events].map { |s| [Snowflake.new(s[:id]), ScheduledEvent.new(@client, s)] }.to_h)
1146
1257
  @data.update(data)
1147
1258
  end
1148
1259
  end
@@ -1155,12 +1266,14 @@ module Discorb
1155
1266
  # |`1 << 0`|`:member_join`|
1156
1267
  # |`1 << 1`|`:server_boost`|
1157
1268
  # |`1 << 2`|`:setup_tips`|
1269
+ # |`1 << 3`|`:join_stickers`|
1158
1270
  #
1159
1271
  class SystemChannelFlag < Flag
1160
1272
  @bits = {
1161
1273
  member_join: 0,
1162
1274
  server_boost: 1,
1163
1275
  setup_tips: 2,
1276
+ join_stickers: 3,
1164
1277
  }.freeze
1165
1278
  end
1166
1279
 
data/lib/discorb/image.rb CHANGED
@@ -16,12 +16,10 @@ module Discorb
16
16
  #
17
17
  def initialize(source, type = nil)
18
18
  if source.respond_to?(:read)
19
- @bytes = source.read
19
+ @io = source
20
20
  @type = type || MIME::Types.type_for(source.path).first.content_type
21
21
  elsif ::File.exist?(source)
22
- ::File.open(source, "rb") do |file|
23
- @bytes = file.read
24
- end
22
+ @io = ::File.open(source, "rb")
25
23
  @type = MIME::Types.type_for(source).first.to_s
26
24
  else
27
25
  raise ArgumentError, "Couldn't read file."
@@ -34,7 +32,11 @@ module Discorb
34
32
  # @return [String] The image as a Discord style.
35
33
  #
36
34
  def to_s
37
- "data:#{@type};base64,#{Base64.strict_encode64(@bytes)}"
35
+ "data:#{@type};base64,#{Base64.strict_encode64(@io.read)}"
36
+ end
37
+
38
+ def inspect
39
+ "#<#{self.class} #{@type}>"
38
40
  end
39
41
  end
40
42
  end