discorb 0.16.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/build_main.yml +2 -2
  4. data/.github/workflows/build_version.yml +1 -1
  5. data/.github/workflows/codeql-analysis.yml +1 -1
  6. data/.github/workflows/lint-push.yml +3 -5
  7. data/.github/workflows/lint.yml +2 -4
  8. data/.github/workflows/spec.yml +33 -0
  9. data/.github/workflows/validate.yml +21 -0
  10. data/.gitignore +2 -0
  11. data/.lefthook/commit-msg/validator.rb +5 -0
  12. data/.rspec +2 -0
  13. data/.rspec_parallel +2 -0
  14. data/.rubocop.yml +43 -6
  15. data/Changelog.md +30 -1
  16. data/Gemfile +20 -8
  17. data/Rakefile +226 -98
  18. data/Steepfile +28 -0
  19. data/bin/console +3 -3
  20. data/docs/Examples.md +1 -1
  21. data/docs/application_command.md +156 -47
  22. data/docs/cli/irb.md +2 -2
  23. data/docs/cli/new.md +14 -9
  24. data/docs/cli/run.md +7 -11
  25. data/docs/cli.md +17 -10
  26. data/docs/events.md +247 -213
  27. data/docs/extension.md +1 -2
  28. data/docs/faq.md +0 -1
  29. data/docs/tutorial.md +18 -18
  30. data/docs/voice_events.md +106 -106
  31. data/examples/commands/message.rb +68 -0
  32. data/examples/commands/permission.rb +19 -0
  33. data/examples/commands/slash.rb +48 -0
  34. data/examples/commands/user.rb +54 -0
  35. data/examples/components/authorization_button.rb +4 -3
  36. data/examples/components/select_menu.rb +6 -3
  37. data/examples/extension/main.rb +2 -1
  38. data/examples/extension/message_expander.rb +6 -2
  39. data/examples/sig/commands/message.rbs +5 -0
  40. data/examples/simple/eval.rb +3 -2
  41. data/examples/simple/ping_pong.rb +2 -1
  42. data/examples/simple/rolepanel.rb +17 -6
  43. data/examples/simple/shard.rb +3 -2
  44. data/examples/simple/wait_for_message.rb +4 -1
  45. data/exe/discorb +33 -18
  46. data/lefthook.yml +45 -0
  47. data/lib/discorb/allowed_mentions.rb +2 -1
  48. data/lib/discorb/app_command/command.rb +130 -72
  49. data/lib/discorb/app_command/common.rb +25 -0
  50. data/lib/discorb/app_command/handler.rb +130 -33
  51. data/lib/discorb/app_command.rb +2 -1
  52. data/lib/discorb/application.rb +1 -0
  53. data/lib/discorb/asset.rb +1 -2
  54. data/lib/discorb/attachment.rb +1 -1
  55. data/lib/discorb/audit_logs.rb +19 -10
  56. data/lib/discorb/automod.rb +269 -0
  57. data/lib/discorb/channel/base.rb +108 -0
  58. data/lib/discorb/channel/category.rb +32 -0
  59. data/lib/discorb/channel/container.rb +44 -0
  60. data/lib/discorb/channel/dm.rb +28 -0
  61. data/lib/discorb/channel/guild.rb +246 -0
  62. data/lib/discorb/channel/stage.rb +140 -0
  63. data/lib/discorb/channel/text.rb +336 -0
  64. data/lib/discorb/channel/thread.rb +325 -0
  65. data/lib/discorb/channel/voice.rb +79 -0
  66. data/lib/discorb/channel.rb +2 -1165
  67. data/lib/discorb/client.rb +50 -36
  68. data/lib/discorb/color.rb +37 -60
  69. data/lib/discorb/common.rb +2 -1
  70. data/lib/discorb/components/button.rb +2 -1
  71. data/lib/discorb/components/select_menu.rb +4 -2
  72. data/lib/discorb/components/text_input.rb +12 -2
  73. data/lib/discorb/components.rb +1 -1
  74. data/lib/discorb/dictionary.rb +1 -1
  75. data/lib/discorb/embed.rb +26 -10
  76. data/lib/discorb/emoji.rb +31 -4
  77. data/lib/discorb/emoji_table.rb +4969 -3
  78. data/lib/discorb/event.rb +29 -4
  79. data/lib/discorb/exe/about.rb +2 -1
  80. data/lib/discorb/exe/irb.rb +2 -4
  81. data/lib/discorb/exe/new.rb +89 -26
  82. data/lib/discorb/exe/run.rb +8 -22
  83. data/lib/discorb/exe/setup.rb +25 -12
  84. data/lib/discorb/exe/show.rb +4 -3
  85. data/lib/discorb/extend.rb +1 -0
  86. data/lib/discorb/extension.rb +6 -7
  87. data/lib/discorb/flag.rb +13 -2
  88. data/lib/discorb/gateway.rb +79 -589
  89. data/lib/discorb/gateway_events.rb +638 -0
  90. data/lib/discorb/guild.rb +318 -67
  91. data/lib/discorb/guild_template.rb +11 -5
  92. data/lib/discorb/http.rb +53 -24
  93. data/lib/discorb/integration.rb +4 -1
  94. data/lib/discorb/intents.rb +28 -19
  95. data/lib/discorb/interaction/autocomplete.rb +28 -16
  96. data/lib/discorb/interaction/command.rb +42 -14
  97. data/lib/discorb/interaction/components.rb +5 -2
  98. data/lib/discorb/interaction/modal.rb +0 -1
  99. data/lib/discorb/interaction/response.rb +125 -26
  100. data/lib/discorb/interaction/root.rb +13 -13
  101. data/lib/discorb/interaction.rb +1 -0
  102. data/lib/discorb/invite.rb +5 -2
  103. data/lib/discorb/member.rb +28 -8
  104. data/lib/discorb/message.rb +60 -25
  105. data/lib/discorb/message_meta.rb +3 -3
  106. data/lib/discorb/modules.rb +59 -16
  107. data/lib/discorb/presence.rb +2 -0
  108. data/lib/discorb/rate_limit.rb +7 -2
  109. data/lib/discorb/reaction.rb +2 -2
  110. data/lib/discorb/role.rb +20 -5
  111. data/lib/discorb/shard.rb +1 -1
  112. data/lib/discorb/sticker.rb +9 -8
  113. data/lib/discorb/user.rb +4 -3
  114. data/lib/discorb/utils/colored_puts.rb +1 -0
  115. data/lib/discorb/voice_state.rb +6 -2
  116. data/lib/discorb/webhook.rb +64 -31
  117. data/lib/discorb.rb +7 -5
  118. data/po/yard.pot +20 -20
  119. data/rbs_collection.lock.yaml +88 -0
  120. data/rbs_collection.yaml +21 -0
  121. data/sig/async.rbs +11 -0
  122. data/sig/discorb/activity.rbs +23 -0
  123. data/sig/discorb/allowed_mentions.rbs +44 -0
  124. data/sig/discorb/app_command/base.rbs +282 -0
  125. data/sig/discorb/app_command/handler.rbs +171 -0
  126. data/sig/discorb/application.rbs +142 -0
  127. data/sig/discorb/asset.rbs +32 -0
  128. data/sig/discorb/attachment.rbs +91 -0
  129. data/sig/discorb/audit_log.rbs +231 -0
  130. data/sig/discorb/automod.rbs +128 -0
  131. data/sig/discorb/avatar.rbs +26 -0
  132. data/sig/discorb/channel/base.rbs +179 -0
  133. data/sig/discorb/channel/category.rbs +56 -0
  134. data/sig/discorb/channel/container.rbs +29 -0
  135. data/sig/discorb/channel/dm.rbs +14 -0
  136. data/sig/discorb/channel/news.rbs +20 -0
  137. data/sig/discorb/channel/stage.rbs +77 -0
  138. data/sig/discorb/channel/text.rbs +158 -0
  139. data/sig/discorb/channel/thread.rbs +185 -0
  140. data/sig/discorb/channel/voice.rbs +41 -0
  141. data/sig/discorb/client.rbs +2495 -0
  142. data/sig/discorb/color.rbs +142 -0
  143. data/sig/discorb/component/base.rbs +28 -0
  144. data/sig/discorb/component/button.rbs +65 -0
  145. data/sig/discorb/component/select_menu.rbs +107 -0
  146. data/sig/discorb/component/text_input.rbs +69 -0
  147. data/sig/discorb/connectable.rbs +8 -0
  148. data/sig/discorb/custom_emoji.rbs +90 -0
  149. data/sig/discorb/dictionary.rbs +85 -0
  150. data/sig/discorb/discord_model.rbs +15 -0
  151. data/sig/discorb/embed.rbs +279 -0
  152. data/sig/discorb/emoji.rbs +13 -0
  153. data/sig/discorb/error.rbs +73 -0
  154. data/sig/discorb/event_handler.rbs +27 -0
  155. data/sig/discorb/extension.rbs +1734 -0
  156. data/sig/discorb/flag.rbs +72 -0
  157. data/sig/discorb/gateway.rbs +481 -0
  158. data/sig/discorb/guild.rbs +870 -0
  159. data/sig/discorb/guild_template.rbs +174 -0
  160. data/sig/discorb/http.rbs +147 -0
  161. data/sig/discorb/image.rbs +20 -0
  162. data/sig/discorb/integration.rbs +118 -0
  163. data/sig/discorb/intents.rbs +97 -0
  164. data/sig/discorb/interaction/autocomplete.rbs +9 -0
  165. data/sig/discorb/interaction/base.rbs +66 -0
  166. data/sig/discorb/interaction/command.rbs +66 -0
  167. data/sig/discorb/interaction/message_component.rbs +140 -0
  168. data/sig/discorb/interaction/modal.rbs +50 -0
  169. data/sig/discorb/interaction/responder.rbs +157 -0
  170. data/sig/discorb/invite.rbs +86 -0
  171. data/sig/discorb/member.rbs +187 -0
  172. data/sig/discorb/message.rbs +469 -0
  173. data/sig/discorb/messageable.rbs +153 -0
  174. data/sig/discorb/partial_emoji.rbs +35 -0
  175. data/sig/discorb/permissions.rbs +149 -0
  176. data/sig/discorb/presence.rbs +237 -0
  177. data/sig/discorb/reaction.rbs +33 -0
  178. data/sig/discorb/role.rbs +145 -0
  179. data/sig/discorb/scheduled_event.rbs +148 -0
  180. data/sig/discorb/shard.rbs +62 -0
  181. data/sig/discorb/snowflake.rbs +56 -0
  182. data/sig/discorb/stage_instance.rbs +63 -0
  183. data/sig/discorb/sticker.rbs +116 -0
  184. data/sig/discorb/system_channel_flag.rbs +17 -0
  185. data/sig/discorb/unicode_emoji.rbs +49 -0
  186. data/sig/discorb/user.rbs +93 -0
  187. data/sig/discorb/utils.rbs +8 -0
  188. data/sig/discorb/voice_region.rbs +30 -0
  189. data/sig/discorb/voice_state.rbs +71 -0
  190. data/sig/discorb/webhook.rbs +327 -0
  191. data/sig/discorb/welcome_screen.rbs +78 -0
  192. data/sig/discorb.rbs +6 -7230
  193. data/sig/manifest.yaml +3 -0
  194. data/sig/override.rbs +19 -0
  195. data/template-replace/files/css/common.css +4 -0
  196. metadata +102 -6
  197. data/examples/commands/bookmarker.rb +0 -42
  198. data/examples/commands/hello.rb +0 -10
  199. data/examples/commands/inspect.rb +0 -25
