discorb 0.12.2 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_main.yml +1 -0
  3. data/.github/workflows/build_version.yml +1 -0
  4. data/.github/workflows/crowdin.yml +32 -0
  5. data/.gitignore +3 -1
  6. data/.yardopts +2 -0
  7. data/Changelog.md +399 -367
  8. data/Gemfile +5 -1
  9. data/README.md +1 -1
  10. data/Rakefile +139 -9
  11. data/crowdin.yml +2 -0
  12. data/discorb.gemspec +1 -1
  13. data/docs/Examples.md +2 -0
  14. data/docs/application_command.md +17 -12
  15. data/docs/cli/irb.md +2 -0
  16. data/docs/cli/new.md +2 -0
  17. data/docs/cli/run.md +3 -1
  18. data/docs/cli/setup.md +4 -2
  19. data/docs/cli.md +2 -0
  20. data/docs/events.md +59 -5
  21. data/docs/extension.md +2 -2
  22. data/docs/faq.md +4 -2
  23. data/docs/license.md +2 -0
  24. data/docs/tutorial.md +4 -3
  25. data/docs/voice_events.md +2 -0
  26. data/lib/discorb/app_command.rb +13 -7
  27. data/lib/discorb/application.rb +32 -2
  28. data/lib/discorb/audit_logs.rb +28 -16
  29. data/lib/discorb/channel.rb +112 -81
  30. data/lib/discorb/client.rb +17 -19
  31. data/lib/discorb/common.rb +28 -1
  32. data/lib/discorb/components.rb +12 -0
  33. data/lib/discorb/dictionary.rb +1 -1
  34. data/lib/discorb/embed.rb +4 -0
  35. data/lib/discorb/emoji.rb +9 -7
  36. data/lib/discorb/emoji_table.rb +3774 -3689
  37. data/lib/discorb/event.rb +266 -24
  38. data/lib/discorb/event_handler.rb +39 -0
  39. data/lib/discorb/exe/show.rb +2 -0
  40. data/lib/discorb/extension.rb +5 -5
  41. data/lib/discorb/file.rb +4 -0
  42. data/lib/discorb/flag.rb +5 -1
  43. data/lib/discorb/gateway.rb +65 -14
  44. data/lib/discorb/gateway_requests.rb +4 -0
  45. data/lib/discorb/guild.rb +169 -82
  46. data/lib/discorb/guild_template.rb +12 -9
  47. data/lib/discorb/http.rb +82 -37
  48. data/lib/discorb/image.rb +7 -5
  49. data/lib/discorb/integration.rb +4 -1
  50. data/lib/discorb/intents.rb +8 -3
  51. data/lib/discorb/interaction/autocomplete.rb +1 -1
  52. data/lib/discorb/interaction/command.rb +2 -2
  53. data/lib/discorb/interaction/response.rb +27 -25
  54. data/lib/discorb/interaction/root.rb +8 -0
  55. data/lib/discorb/invite.rb +3 -2
  56. data/lib/discorb/log.rb +4 -0
  57. data/lib/discorb/member.rb +42 -13
  58. data/lib/discorb/message.rb +32 -17
  59. data/lib/discorb/modules.rb +19 -26
  60. data/lib/discorb/permission.rb +4 -0
  61. data/lib/discorb/rate_limit.rb +6 -2
  62. data/lib/discorb/role.rb +15 -11
  63. data/lib/discorb/sticker.rb +17 -12
  64. data/lib/discorb/user.rb +8 -7
  65. data/lib/discorb/voice_state.rb +8 -5
  66. data/lib/discorb/webhook.rb +38 -47
  67. data/lib/discorb.rb +2 -2
  68. data/po/yard.pot +7775 -5157
  69. data/sig/discorb.rbs +3317 -3820
  70. data/template-replace/scripts/locale_ja.rb +62 -0
  71. data/template-replace/scripts/yard_replace.rb +6 -0
  72. metadata +7 -4
data/lib/discorb/event.rb CHANGED
@@ -1,35 +1,277 @@
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
+ # @async
94
+ #
95
+ # @param [:stage_instance, :voice, :external] type The type of event to create.
96
+ # @param [String] name The name of the event.
97
+ # @param [String] description The description of the event.
98
+ # @param [Time] start_time The start time of the event.
99
+ # @param [Time, nil] end_time The end time of the event. Defaults to `nil`.
100
+ # @param [Discorb::Channel, Discorb::Snowflake, nil] channel The channel to run the event in.
101
+ # @param [String, nil] location The location of the event. Defaults to `nil`.
102
+ # @param [:guild_only] privacy_level The privacy level of the event. This must be `:guild_only`.
103
+ # @param [:active, :completed, :canceled] status The status of the event.
104
+ #
105
+ # @return [Async::Task<Discorb::ScheduledEvent>] The event that was created.
106
+ #
107
+ # @see Event#start
108
+ # @see Event#cancel
109
+ # @see Event#complete
110
+ #
111
+ def edit(
112
+ type: Discorb::Unset,
113
+ name: Discorb::Unset,
114
+ description: Discorb::Unset,
115
+ start_time: Discorb::Unset,
116
+ end_time: Discorb::Unset,
117
+ privacy_level: Discorb::Unset,
118
+ location: Discorb::Unset,
119
+ channel: Discorb::Unset,
120
+ status: Discorb::Unset
121
+ )
122
+ Async do
123
+ payload = case (type == Discorb::Unset) ? @entity_type : type
124
+ when :stage_instance
125
+ raise ArgumentError, "channel must be provided for stage_instance events" unless channel
126
+ {
127
+ name: name,
128
+ description: description,
129
+ scheduled_start_time: start_time.iso8601,
130
+ scheduled_end_time: end_time&.iso8601,
131
+ privacy_level: Discorb::ScheduledEvent.privacy_level.key(privacy_level) || Discorb::Unset,
132
+ channel_id: channel&.id,
133
+ entity_type: Discorb::ScheduledEvent.entity_type.key(:stage_instance),
134
+ status: Discorb::ScheduledEvent.status.key(status) || Discorb::Unset,
135
+ }.reject { |_, v| v == Discorb::Unset }
136
+ when :voice
137
+ raise ArgumentError, "channel must be provided for voice events" unless channel
138
+ {
139
+ name: name,
140
+ description: description,
141
+ scheduled_start_time: start_time.iso8601,
142
+ scheduled_end_time: end_time&.iso8601,
143
+ privacy_level: Discorb::ScheduledEvent.privacy_level.key(privacy_level) || Discorb::Unset,
144
+ channel_id: channel&.id,
145
+ entity_type: Discorb::ScheduledEvent.entity_type.key(:voice),
146
+ status: Discorb::ScheduledEvent.status.key(status) || Discorb::Unset,
147
+ }.reject { |_, v| v == Discorb::Unset }
148
+ when :external
149
+ raise ArgumentError, "location must be provided for external events" unless location
150
+ raise ArgumentError, "end_time must be provided for external events" unless end_time
151
+ {
152
+ name: name,
153
+ description: description,
154
+ channel_id: nil,
155
+ scheduled_start_time: start_time.iso8601,
156
+ scheduled_end_time: end_time.iso8601,
157
+ privacy_level: Discorb::ScheduledEvent.privacy_level.key(privacy_level) || Discorb::Unset,
158
+ entity_type: Discorb::ScheduledEvent.entity_type.key(:external),
159
+ entity_metadata: {
160
+ location: location,
161
+ },
162
+ status: Discorb::ScheduledEvent.status.key(status) || Discorb::Unset,
163
+ }.reject { |_, v| v == Discorb::Unset }
164
+ else
165
+ raise ArgumentError, "Invalid scheduled event type: #{type}"
166
+ end
167
+ @client.http.patch("/guilds/#{@guild_id}/scheduled-events/#{@id}", payload).wait
168
+ end
169
+ end
170
+
171
+ alias modify edit
19
172
 