@@ -29,6 +29,7 @@ module Discorb
29
29
  alias bot_require_code_grant? bot_require_code_grant
30
30
  # @return [Discorb::Application::Flag] The application's flags.
31
31
  attr_reader :flags
32
+
32
33
  #
33
34
  # Initializes a new instance of the Application class.
34
35
  # @private
data/lib/discorb/asset.rb CHANGED
@@ -51,7 +51,7 @@ module Discorb
51
51
  case @target
52
52
  when User, Member, Webhook
53
53
  "avatars"
54
- when Guild, IncomingWebhook::Guild
54
+ when Guild, Webhook::FollowerWebhook::Guild
55
55
  "icons"
56
56
  when Application, Integration::Application
57
57
  "app-icons"
@@ -65,7 +65,6 @@ module Discorb
65
65
  # Represents a default avatar.
66
66
  #
67
67
  class DefaultAvatar < DiscordModel
68
-
69
68
  # @!attribute [r] animated?
70
69
  # @return [false] For compatibility with {Asset}, always `false`.
71
70
 
@@ -70,7 +70,7 @@ module Discorb
70
70
  def initialize_hash(data)
71
71
  @id = Snowflake.new(data[:id])
72
72
  @filename = data[:filename]
73
- @content_type = data[:content_type]
73
+ @content_type = data[:content_type] || "application/octet-stream"
74
74
  @size = data[:size]