20
- def initialize(block, id, metadata)
21
- @block = block
22
- @id = id
23
- @once = metadata.fetch(:once, false)
24
- @metadata = metadata
25
- @rescue = nil
173
+ #
174
+ # Starts the event. Shortcut for `edit(status: :active)`.
175
+ #
176
+ def start
177
+ edit(status: :active)
178
+ end
179
+
180
+ #
181
+ # Completes the event. Shortcut for `edit(status: :completed)`.
182
+ #
183
+ def complete
184
+ edit(status: :completed)
185
+ end
186
+
187
+ alias finish complete
188
+
189
+ #
190
+ # Cancels the event. Shortcut for `edit(status: :canceled)`.
191
+ #
192
+ def cancel
193
+ edit(status: :canceled)
194
+ end
195
+
196
+ #
197
+ # Deletes the event.
198
+ # @async
199
+ #
200
+ # @return [Async::Task<void>] The task.
201
+ #
202
+ def delete!
203
+ Async do
204
+ @client.http.delete("/guilds/#{@guild_id}/scheduled-events/#{@id}").wait
205
+ end
26
206
  end
27
207
 
208
+ alias destroy! delete!
209
+
210
+ #
211
+ # Fetches the event users.
212
+ # @async
213
+ #
214
+ # @note You can fetch all of members by not specifying a parameter.
215
+ #
216
+ # @param [Integer] limit The maximum number of users to fetch. Defaults to `100`.
217
+ # @param [#to_s] after The ID of the user to start fetching from. Defaults to `nil`.
218
+ # @param [#to_s] before The ID of the user to stop fetching at. Defaults to `nil`.
219
+ # @param [Boolean] with_member Whether to include the member object of the event. Defaults to `false`.
220
+ # This should be used for manual fetching of members.
28
221
  #
29
- # Calls the block associated with the event.
222
+ # @return [Async::Task<Array<Discorb::Member>>] The event users.
30
223
  #
31
- def call(...)
32
- @block.call(...)
224
+ def fetch_users(limit = nil, before: nil, after: nil, with_member: true)
225
+ Async do
226
+ if limit.nil?
227
+ after = 0
228
+ res = []
229
+ while true
230
+ _resp, users = @client.http.get("/guilds/#{@guild_id}/scheduled-events/#{@id}/users?limit=100&after=#{after}&with_member=true").wait
231
+ if users.empty?
232
+ break
233
+ end
234
+ res += users.map { |u| Member.new(@client, @guild_id, u[:user], u[:member]) }
235
+ after = users.last[:user][:id]
236
+ end
237
+ res
238
+ else
239
+ params = {
240
+ limit: limit,
241
+ before: Discorb::Utils.try(after, :id),
242
+ after: Discorb::Utils.try(around, :id),
243
+ with_member: with_member,
244
+ }.filter { |_k, v| !v.nil? }.to_h
245
+ _resp, messages = @client.http.get("/channels/#{channel_id.wait}/messages?#{URI.encode_www_form(params)}").wait
246
+ messages.map { |m| Message.new(@client, m.merge({ guild_id: @guild_id.to_s })) }
247
+ end
248
+ end
249
+ end
250
+
251
+ alias fetch_members fetch_users
252
+
253
+ private
254
+
255
+ def _set_data(data)
256
+ @id = Snowflake.new(data[:id])
257
+ @guild_id = Snowflake.new(data[:guild_id])
258
+ @channel_id = data[:channel_id] && Snowflake.new(data[:channel_id])
259
+ @creator_id = data[:creator_id] && Snowflake.new(data[:creator_id])
260
+ @name = data[:name]
261
+ @description = data[:description]
262
+ @scheduled_start_time = Time.iso8601(data[:scheduled_start_time])
263
+ @scheduled_end_time = data[:scheduled_end_time] && Time.iso8601(data[:scheduled_end_time])
264
+ @privacy_level = :guild_only # data[:privacy_level]
265
+ @status = self.class.status[data[:status]]
266
+ @entity_type = self.class.entity_type[data[:entity_type]]
267
+ @entity_id = data[:entity_id] && Snowflake.new(data[:entity_id])
268
+ @entity_metadata = data[:entity_metadata] && Metadata.new(data[:entity_metadata])
269
+ @creator = @client.users[@creator_id] || (data[:creator] && User.new(@client, data[:creator]))
270
+ @user_count = data[:user_count]
271
+ end
272
+
273
+ class << self
274
+ attr_reader :status, :entity_type, :privacy_level
33
275
  end