75
75
  @url = data[:url]
76
76
  @proxy_url = data[:proxy_url]
@@ -21,9 +21,11 @@ module Discorb
21
21
  def initialize(client, data, guild)
22
22
  @client = client
23
23
  @guild = guild
24
- @webhooks = data[:webhooks].map { |webhook| Webhook.new([@client, webhook]) }
24
+ @webhooks = data[:webhooks].map { |webhook| Webhook.from_data(@client, webhook) }
25
25
  @users = data[:users].map { |user| client.users[user[:id]] || User.new(@client, user) }
26
- @threads = data[:threads].map { |thread| client.channels[thread[:id]] || Channel.make_channel(@client, thread, no_cache: true) }
26
+ @threads = data[:threads].map do |thread|
27
+ client.channels[thread[:id]] || Channel.make_channel(@client, thread, no_cache: true)
28
+ end
27
29
  @entries = data[:audit_log_entries].map { |entry| AuditLog::Entry.new(@client, entry, guild.id) }
28
30
  end
29
31
 
@@ -103,10 +105,12 @@ module Discorb
103
105
  # * `:thread_create`
104
106
  # * `:thread_update`
105
107
  # * `:thread_delete`
108
+ # * `:application_command_permission_update``
106
109
  attr_reader :type
107
110
  # @return [Discorb::AuditLog::Entry::Changes] The changes in this entry.
108
111
  attr_reader :changes
109
- # @return [Discorb::Channel, Discorb::Role, Discorb::Member, Discorb::Guild, Discorb::Message] The target of the entry.
112
+ # @return [Discorb::Channel, Discorb::Role, Discorb::Member, Discorb::Guild, Discorb::Message, Discorb::Snowflake]
113
+ # The target of the entry.
110
114
  attr_reader :target
111
115
  # @return [Hash{Symbol => Object}] The optional data for this entry.
112
116
  # @note You can use dot notation to access the data.
@@ -167,6 +171,11 @@ module Discorb
167
171
  110 => :thread_create,
168
172
  111 => :thread_update,
169
173
  112 => :thread_delete,
174
+ 121 => :application_command_permission_update,
175
+ 140 => :automod_rule_create,
176
+ 141 => :automod_rule_update,
177
+ 142 => :automod_rule_delete,
178
+ 143 => :automod_block_message,
170
179
  }.freeze
171
180
 
172
181
  #
@@ -192,16 +201,16 @@ module Discorb
192
201
  @id = Snowflake.new(data[:id])
193
202
  @user_id = Snowflake.new(data[:user_id])
194
203
  @target_id = Snowflake.new(data[:target_id])
195
- @type = EVENTS[data[:action_type]]
196
- @target = self.class.converts[@type.to_s.split("_")[0].to_sym]&.call(client, @target_id, @gui)
204
+ @type = EVENTS[data[:action_type]] || :unknown
205
+ @target = CONVERTERS[@type.to_s.split("_")[0].to_sym]&.call(client, @target_id, @gui)
197
206
  @target ||= Snowflake.new(data[:target_id])
198
207
  @changes = data[:changes] && Changes.new(data[:changes])
199
208
  @reason = data[:reason]
200
209
  data[:options]&.each do |option, value|
201
210
  define_singleton_method(option) { value }
202
- if option.end_with?("_id")
211
+ if option.end_with?("_id") && CONVERTERS.key?(option.to_s.split("_")[0].to_sym)
203
212
  define_singleton_method(option.to_s.sub("_id", "")) do
204
- self.class.converts[option.to_s.split("_")[0].to_sym]&.call(client, value, @guild_id)
213
+ CONVERTERS[option.to_s.split("_")[0].to_sym]&.call(client, value, @guild_id)
205
214
  end
206
215
  end