34
276
  end
35
277
  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
@@ -2,7 +2,9 @@
2
2
 
3
3
  require "etc"
4
4
  require "discorb"
5
+
5
6
  puts "\e[90mRuby:\e[m #{RUBY_VERSION}"
6
7
  puts "\e[90mdiscorb:\e[m #{Discorb::VERSION}"
7
8
  uname = Etc.uname
8
9
  puts "\e[90mSystem:\e[m #{uname[:sysname]} #{uname[:release]}"
10
+ puts "\e[90mPlatform:\e[m #{RUBY_PLATFORM}"
@@ -4,7 +4,7 @@ module Discorb
4
4
  #
5
5
  # Abstract class to make extension.
6
6
  # Include from this module to make your own extension.
7
- # @see file:docs/extension.md
7
+ # @see file:docs/extension.md Extension
8
8
  # @abstract
9
9
  #
10
10
  module Extension
@@ -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
@@ -92,10 +92,14 @@ module Discorb
92
92
  #
93
93
  # @return [Discorb::Flag] The negation of the flag.
94
94
  #
95
- def ~@
95
+ def ~
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
@@ -94,8 +94,7 @@ module Discorb
94
94
 
95
95
  # Fetch the message.
96
96
  # If message is cached, it will be returned.
97
- # @macro async
98
- # @macro http
97
+ # @async
99
98
  #
100
99
  # @param [Boolean] force Whether to force fetching the message.
101
100
  #
@@ -143,8 +142,7 @@ module Discorb
143
142
 
144
143
  # Fetch the message.
145
144
  # If message is cached, it will be returned.
146
- # @macro async
147
- # @macro http
145
+ # @async
148
146
  #
149
147
  # @param [Boolean] force Whether to force fetching the message.
150
148
  #
@@ -195,8 +193,7 @@ module Discorb
195
193
 
196
194
  # Fetch the message.
197
195
  # If message is cached, it will be returned.
198
- # @macro async
199
- # @macro http
196
+ # @async
200
197
  #
201
198
  # @param [Boolean] force Whether to force fetching the message.
202
199
  #
@@ -210,6 +207,28 @@ module Discorb
210
207
  end
211
208
  end
212
209
 
210
+ #
211
+ # Represents a `GUILD_SCHEDULED_EVENT_USER_ADD` and `GUILD_SCHEDULED_EVENT_USER_REMOVE` event.
212
+ #
213
+ class ScheduledEventUserEvent < GatewayEvent
214
+ # @return [Discorb::User] The user that triggered the event.
215
+ attr_reader :user
216
+ # @return [Discorb::Guild] The guild the event was triggered in.
217
+ attr_reader :guild
218
+ # @return [Discorb::ScheduledEvent] The scheduled event.
219
+ attr_reader :scheduled_event
220
+ # @private
221
+ def initialize(client, data)
222
+ @client = client
223
+ @scheduled_event_id = Snowflake.new(data[:scheduled_event_id])
224
+ @user_id = Snowflake.new(data[:user_id])
225
+ @guild_id = Snowflake.new(data[:guild_id])
226
+ @guild = client.guilds[data[:guild_id]]
227
+ @scheduled_event = @guild.scheduled_events[@scheduled_event_id]
228
+ @user = client.users[data[:user_id]]
229
+ end
230
+ end
231
+
213
232
  #
214
233
  # Represents a `MESSAGE_UPDATE` event.
215
234
  #
@@ -271,8 +290,7 @@ module Discorb
271
290
  end
272
291
 
273
292
  # Fetch the message.