207
216
  end
@@ -304,11 +313,11 @@ module Discorb
304
313
  when "permissions"
305
314
  ->(v) { Discorb::Permission.new(v.to_i) }
306
315
  when "status"
307
- ->(v) { Discorb::ScheduledEvent.status[v] }
316
+ ->(v) { Discorb::ScheduledEvent::STATUS[v] }
308
317
  when "entity_type"
309
- ->(v) { Discorb::ScheduledEvent.entity_type[v] }
318
+ ->(v) { Discorb::ScheduledEvent::ENTITY_TYPE[v] }
310
319
  when "privacy_level"
311
- ->(v) { Discorb::StageInstance.privacy_level[v] || Discorb::ScheduledEvent.privacy_level[v] }
320
+ ->(v) { Discorb::StageInstance::PRIVACY_LEVEL[v] || Discorb::ScheduledEvent::PRIVACY_LEVEL[v] }
312
321
  else
313
322
  ->(v) { v }
314
323
  end
@@ -0,0 +1,269 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a rule of auto moderation.
6
+ #
7
+ class AutoModRule < DiscordModel
8
+ # @return [Hash{Integer => Symbol}] The mapping of trigger types.
9
+ # @private
10
+ TRIGGER_TYPES = {
11
+ 1 => :keyword,
12
+ 2 => :harmful_link,
13
+ 3 => :spam,
14
+ 4 => :keyword_preset,
15
+ }.freeze
16
+ # @return [Hash{Integer => Symbol}] The mapping of preset types.
17
+ # @private
18
+ PRESET_TYPES = {
19
+ 1 => :profanity,
20
+ 2 => :sexual_content,
21
+ 3 => :slurs,
22
+ }.freeze
23
+ # @return [Hash{Integer => Symbol}] The mapping of event types.
24
+ # @private
25
+ EVENT_TYPES = {
26
+ 1 => :message_send,
27
+ }.freeze
28
+
29
+ # @return [Discorb::Snowflake] The ID of the rule.
30
+ attr_reader :id
31
+ # @return [String] The name of the rule.
32
+ attr_reader :name
33
+ # @return [Boolean] Whether the rule is enabled.
34
+ attr_reader :enabled
35
+ alias enabled? enabled
36
+ # @return [Array<Discorb::AutoModRule::Action>] The actions of the rule.
37
+ attr_reader :actions
38
+ # @return [Array<String>] The keywords that the rule is triggered by.
39
+ # @note This is only available if the trigger type is `:keyword`.
40
+ attr_reader :keyword_filter
41
+
42
+ #
43
+ # Initialize a new auto mod.
44
+ # @private
45
+ #
46
+ # @param [Discorb::Client] client The client.
47
+ # @param [Hash] data The auto mod data.
48
+ #
49
+ def initialize(client, data)
50
+ @client = client
51
+ _set_data(data)
52
+ end
53
+
54
+ # @!attribute [r]
55
+ # @return [Symbol] Returns the type of the preset.
56
+ # @note This is only available if the trigger type is `:keyword_preset`.
57
+ def preset_type
58
+ PRESET_TYPES[@presets_raw]
59
+ end
60
+
61
+ # @!attribute [r]
62
+ # @return [Symbol] Returns the type of the trigger.
63
+ def trigger_type
64
+ TRIGGER_TYPES[@trigger_type_raw]
65
+ end
66
+
67
+ # @!attribute [r]
68
+ # @return [Symbol] Returns the type of the event.
69
+ def event_type
70
+ EVENT_TYPES[@event_type_raw]
71
+ end
72
+
73
+ # @!attribute [r]
74
+ # @macro client_cache
75
+ # @return [Discorb::Member] The member who created the rule.
76
+ def creator
77
+ guild.members[@creator_id]
78
+ end
79
+
80
+ # @!attribute [r]
81
+ # @return [Discorb::Guild] The guild that the rule is in.
82
+ def guild
83
+ @client.guilds[@guild_id]
84
+ end
85
+
86
+ # @!attribute [r]
87
+ # @return [Array<Discorb::Role>] The roles that the rule is exempt from.
88
+ def exempt_roles
89
+ @exempt_roles_id.map { |id| guild.roles[id] }
90
+ end
91
+
92
+ # @!attribute [r]
93
+ # @return [Array<Discorb::Channel>] The channels that the rule is exempt from.
94
+ def exempt_channels
95
+ @exempt_channels_id.map { |id| guild.channels[id] }
96
+ end
97
+
98
+ #
99
+ # Edit the rule.
100
+ # @async
101
+ # @edit
102
+ #
103
+ # @param [String] name The name of the rule.
104
+ # @param [Symbol] event_type The event type of the rule. See {Discorb::AutoModRule::EVENT_TYPES}.
105
+ # @param [Array<Discorb::AutoModRule::Action>] actions The actions of the rule.
106
+ # @param [Boolean] enabled Whether the rule is enabled or not.
107
+ # @param [Array<Discorb::Role>] exempt_roles The roles that are exempt from the rule.
108
+ # @param [Array<Discorb::Channel>] exempt_channels The channels that are exempt from the rule.
109
+ # @param [Array<String>] keyword_filter The keywords to filter.
110
+ # @param [Symbol] presets The preset of the rule. See {Discorb::AutoModRule::PRESET_TYPES}.
111
+ # @param [String] reason The reason for creating the rule.
112
+ #
113
+ # @return [Async::Task<void>] The task.
114
+ #
115
+ def edit(
116
+ name: Discorb::Unset,
117
+ event_type: Discorb::Unset,
118
+ actions: Discorb::Unset,
119
+ enabled: Discorb::Unset,
120
+ exempt_roles: Discorb::Unset,
121
+ exempt_channels: Discorb::Unset,
122
+ keyword_filter: Discorb::Unset,
123
+ presets: Discorb::Unset,
124
+ reason: nil
125
+ )
126
+ # @type var payload: Hash[Symbol, untyped]
127
+ payload = {
128
+ metadata: {},
129
+ }
130
+ payload[:name] = name unless name == Discorb::Unset
131
+ payload[:event_type] = EVENT_TYPES.key(event_type) unless event_type == Discorb::Unset
132
+ payload[:actions] = actions unless actions == Discorb::Unset
133
+ payload[:enabled] = enabled unless enabled == Discorb::Unset
134
+ payload[:exempt_roles] = exempt_roles.map(&:id) unless exempt_roles == Discorb::Unset
135
+ payload[:exempt_channels] = exempt_channels.map(&:id) unless exempt_channels == Discorb::Unset
136
+ payload[:metadata][:keyword_filter] = keyword_filter unless keyword_filter == Discorb::Unset
137
+ payload[:metadata][:presets] = PRESET_TYPES.key(presets) unless presets == Discorb::Unset
138
+
139
+ @client.http.request(
140
+ Route.new(
141
+ "/guilds/#{@guild_id}/automod/rules/#{@id}",
142
+ "//guilds/:guild_id/automod/rules/:id",
143
+ :patch
144
+ ),
145
+ payload,
146
+ audit_log_reason: reason,
147
+ )
148
+ end
149
+
150
+ #
151
+ # Delete the rule.
152
+ #
153
+ # @param [String] reason The reason for deleting the rule.
154
+ #
155
+ # @return [Async::Task<void>] The task.
156
+ #
157
+ def delete!(reason: nil)
158
+ Async do
159
+ @client.http.request(
160
+ Route.new(
161
+ "/guilds/#{@guild_id}/automod/rules/#{@id}",
162
+ "//guilds/:guild_id/automod/rules/:id",
163
+ :delete
164
+ ),
165
+ audit_log_reason: reason,
166
+ )
167
+ end
168
+ end
169
+
170
+ # @private
171
+ def _set_data(data)
172
+ @id = Snowflake.new(data[:id])
173
+ @guild_id = data[:guild_id]
174
+ @name = data[:name]
175
+ @creator_id = data[:creator_id]
176
+ @trigger_type_raw = data[:trigger_type]
177
+ @event_type_raw = data[:event_type]
178
+ @actions = data[:actions].map { |action| Action.from_hash(@client, action) }
179
+ case trigger_type
180
+ when :keyword
181
+ @keyword_filter = data[:trigger_metadata][:keyword_filter]
182
+ when :presets
183
+ @presets_raw = data[:trigger_metadata][:presets]
184
+ end
185
+ @enabled = data[:enabled]
186
+ @exempt_roles_id = data[:exempt_roles]
187
+ @exempt_channels_id = data[:exempt_channels]
188
+ end
189
+
190
+ #
191
+ # Represents the action of auto moderation.
192
+ #
193
+ class Action < DiscordModel
194
+ # @return [Hash{Integer => Symbol}] The mapping of action types.
195
+ # @private
196
+ ACTION_TYPES = {
197
+ 1 => :block_message,
198
+ 2 => :send_alert_message,
199
+ 3 => :timeout,
200
+ }.freeze
201
+
202
+ # @return [Symbol] Returns the type of the action.
203
+ attr_reader :type
204
+ # @return [Integer] The duration of the timeout.
205
+ # @note This is only available if the action type is `:timeout`.
206
+ attr_reader :duration_seconds
207
+
208
+ #
209
+ # Initialize a new action.
210
+ #
211
+ # @param [Symbol] type The type of the action.
212
+ # @param [Integer] duration_seconds The duration of the timeout.
213
+ # This is only available if the action type is `:timeout`.
214
+ # @param [Discorb::Channel] channel The channel that the alert message is sent to.
215
+ # This is only available if the action type is `:send_alert_message`.
216
+ #
217
+ def initialize(type, duration_seconds: nil, channel: nil)
218
+ @type = type
219
+ @duration_seconds = duration_seconds
220
+ @channel = channel
221
+ end
222
+
223
+ #
224
+ # Convert the action to hash.
225
+ #
226
+ # @return [Hash] The action hash.
227
+ #
228
+ def to_hash
229
+ {
230
+ type: @type,
231
+ metadata: {
232
+ channel_id: @channel&.id,
233
+ duration_seconds: @duration_seconds,
234
+ },
235
+ }
236
+ end
237
+
238
+ #
239
+ # Initialize a new action from hash.
240
+ # @private
241
+ #
242
+ # @param [Discorb::Client] client The client.
243
+ # @param [Hash] data The action data.
244
+ #
245
+ def initialize_hash(client, data)
246
+ @client = client
247
+ _set_data(data)
248
+ end
249
+
250
+ # @!attribute [r]
251
+ # @return [Discorb::Channel] The channel that the alert message is sent to.
252
+ # @note This is only available if the action type is `:send_alert_message`.
253
+ def channel
254
+ @client.channels[@channel_id]
255
+ end
256
+
257
+ # @private
258
+ def _set_data(data)
259
+ @type = ACTION_TYPES[data[:type]]
260
+ @channel_id = data[:metadata][:channel_id]
261
+ @duration_seconds = data[:metadata][:duration_seconds]
262
+ end
263
+
264
+ def self.from_hash(client, data)
265
+ allocate.tap { |action| action.initialize_hash(client, data) }
266
+ end
267
+ end
268
+ end
269
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a channel of Discord.
6
+ # @abstract
7
+ #
8
+ class Channel < DiscordModel
9
+ # @return [Discorb::Snowflake] The ID of the channel.
10
+ attr_reader :id
11
+ # @return [String] The name of the channel.
12
+ attr_reader :name
13
+
14
+ # @!attribute [r] type
15
+ # @return [Integer] The type of the channel as integer.
16
+
17
+ @channel_type = nil
18
+ @subclasses = []
19
+
20
+ #
21
+ # Initializes a new instance of the Channel class.
22
+ # @private
23
+ #
24
+ def initialize(client, data, no_cache: false)
25
+ @client = client
26
+ @data = {}
27
+ @no_cache = no_cache
28
+ _set_data(data)
29
+ end
30
+
31
+ #
32
+ # Checks if the channel is other channel.
33
+ #
34
+ # @param [Discorb::Channel] other The channel to check.
35
+ #
36
+ # @return [Boolean] True if the channel is other channel.
37
+ #
38
+ def ==(other)
39
+ return false unless other.respond_to?(:id)
40
+
41
+ @id == other.id
42
+ end
43
+
44
+ def inspect
45
+ "#<#{self.class} \"##{@name}\" id=#{@id}>"
46
+ end
47
+
48
+ #
49
+ # Returns the descendants of the Channel class.
50
+ # @private
51
+ #
52
+ def self.descendants
53
+ ObjectSpace.each_object(Class).select { |klass| klass < self }
54
+ end
55
+
56
+ #
57
+ # Creates a new instance of the Channel class or instance of its descendants.
58
+ # @private
59
+ #
60
+ # @param [Discorb::Client] client The client that instantiated the object.
61
+ # @param [Hash] data The data of the object.
62
+ # @param [Boolean] no_cache Whether to disable cache the object.
63
+ #
64
+ def self.make_channel(client, data, no_cache: false)
65
+ descendants.each do |klass|
66
+ if !klass.channel_type.nil? && klass.channel_type == data[:type]
67
+ return klass.new(client, data,
68
+ no_cache: no_cache)
69
+ end
70
+ end
71
+ client.logger.warn("Unknown channel type #{data[:type]}, initialized GuildChannel")
72
+ GuildChannel.new(client, data)
73
+ end
74
+
75
+ class << self
76
+ #
77
+ # @private
78
+ # @return [Integer] The type of the channel.
79
+ #
80
+ attr_reader :channel_type
81
+ end
82
+
83
+ def type
84
+ self.class.channel_type
85
+ end
86
+
87
+ #
88
+ # Returns the channel id to request.
89
+ # @private
90
+ #
91
+ # @return [Async::Task<Discorb::Snowflake>] A task that resolves to the channel id.
92
+ #
93
+ def channel_id
94
+ Async do
95
+ @id
96
+ end
97
+ end
98
+
99
+ private
100
+
101
+ def _set_data(data)
102
+ @id = Snowflake.new(data[:id])
103
+ @name = data[:name]
104
+ @client.channels[@id] = self if !@no_cache && !(data[:no_cache])
105
+ @data.update(data)
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a category in a guild.
6
+ #
7
+ class CategoryChannel < GuildChannel
8
+ @channel_type = 4
9
+
10
+ include Discorb::ChannelContainer
11
+
12
+ def channels
13
+ @client.channels.values.filter { |channel| channel.parent == self }
14
+ end
15
+
16
+ def create_text_channel(*args, **kwargs)
17
+ guild.create_text_channel(*args, parent: self, **kwargs)
18
+ end
19
+
20
+ def create_voice_channel(*args, **kwargs)
21
+ guild.create_voice_channel(*args, parent: self, **kwargs)
22
+ end
23
+
24
+ def create_news_channel(*args, **kwargs)
25
+ guild.create_news_channel(*args, parent: self, **kwargs)
26
+ end
27
+
28
+ def create_stage_channel(*args, **kwargs)
29
+ guild.create_stage_channel(*args, parent: self, **kwargs)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Module for container of channels.
6
+ #
7
+ module ChannelContainer
8
+ #
9
+ # Returns text channels.
10
+ #
11
+ # @return [Array<Discorb::TextChannel>] The text channels.
12
+ #
13
+ def text_channels
14
+ channels.filter { |c| c.instance_of? TextChannel }
15
+ end
16
+
17
+ #
18
+ # Returns voice channels.
19
+ #
20
+ # @return [Array<Discorb::VoiceChannel>] The voice channels.
21
+ #
22
+ def voice_channels
23
+ channels.filter { |c| c.instance_of? VoiceChannel }
24
+ end
25
+
26
+ #
27
+ # Returns news channels.
28
+ #
29
+ # @return [Array<Discorb::NewsChannel>] The news channels.
30
+ #
31
+ def news_channels
32
+ channels.filter { |c| c.instance_of? NewsChannel }
33
+ end
34
+
35
+ #
36
+ # Returns stage channels.
37
+ #
38
+ # @return [Array<Discorb::StageChannel>] The stage channels.
39
+ #
40
+ def stage_channels
41
+ channels.filter { |c| c.instance_of? StageChannel }
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a DM channel.
6
+ #
7
+ class DMChannel < Channel
8
+ include Messageable
9
+
10
+ #
11
+ # Returns the channel id to request.
12
+ # @private
13
+ #
14
+ # @return [Async::Task<Discorb::Snowflake>] A task that resolves to the channel id.
15
+ #
16
+ def channel_id
17
+ Async do
18
+ @id
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def _set_data(data)
25
+ @id = Snowflake.new(data)
26
+ end
27
+ end
28
+ end