274
- # @macro async
275
- # @macro http
293
+ # @async
276
294
  #
277
295
  # @return [Async::Task<Discorb::Message>] The message.
278
296
  def fetch_message
@@ -481,14 +499,14 @@ module Discorb
481
499
  module Handler
482
500
  private
483
501
 
484
- def connect_gateway(reconnect)
502
+ def connect_gateway(reconnect, no_close: false)
485
503
  if reconnect
486
504
  @log.info "Reconnecting to gateway..."
487
505
  else
488
506
  @log.info "Connecting to gateway..."
489
507
  end
490
508
  Async do
491
- @connection&.close
509
+ @connection&.close unless no_close
492
510
  @http = HTTP.new(self)
493
511
  _, gateway_response = @http.get("/gateway").wait
494
512
  gateway_url = gateway_response[:url]
@@ -515,9 +533,9 @@ module Discorb
515
533
  end
516
534
  end
517
535
  end
518
- rescue Async::Wrapper::Cancelled, OpenSSL::SSL::SSLError, Async::Wrapper::WaitError, EOFError => e
519
- @log.error "Gateway connection closed: #{e.class}: #{e.message}"
520
- connect_gateway(true)
536
+ rescue Async::Wrapper::Cancelled, OpenSSL::SSL::SSLError, Async::Wrapper::WaitError, EOFError, Errno::EPIPE => e
537
+ @log.error "Gateway connection closed accidentally: #{e.class}: #{e.message}"
538
+ connect_gateway(true, no_close: true)
521
539
  else # should never happen
522
540
  connect_gateway(true)
523
541
  end
@@ -1042,11 +1060,44 @@ module Discorb
1042
1060
  @log.info("Successfully resumed connection")
1043
1061
  @tasks << handle_heartbeat
1044
1062
  dispatch(:resumed)
1063
+ when "GUILD_SCHEDULED_EVENT_CREATE"
1064
+ @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1065
+ event = ScheduledEvent.new(self, data)
1066
+ guild.scheduled_events[data[:id]] = event
1067
+ dispatch(:scheduled_event_create, event)
1068
+ when "GUILD_SCHEDULED_EVENT_UPDATE"
1069
+ @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1070
+ @log.warn("Unknown scheduled event id #{data[:id]}, ignoring") unless (event = guild.scheduled_events[data[:id]])
1071
+ old = event.dup
1072
+ event.send(:_set_data, data)
1073
+ dispatch(:scheduled_event_update, old, event)
1074
+ if old.status != event.status
1075
+ case event.status
1076
+ when :active
1077
+ dispatch(:scheduled_event_start, event)
1078
+ when :completed
1079
+ dispatch(:scheduled_event_end, event)
1080
+ end
1081
+ else
1082
+ dispatch(:scheduled_event_edit, old, event)
1083
+ end
1084
+ when "GUILD_SCHEDULED_EVENT_DELETE"
1085
+ @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1086
+ @log.warn("Unknown scheduled event id #{data[:id]}, ignoring") unless (event = guild.scheduled_events[data[:id]])
1087
+ guild.scheduled_events.remove(data[:id])
1088
+ dispatch(:scheduled_event_delete, event)
1089
+ dispatch(:scheduled_event_cancel, event)
1090
+ when "GUILD_SCHEDULED_EVENT_USER_ADD"
1091
+ @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1092
+ dispatch(:scheduled_event_user_add, ScheduledEventUserEvent.new(self, data))
1093
+ when "GUILD_SCHEDULED_EVENT_USER_REMOVE"
1094
+ @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1095
+ dispatch(:scheduled_event_user_remove, ScheduledEventUserEvent.new(self, data))
1045
1096
  else
1046
1097
  if respond_to?("event_" + event_name.downcase)
1047
1098
  __send__("event_" + event_name.downcase, data)
1048
1099
  else
1049
- @log.debug "#{event_name}\n#{data.inspect}"
1100
+ @log.debug "Unhandled event: #{event_name}\n#{data.inspect}"
1050
1101
  end
1051
1102
  end
1052
1103
  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