onyxcord 2.0.13 → 3.2.0

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 (270) hide show
  1. checksums.yaml +4 -4
  2. data/lib/onyxcord/application_commands/command.rb +4 -97
  3. data/lib/onyxcord/application_commands/context.rb +4 -94
  4. data/lib/onyxcord/application_commands/option.rb +4 -75
  5. data/lib/onyxcord/application_commands/registry.rb +4 -45
  6. data/lib/onyxcord/application_commands.rb +8 -5
  7. data/lib/onyxcord/bot.rb +24 -1759
  8. data/lib/onyxcord/{cache.rb → cache/manager.rb} +16 -14
  9. data/lib/onyxcord/cache/stores/gateway.rb +272 -0
  10. data/lib/onyxcord/commands/bot/channels.rb +48 -0
  11. data/lib/onyxcord/commands/bot/execution.rb +174 -0
  12. data/lib/onyxcord/commands/bot/message_dispatch.rb +58 -0
  13. data/lib/onyxcord/commands/bot/permissions.rb +72 -0
  14. data/lib/onyxcord/commands/bot.rb +209 -0
  15. data/lib/onyxcord/commands/container.rb +21 -2
  16. data/lib/onyxcord/commands/parser.rb +30 -1
  17. data/lib/onyxcord/container.rb +16 -960
  18. data/lib/onyxcord/core/bot/application_commands.rb +210 -0
  19. data/lib/onyxcord/core/bot/awaits.rb +112 -0
  20. data/lib/onyxcord/core/bot/invites.rb +42 -0
  21. data/lib/onyxcord/core/bot/messaging.rb +161 -0
  22. data/lib/onyxcord/core/bot/oauth.rb +27 -0
  23. data/lib/onyxcord/core/bot/presence.rb +103 -0
  24. data/lib/onyxcord/core/bot/runtime.rb +183 -0
  25. data/lib/onyxcord/core/bot/voice.rb +69 -0
  26. data/lib/onyxcord/{errors.rb → core/errors.rb} +18 -3
  27. data/lib/onyxcord/{logger.rb → core/logger.rb} +5 -0
  28. data/lib/onyxcord/core/version.rb +5 -0
  29. data/lib/onyxcord/events/await/base.rb +48 -0
  30. data/lib/onyxcord/events/await.rb +1 -46
  31. data/lib/onyxcord/events/ban/base.rb +54 -0
  32. data/lib/onyxcord/events/ban/remove.rb +11 -0
  33. data/lib/onyxcord/events/bans.rb +2 -58
  34. data/lib/onyxcord/events/channels/base.rb +91 -0
  35. data/lib/onyxcord/events/channels/delete.rb +73 -0
  36. data/lib/onyxcord/events/channels/pins.rb +44 -0
  37. data/lib/onyxcord/events/channels/recipients.rb +77 -0
  38. data/lib/onyxcord/events/channels.rb +4 -239
  39. data/lib/onyxcord/events/guilds/audit_logs.rb +79 -0
  40. data/lib/onyxcord/events/guilds/base.rb +97 -0
  41. data/lib/onyxcord/events/guilds/emoji.rb +147 -0
  42. data/lib/onyxcord/events/guilds.rb +3 -267
  43. data/lib/onyxcord/events/handlers/channels.rb +133 -0
  44. data/lib/onyxcord/events/handlers/core.rb +146 -0
  45. data/lib/onyxcord/events/handlers/guilds.rb +375 -0
  46. data/lib/onyxcord/events/handlers/interactions.rb +238 -0
  47. data/lib/onyxcord/events/handlers/lifetime.rb +71 -0
  48. data/lib/onyxcord/events/handlers/messages.rb +218 -0
  49. data/lib/onyxcord/events/handlers/presence.rb +56 -0
  50. data/lib/onyxcord/events/handlers/raw.rb +39 -0
  51. data/lib/onyxcord/events/handlers/reactions.rb +98 -0
  52. data/lib/onyxcord/events/handlers/scheduled_events.rb +243 -0
  53. data/lib/onyxcord/events/handlers/voice.rb +46 -0
  54. data/lib/onyxcord/events/integration/base.rb +45 -0
  55. data/lib/onyxcord/events/integration/create.rb +11 -0
  56. data/lib/onyxcord/events/integration/delete.rb +48 -0
  57. data/lib/onyxcord/events/integration/update.rb +11 -0
  58. data/lib/onyxcord/events/integrations.rb +4 -98
  59. data/lib/onyxcord/events/interactions/application_commands.rb +185 -0
  60. data/lib/onyxcord/events/interactions/autocomplete.rb +62 -0
  61. data/lib/onyxcord/events/interactions/base.rb +175 -0
  62. data/lib/onyxcord/events/interactions/components.rb +221 -0
  63. data/lib/onyxcord/events/interactions/permissions.rb +53 -0
  64. data/lib/onyxcord/events/interactions.rb +5 -622
  65. data/lib/onyxcord/events/invite/create.rb +79 -0
  66. data/lib/onyxcord/events/invite/delete.rb +55 -0
  67. data/lib/onyxcord/events/invites.rb +2 -125
  68. data/lib/onyxcord/events/lifetime/base.rb +31 -0
  69. data/lib/onyxcord/events/lifetime.rb +1 -29
  70. data/lib/onyxcord/events/member/add.rb +12 -0
  71. data/lib/onyxcord/events/member/base.rb +67 -0
  72. data/lib/onyxcord/events/member/delete.rb +21 -0
  73. data/lib/onyxcord/events/member/update.rb +25 -0
  74. data/lib/onyxcord/events/members.rb +4 -108
  75. data/lib/onyxcord/events/message/base.rb +295 -0
  76. data/lib/onyxcord/events/message/ids.rb +71 -0
  77. data/lib/onyxcord/events/message/mentions.rb +55 -0
  78. data/lib/onyxcord/events/message/updates.rb +27 -0
  79. data/lib/onyxcord/events/message.rb +4 -397
  80. data/lib/onyxcord/events/poll/add.rb +11 -0
  81. data/lib/onyxcord/events/poll/base.rb +106 -0
  82. data/lib/onyxcord/events/poll/remove.rb +11 -0
  83. data/lib/onyxcord/events/polls.rb +3 -116
  84. data/lib/onyxcord/events/presence/playing.rb +77 -0
  85. data/lib/onyxcord/events/presence/status.rb +60 -0
  86. data/lib/onyxcord/events/presence.rb +2 -129
  87. data/lib/onyxcord/events/raw/base.rb +74 -0
  88. data/lib/onyxcord/events/raw.rb +1 -72
  89. data/lib/onyxcord/events/reactions/base.rb +143 -0
  90. data/lib/onyxcord/events/reactions/clear.rb +99 -0
  91. data/lib/onyxcord/events/reactions.rb +2 -216
  92. data/lib/onyxcord/events/role/create.rb +46 -0
  93. data/lib/onyxcord/events/role/delete.rb +40 -0
  94. data/lib/onyxcord/events/role/update.rb +11 -0
  95. data/lib/onyxcord/events/roles.rb +3 -85
  96. data/lib/onyxcord/events/scheduled_events/events.rb +112 -0
  97. data/lib/onyxcord/events/scheduled_events/users.rb +91 -0
  98. data/lib/onyxcord/events/scheduled_events.rb +2 -169
  99. data/lib/onyxcord/events/thread/base.rb +49 -0
  100. data/lib/onyxcord/events/thread/members.rb +44 -0
  101. data/lib/onyxcord/events/thread/update.rb +18 -0
  102. data/lib/onyxcord/events/threads.rb +3 -98
  103. data/lib/onyxcord/events/typing/base.rb +73 -0
  104. data/lib/onyxcord/events/typing.rb +1 -71
  105. data/lib/onyxcord/events/voice/server_update.rb +48 -0
  106. data/lib/onyxcord/events/voice/state_update.rb +137 -0
  107. data/lib/onyxcord/events/voice_server_update.rb +2 -46
  108. data/lib/onyxcord/events/voice_state_update.rb +2 -135
  109. data/lib/onyxcord/events/webhook/update.rb +65 -0
  110. data/lib/onyxcord/events/webhooks.rb +1 -63
  111. data/lib/onyxcord/gateway/client.rb +460 -0
  112. data/lib/onyxcord/interactions/command.rb +120 -0
  113. data/lib/onyxcord/interactions/context.rb +109 -0
  114. data/lib/onyxcord/interactions/internal/application_command.rb +203 -0
  115. data/lib/onyxcord/interactions/internal/message.rb +152 -0
  116. data/lib/onyxcord/interactions/internal/metadata.rb +109 -0
  117. data/lib/onyxcord/interactions/internal/option_builder.rb +230 -0
  118. data/lib/onyxcord/interactions/internal/permission_builder.rb +90 -0
  119. data/lib/onyxcord/interactions/option.rb +88 -0
  120. data/lib/onyxcord/interactions/registry.rb +50 -0
  121. data/lib/onyxcord/interactions.rb +16 -0
  122. data/lib/onyxcord/internal/async_runtime.rb +32 -0
  123. data/lib/onyxcord/internal/event_bus.rb +591 -0
  124. data/lib/onyxcord/internal/event_executor.rb +155 -0
  125. data/lib/onyxcord/internal/gateway/opcodes.rb +22 -0
  126. data/lib/onyxcord/internal/gateway/session.rb +45 -0
  127. data/lib/onyxcord/internal/http.rb +189 -0
  128. data/lib/onyxcord/internal/json.rb +51 -0
  129. data/lib/onyxcord/internal/message_payload.rb +78 -0
  130. data/lib/onyxcord/internal/rate_limiter/async_rest.rb +151 -0
  131. data/lib/onyxcord/internal/rate_limiter/gateway.rb +44 -0
  132. data/lib/onyxcord/internal/rate_limiter/rest.rb +144 -0
  133. data/lib/onyxcord/internal/upload.rb +39 -0
  134. data/lib/onyxcord/internal/websocket.rb +79 -0
  135. data/lib/onyxcord/light/data.rb +1 -1
  136. data/lib/onyxcord/light/integrations.rb +1 -1
  137. data/lib/onyxcord/light/light_bot.rb +7 -7
  138. data/lib/onyxcord/{data → models}/activity.rb +2 -2
  139. data/lib/onyxcord/{data → models}/application.rb +3 -3
  140. data/lib/onyxcord/{data → models}/avatar_decoration.rb +1 -1
  141. data/lib/onyxcord/{data → models}/channel.rb +23 -23
  142. data/lib/onyxcord/{data → models}/collectibles.rb +1 -1
  143. data/lib/onyxcord/{data → models}/emoji.rb +1 -1
  144. data/lib/onyxcord/models/interaction.rb +450 -0
  145. data/lib/onyxcord/{data → models}/invite.rb +1 -1
  146. data/lib/onyxcord/{data → models}/member.rb +11 -11
  147. data/lib/onyxcord/{data → models}/message.rb +22 -14
  148. data/lib/onyxcord/{data → models}/poll.rb +2 -2
  149. data/lib/onyxcord/{data → models}/primary_server.rb +1 -1
  150. data/lib/onyxcord/{data → models}/profile.rb +4 -4
  151. data/lib/onyxcord/{data → models}/role.rb +6 -12
  152. data/lib/onyxcord/{data → models}/scheduled_event.rb +5 -5
  153. data/lib/onyxcord/{data → models}/server.rb +41 -41
  154. data/lib/onyxcord/{data → models}/server_preview.rb +2 -2
  155. data/lib/onyxcord/{data → models}/team.rb +1 -1
  156. data/lib/onyxcord/{data → models}/user.rb +5 -5
  157. data/lib/onyxcord/{data → models}/webhook.rb +13 -11
  158. data/lib/onyxcord/models.rb +57 -0
  159. data/lib/onyxcord/{api.rb → rest/client.rb} +83 -27
  160. data/lib/onyxcord/{api → rest/routes}/application.rb +79 -57
  161. data/lib/onyxcord/rest/routes/channel/base.rb +73 -0
  162. data/lib/onyxcord/rest/routes/channel/groups.rb +78 -0
  163. data/lib/onyxcord/rest/routes/channel/messages.rb +130 -0
  164. data/lib/onyxcord/rest/routes/channel/permissions.rb +73 -0
  165. data/lib/onyxcord/rest/routes/channel/pins.rb +45 -0
  166. data/lib/onyxcord/rest/routes/channel/polls.rb +32 -0
  167. data/lib/onyxcord/rest/routes/channel/reactions.rb +86 -0
  168. data/lib/onyxcord/rest/routes/channel/threads.rb +176 -0
  169. data/lib/onyxcord/rest/routes/channel/webhooks.rb +47 -0
  170. data/lib/onyxcord/rest/routes/channel.rb +12 -0
  171. data/lib/onyxcord/{api/interaction.rb → rest/routes/interaction/base.rb} +10 -33
  172. data/lib/onyxcord/rest/routes/interaction/response.rb +24 -0
  173. data/lib/onyxcord/rest/routes/interaction.rb +4 -0
  174. data/lib/onyxcord/{api → rest/routes}/invite.rb +7 -7
  175. data/lib/onyxcord/rest/routes/server/admin.rb +174 -0
  176. data/lib/onyxcord/rest/routes/server/assets.rb +25 -0
  177. data/lib/onyxcord/rest/routes/server/bans.rb +67 -0
  178. data/lib/onyxcord/rest/routes/server/base.rb +77 -0
  179. data/lib/onyxcord/rest/routes/server/channels.rb +58 -0
  180. data/lib/onyxcord/rest/routes/server/emoji.rb +48 -0
  181. data/lib/onyxcord/rest/routes/server/members.rb +109 -0
  182. data/lib/onyxcord/rest/routes/server/messages.rb +19 -0
  183. data/lib/onyxcord/rest/routes/server/roles.rb +156 -0
  184. data/lib/onyxcord/rest/routes/server/scheduled_events.rb +86 -0
  185. data/lib/onyxcord/rest/routes/server.rb +12 -0
  186. data/lib/onyxcord/{api → rest/routes}/user.rb +23 -23
  187. data/lib/onyxcord/{api → rest/routes}/webhook.rb +30 -32
  188. data/lib/onyxcord/{allowed_mentions.rb → utils/allowed_mentions.rb} +9 -1
  189. data/lib/onyxcord/utils/timestamp.rb +69 -0
  190. data/lib/onyxcord/voice/{voice_bot.rb → client.rb} +4 -4
  191. data/lib/onyxcord/voice/encoder.rb +1 -1
  192. data/lib/onyxcord/voice/network/udp.rb +135 -0
  193. data/lib/onyxcord/voice/network/websocket.rb +225 -0
  194. data/lib/onyxcord/voice/network.rb +5 -357
  195. data/lib/onyxcord/webhooks/builder.rb +1 -1
  196. data/lib/onyxcord/webhooks/client.rb +13 -13
  197. data/lib/onyxcord/webhooks/modal/group_builder.rb +55 -0
  198. data/lib/onyxcord/webhooks/modal/label_builder.rb +183 -0
  199. data/lib/onyxcord/webhooks/modal.rb +2 -239
  200. data/lib/onyxcord/webhooks/version.rb +3 -3
  201. data/lib/onyxcord/webhooks/view/container_builder.rb +80 -0
  202. data/lib/onyxcord/webhooks/view/file_builder.rb +24 -0
  203. data/lib/onyxcord/webhooks/view/media_gallery_builder.rb +50 -0
  204. data/lib/onyxcord/webhooks/view/row_builder.rb +120 -0
  205. data/lib/onyxcord/webhooks/view/section_builder.rb +61 -0
  206. data/lib/onyxcord/webhooks/view/select_menu_builder.rb +77 -0
  207. data/lib/onyxcord/webhooks/view/separator_builder.rb +22 -0
  208. data/lib/onyxcord/webhooks/view/text_display_builder.rb +20 -0
  209. data/lib/onyxcord/webhooks/view.rb +9 -425
  210. data/lib/onyxcord.rb +106 -40
  211. metadata +208 -91
  212. data/.github/CONTRIBUTING.md +0 -13
  213. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
  214. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -24
  215. data/.github/pull_request_template.md +0 -37
  216. data/.github/workflows/ci.yml +0 -78
  217. data/.github/workflows/codeql.yml +0 -65
  218. data/.github/workflows/deploy.yml +0 -54
  219. data/.github/workflows/release.yml +0 -51
  220. data/.gitignore +0 -17
  221. data/.markdownlint.json +0 -4
  222. data/.overcommit.yml +0 -7
  223. data/.rspec +0 -2
  224. data/.rubocop.yml +0 -129
  225. data/.yardopts +0 -1
  226. data/CHANGELOG.md +0 -202
  227. data/Gemfile +0 -6
  228. data/LICENSE.txt +0 -21
  229. data/README.md +0 -448
  230. data/Rakefile +0 -13
  231. data/lib/onyxcord/api/channel.rb +0 -705
  232. data/lib/onyxcord/api/server.rb +0 -775
  233. data/lib/onyxcord/async/runtime.rb +0 -30
  234. data/lib/onyxcord/commands/command_bot.rb +0 -505
  235. data/lib/onyxcord/data/interaction.rb +0 -1143
  236. data/lib/onyxcord/data.rb +0 -57
  237. data/lib/onyxcord/event_executor.rb +0 -153
  238. data/lib/onyxcord/gateway.rb +0 -500
  239. data/lib/onyxcord/http.rb +0 -115
  240. data/lib/onyxcord/json.rb +0 -49
  241. data/lib/onyxcord/rate_limiter/async_rest.rb +0 -149
  242. data/lib/onyxcord/rate_limiter/gateway.rb +0 -42
  243. data/lib/onyxcord/rate_limiter/rest.rb +0 -142
  244. data/lib/onyxcord/version.rb +0 -7
  245. data/lib/onyxcord/websocket.rb +0 -77
  246. data/onyxcord.gemspec +0 -63
  247. /data/lib/onyxcord/{configuration.rb → core/configuration.rb} +0 -0
  248. /data/lib/onyxcord/{data → models}/attachment.rb +0 -0
  249. /data/lib/onyxcord/{data → models}/audit_logs.rb +0 -0
  250. /data/lib/onyxcord/{data → models}/call.rb +0 -0
  251. /data/lib/onyxcord/{data → models}/channel_tag.rb +0 -0
  252. /data/lib/onyxcord/{data → models}/component.rb +0 -0
  253. /data/lib/onyxcord/{data → models}/embed.rb +0 -0
  254. /data/lib/onyxcord/{data → models}/install_params.rb +0 -0
  255. /data/lib/onyxcord/{data → models}/integration.rb +0 -0
  256. /data/lib/onyxcord/{data → models}/message_activity.rb +0 -0
  257. /data/lib/onyxcord/{data → models}/overwrite.rb +0 -0
  258. /data/lib/onyxcord/{data → models}/reaction.rb +0 -0
  259. /data/lib/onyxcord/{data → models}/recipient.rb +0 -0
  260. /data/lib/onyxcord/{data → models}/role_connection_data.rb +0 -0
  261. /data/lib/onyxcord/{data → models}/role_subscription.rb +0 -0
  262. /data/lib/onyxcord/{data → models}/snapshot.rb +0 -0
  263. /data/lib/onyxcord/{data → models}/timestamp.rb +0 -0
  264. /data/lib/onyxcord/{data → models}/voice_region.rb +0 -0
  265. /data/lib/onyxcord/{data → models}/voice_state.rb +0 -0
  266. /data/lib/onyxcord/{colour_rgb.rb → utils/colour_rgb.rb} +0 -0
  267. /data/lib/onyxcord/{id_object.rb → utils/id_object.rb} +0 -0
  268. /data/lib/onyxcord/{message_components.rb → utils/message_components.rb} +0 -0
  269. /data/lib/onyxcord/{paginator.rb → utils/paginator.rb} +0 -0
  270. /data/lib/onyxcord/{permissions.rb → utils/permissions.rb} +0 -0
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'onyxcord/events/generic'
4
+ require 'onyxcord/models'
5
+
6
+ module OnyxCord::Events
7
+ # Event for ApplicationCommand interactions.
8
+ class ApplicationCommandEvent < InteractionCreateEvent
9
+ # @return [Symbol] The name of the command.
10
+ attr_reader :command_name
11
+
12
+ # @return [Integer] The ID of the command.
13
+ attr_reader :command_id
14
+
15
+ # @return [Symbol, nil] The name of the subcommand group relevant to this event.
16
+ attr_reader :subcommand_group
17
+
18
+ # @return [Symbol, nil] The name of the subcommand relevant to this event.
19
+ attr_reader :subcommand
20
+
21
+ # @return [Resolved] The resolved channels, roles, users, members, and attachments for this event.
22
+ attr_reader :resolved
23
+
24
+ # @return [Hash<Symbol, Object>] Arguments provided to the command, mapped as `Name => Value`.
25
+ attr_reader :options
26
+
27
+ # @return [Integer, nil] The target of this command when it is a context command.
28
+ attr_reader :target_id
29
+
30
+ # @!visibility private
31
+ def initialize(data, bot)
32
+ super
33
+
34
+ command_data = data['data']
35
+
36
+ @command_id = command_data['id'].to_i
37
+ @command_name = command_data['name'].to_sym
38
+ @command_server_id = command_data['guild_id']
39
+
40
+ @target_id = command_data['target_id']&.to_i
41
+ @resolved = Resolved.new({}, {}, {}, {}, {}, {})
42
+ process_resolved(command_data['resolved']) if command_data['resolved']
43
+
44
+ options = command_data['options'] || []
45
+
46
+ if options.empty?
47
+ @options = {}
48
+ return
49
+ end
50
+
51
+ case options[0]['type']
52
+ when 2
53
+ options = options[0]
54
+ @subcommand_group = options['name'].to_sym
55
+ @subcommand = options['options'][0]['name'].to_sym
56
+ options = options['options'][0]['options']
57
+ when 1
58
+ options = options[0]
59
+ @subcommand = options['name'].to_sym
60
+ options = options['options']
61
+ end
62
+
63
+ @options = transform_options_hash(options || {})
64
+ end
65
+
66
+ # @return [true, false] Whether or not the application command that was executed
67
+ # has been registered globally. If this is false, then the application command
68
+ # that was executed is only available in the invoking server.
69
+ def global_command?
70
+ @command_server_id.nil?
71
+ end
72
+
73
+ # @return [Message, User, nil] The target of this command, for context commands.
74
+ def target
75
+ return nil unless @target_id
76
+
77
+ @resolved.find { |data| data.key?(@target_id) }[@target_id]
78
+ end
79
+
80
+ private
81
+
82
+ def transform_options_hash(hash)
83
+ hash.to_h { |opt| [opt['name'], opt['options'] || opt['value']] }
84
+ end
85
+ end
86
+
87
+ # Event handler for ApplicationCommandEvents.
88
+
89
+ # Event handler for ApplicationCommandEvents.
90
+ class ApplicationCommandEventHandler < EventHandler
91
+ # @return [Hash]
92
+ attr_reader :subcommands
93
+
94
+ # @!visibility private
95
+ def initialize(attributes, block)
96
+ super
97
+
98
+ @subcommands = {}
99
+ end
100
+
101
+ # @param name [Symbol, String]
102
+ # @yieldparam [SubcommandBuilder]
103
+ # @return [ApplicationCommandEventHandler]
104
+ def group(name)
105
+ raise ArgumentError, 'Unable to mix subcommands and groups' if @subcommands.any? { |n, v| n == name && v.is_a?(Proc) }
106
+
107
+ builder = SubcommandBuilder.new(name)
108
+ yield builder
109
+
110
+ @subcommands.merge!(builder.to_h)
111
+ self
112
+ end
113
+
114
+ # @param name [String, Symbol]
115
+ # @yieldparam [SubcommandBuilder]
116
+ # @return [ApplicationCommandEventHandler]
117
+ def subcommand(name, &block)
118
+ raise ArgumentError, 'Unable to mix subcommands and groups' if @subcommands.any? { |n, v| n == name && v.is_a?(Hash) }
119
+
120
+ @subcommands[name.to_sym] = block
121
+
122
+ self
123
+ end
124
+
125
+ # @!visibility private
126
+ # @param event [Event]
127
+ def call(event)
128
+ return unless matches?(event)
129
+
130
+ if event.subcommand_group
131
+ unless (cmd = @subcommands.dig(event.subcommand_group, event.subcommand))
132
+ OnyxCord::LOGGER.debug("Received an event for an unhandled subcommand `#{event.command_name} #{event.subcommand_group} #{event.subcommand}'")
133
+ return
134
+ end
135
+
136
+ cmd.call(event)
137
+ elsif event.subcommand
138
+ unless (cmd = @subcommands[event.subcommand])
139
+ OnyxCord::LOGGER.debug("Received an event for an unhandled subcommand `#{event.command_name} #{event.subcommand}'")
140
+ return
141
+ end
142
+
143
+ cmd.call(event)
144
+ else
145
+ @block.call(event)
146
+ end
147
+ end
148
+
149
+ # @!visibility private
150
+ def matches?(event)
151
+ return false unless event.is_a? ApplicationCommandEvent
152
+
153
+ [
154
+ matches_all(@attributes[:name], event.command_name) do |a, e|
155
+ a.to_sym == e.to_sym
156
+ end
157
+ ].reduce(true, &:&)
158
+ end
159
+ end
160
+
161
+ # Builder for adding subcommands to an ApplicationCommandHandler
162
+
163
+ # Builder for adding subcommands to an ApplicationCommandHandler
164
+ class SubcommandBuilder
165
+ # @!visibility private
166
+ # @param group [String, Symbol, nil]
167
+ def initialize(group = nil)
168
+ @group = group&.to_sym
169
+ @subcommands = {}
170
+ end
171
+
172
+ # @param name [Symbol, String]
173
+ # @yieldparam [ApplicationCommandEvent]
174
+ def subcommand(name, &block)
175
+ @subcommands[name.to_sym] = block
176
+ end
177
+
178
+ # @!visibility private
179
+ def to_h
180
+ @group ? { @group => @subcommands } : @subcommands
181
+ end
182
+ end
183
+
184
+ # An event for when a user interacts with a component.
185
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'onyxcord/events/generic'
4
+ require 'onyxcord/models'
5
+
6
+ module OnyxCord::Events
7
+ # Event handler for an autocomplete option choices.
8
+ class AutocompleteEventHandler < InteractionCreateEventHandler
9
+ def matches?(event)
10
+ return false unless super
11
+ return false unless event.is_a?(AutocompleteEvent)
12
+
13
+ [
14
+ matches_all(@attributes[:name], event.focused) { |a, e| a == e },
15
+ matches_all(@attributes[:command_id], event.command_id) { |a, e| a&.to_i == e },
16
+ matches_all(@attributes[:subcommand], event.subcommand) { |a, e| a&.to_sym == e },
17
+ matches_all(@attributes[:command_name], event.command_name) { |a, e| a&.to_sym == e },
18
+ matches_all(@attributes[:subcommand_group], event.subcommand_group) { |a, e| a&.to_sym == e },
19
+ matches_all(@attributes[:server], event.server_id) { |a, e| a&.resolve_id == e }
20
+ ].reduce(&:&)
21
+ end
22
+ end
23
+
24
+ # An event for an autocomplete option choice.
25
+
26
+ # An event for an autocomplete option choice.
27
+ class AutocompleteEvent < ApplicationCommandEvent
28
+ # @return [String] Name of the currently focused option.
29
+ attr_reader :focused
30
+
31
+ # @return [Hash] An empty hash that can be used to return choices by adding K/V pairs.
32
+ attr_reader :choices
33
+
34
+ # @!visibility private
35
+ def initialize(data, bot)
36
+ super
37
+
38
+ @choices = {}
39
+
40
+ options = data['data']['options']
41
+
42
+ options = case options[0]['type']
43
+ when 1
44
+ options[0]['options']
45
+ when 2
46
+ options[0]['options'][0]['options']
47
+ else
48
+ options
49
+ end
50
+
51
+ @focused = options.find { |opt| opt.key?('focused') }['name']
52
+ end
53
+
54
+ # Respond to this interaction with autocomplete choices.
55
+ # @param choices [Array<Hash>, Hash, nil] Autocomplete choices to return.
56
+ def respond(choices:)
57
+ @interaction.show_autocomplete_choices(choices || [])
58
+ end
59
+ end
60
+
61
+ # An event for whenever an application command's permissions are updated.
62
+ end
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'onyxcord/events/generic'
4
+ require 'onyxcord/models'
5
+
6
+ module OnyxCord::Events
7
+ # Generic subclass for interaction events
8
+ class InteractionCreateEvent < Event
9
+ # Struct to allow accessing data via [] or methods.
10
+ Resolved = Struct.new('Resolved', :channels, :members, :messages, :roles, :users, :attachments) # rubocop:disable Lint/StructNewOverride
11
+
12
+ # @return [Interaction] The interaction for this event.
13
+ attr_reader :interaction
14
+
15
+ # @!attribute [r] type
16
+ # @return [Integer]
17
+ # @see Interaction#type
18
+ # @!attribute [r] server
19
+ # @return [Server, nil]
20
+ # @see Interaction#server
21
+ # @!attribute [r] server_id
22
+ # @return [Integer]
23
+ # @see Interaction#server_id
24
+ # @!attribute [r] channel
25
+ # @return [Channel]
26
+ # @see Interaction#channel
27
+ # @!attribute [r] channel_id
28
+ # @return [Integer]
29
+ # @see Interaction#channel_id
30
+ # @!attribute [r] user
31
+ # @return [User]
32
+ # @see Interaction#user
33
+ # @!attribute [r] user_locale
34
+ # @return [String]
35
+ # @see Interaction#user_locale
36
+ # @!attribute [r] context
37
+ # @return [Integer]
38
+ # @see Interaction#context
39
+ # @!attribute [r] user_integration?
40
+ # @return [true, false]
41
+ # @see Interaction#user_integration?
42
+ # @!attribute [r] server_integration?
43
+ # @return [true, false]
44
+ # @see Interaction#server_integration?
45
+ delegate :type, :server, :server_id, :channel, :channel_id, :user, :user_locale, :context, :user_integration?, :server_integration?, to: :interaction
46
+
47
+ # @!visibility private
48
+ def initialize(data, bot)
49
+ @bot = bot
50
+ @interaction = OnyxCord::Interaction.new(data, @bot)
51
+ end
52
+
53
+ # @see Interaction#respond
54
+ def respond(...)
55
+ @interaction.respond(...)
56
+ end
57
+
58
+ # @see Interaction#defer
59
+ def defer(...)
60
+ @interaction.defer(...)
61
+ end
62
+
63
+ # @see Interaction#update_message
64
+ def update_message(...)
65
+ @interaction.update_message(...)
66
+ end
67
+
68
+ # @see Interaction#show_modal
69
+ def show_modal(...)
70
+ @interaction.show_modal(...)
71
+ end
72
+
73
+ # @see Interaction#edit_response
74
+ def edit_response(...)
75
+ @interaction.edit_response(...)
76
+ end
77
+
78
+ # @see Interaction#delete_response
79
+ def delete_response
80
+ @interaction.delete_response
81
+ end
82
+
83
+ # @see Interaction#send_message
84
+ def send_message(...)
85
+ @interaction.send_message(...)
86
+ end
87
+
88
+ # @see Interaction#edit_message
89
+ def edit_message(...)
90
+ @interaction.edit_message(...)
91
+ end
92
+
93
+ # @see Interaction#delete_message
94
+ def delete_message(...)
95
+ @interaction.delete_message(...)
96
+ end
97
+
98
+ # @see Interaction#defer_update
99
+ def defer_update
100
+ @interaction.defer_update
101
+ end
102
+
103
+ # @see Interaction#get_component
104
+ def get_component(...)
105
+ @interaction.get_component(...)
106
+ end
107
+
108
+ private
109
+
110
+ # @!visibility private
111
+ def process_resolved(resolved_data)
112
+ resolved_data['users']&.each do |id, data|
113
+ @resolved[:users][id.to_i] = @bot.ensure_user(data)
114
+ end
115
+
116
+ resolved_data['roles']&.each do |id, data|
117
+ @resolved[:roles][id.to_i] = OnyxCord::Role.new(data, @bot)
118
+ end
119
+
120
+ resolved_data['channels']&.each do |id, data|
121
+ data['guild_id'] = @interaction.server_id
122
+ @resolved[:channels][id.to_i] = OnyxCord::Channel.new(data, @bot)
123
+ end
124
+
125
+ resolved_data['members']&.each do |id, data|
126
+ data['user'] = resolved_data['users'][id]
127
+ data['guild_id'] = @interaction.server_id
128
+ @resolved[:members][id.to_i] = OnyxCord::Member.new(data, nil, @bot)
129
+ end
130
+
131
+ resolved_data['messages']&.each do |id, data|
132
+ @resolved[:messages][id.to_i] = OnyxCord::Message.new(data, @bot)
133
+ end
134
+
135
+ resolved_data['attachments']&.each do |id, data|
136
+ @resolved[:attachments][id.to_i] = OnyxCord::Attachment.new(data, nil, @bot)
137
+ end
138
+ end
139
+ end
140
+
141
+ # Event handler for INTERACTION_CREATE events.
142
+
143
+ # Event handler for INTERACTION_CREATE events.
144
+ class InteractionCreateEventHandler < EventHandler
145
+ # @!visibility private
146
+ def matches?(event)
147
+ return false unless event.is_a? InteractionCreateEvent
148
+
149
+ [
150
+ matches_all(@attributes[:type], event.type) do |a, e|
151
+ a == case a
152
+ when String, Symbol
153
+ OnyxCord::Interactions::TYPES[e.to_sym]
154
+ else
155
+ e
156
+ end
157
+ end,
158
+
159
+ matches_all(@attributes[:server], event.interaction) do |a, e|
160
+ a.resolve_id == e.server_id
161
+ end,
162
+
163
+ matches_all(@attributes[:channel], event.interaction) do |a, e|
164
+ a.resolve_id == e.channel_id
165
+ end,
166
+
167
+ matches_all(@attributes[:user], event.user) do |a, e|
168
+ a.resolve_id == e.id
169
+ end
170
+ ].reduce(true, &:&)
171
+ end
172
+ end
173
+
174
+ # Event for ApplicationCommand interactions.
175
+ end
@@ -0,0 +1,221 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'onyxcord/events/generic'
4
+ require 'onyxcord/models'
5
+
6
+ module OnyxCord::Events
7
+ # An event for when a user interacts with a component.
8
+ class ComponentEvent < InteractionCreateEvent
9
+ # @return [String] User provided data for this button.
10
+ attr_reader :custom_id
11
+
12
+ # @return [Interactions::Message, nil] The message the button originates from.
13
+ attr_reader :message
14
+
15
+ # @!visibility private
16
+ def initialize(data, bot)
17
+ super
18
+
19
+ @message = @interaction.message
20
+ @custom_id = data['data']['custom_id']
21
+ end
22
+ end
23
+
24
+ # Generic handler for component events.
25
+
26
+ # Generic handler for component events.
27
+ class ComponentEventHandler < InteractionCreateEventHandler
28
+ def matches?(event)
29
+ return false unless super
30
+ return false unless event.is_a? ComponentEvent
31
+
32
+ [
33
+ matches_all(@attributes[:custom_id], event.custom_id) do |a, e|
34
+ # Match regexp and strings
35
+ case a
36
+ when Regexp
37
+ a.match?(e)
38
+ else
39
+ a == e
40
+ end
41
+ end,
42
+ matches_all(@attributes[:message], event.message) do |a, e|
43
+ case a
44
+ when String, Integer
45
+ a.resolve_id == e.id
46
+ else
47
+ a.id == e.id
48
+ end
49
+ end
50
+ ].reduce(&:&)
51
+ end
52
+ end
53
+
54
+ # An event for when a user interacts with a button component.
55
+
56
+ # An event for when a user interacts with a button component.
57
+ class ButtonEvent < ComponentEvent
58
+ end
59
+
60
+ # Event handler for a Button interaction event.
61
+
62
+ # Event handler for a Button interaction event.
63
+ class ButtonEventHandler < ComponentEventHandler
64
+ end
65
+
66
+ # Event for when a user interacts with a select string component.
67
+
68
+ # Event for when a user interacts with a select string component.
69
+ class StringSelectEvent < ComponentEvent
70
+ # @return [Array<String>] Selected values.
71
+ attr_reader :values
72
+
73
+ # @!visibility private
74
+ def initialize(data, bot)
75
+ super
76
+
77
+ @values = data['data']['values']
78
+ end
79
+ end
80
+
81
+ # Event handler for a select string component.
82
+
83
+ # Event handler for a select string component.
84
+ class StringSelectEventHandler < ComponentEventHandler
85
+ end
86
+
87
+ # An event for when a user submits a modal.
88
+
89
+ # An event for when a user submits a modal.
90
+ class ModalSubmitEvent < ComponentEvent
91
+ # @return [Array<Component>] an array of partial component objects that were in the modal.
92
+ attr_reader :components
93
+
94
+ # @return [Resolved] The resolved channels, roles, users, members, and attachments for the modal.
95
+ attr_reader :resolved
96
+
97
+ # @!visibility private
98
+ def initialize(data, bot)
99
+ super
100
+
101
+ @components = @interaction.components
102
+ @resolved = Resolved.new({}, {}, {}, {}, {}, {})
103
+ process_resolved(data['data']['resolved']) if data['data']['resolved']
104
+ end
105
+
106
+ # Get the value of an input passed to the modal.
107
+ # @param custom_id [String] The custom ID of the component to look for.
108
+ # @return [String, nil] The selected value for the component.
109
+ def value(custom_id)
110
+ get_component(custom_id)&.value
111
+ end
112
+
113
+ # Get the selected values from a select menu or file upload component.
114
+ # @param custom_id [String] The custom ID of the component to look for.
115
+ # @return [Array<String>, nil] The values that were chosen for the component.
116
+ def values(custom_id)
117
+ get_component(custom_id)&.values
118
+ end
119
+
120
+ # Get the attachments that a user uploaded in this modal.
121
+ # @param custom_id [String] The custom ID of the file upload component to get attachments for.
122
+ # @return [Array<Attachment>] the attachments that were uploaded to the file upload component.
123
+ def attachments(custom_id)
124
+ values(custom_id)&.map { |id| @resolved[:attachments][id.to_i] } || []
125
+ end
126
+ end
127
+
128
+ # Event handler for a modal submission.
129
+
130
+ # Event handler for a modal submission.
131
+ class ModalSubmitEventHandler < ComponentEventHandler
132
+ end
133
+
134
+ # Event for when a user interacts with a select user component.
135
+
136
+ # Event for when a user interacts with a select user component.
137
+ class UserSelectEvent < ComponentEvent
138
+ # @return [Array<User>] Selected values.
139
+ attr_reader :values
140
+
141
+ # @!visibility private
142
+ def initialize(data, bot)
143
+ super
144
+
145
+ @values = data['data']['values'].map { |e| bot.user(e) }
146
+ end
147
+ end
148
+
149
+ # Event handler for a select user component.
150
+
151
+ # Event handler for a select user component.
152
+ class UserSelectEventHandler < ComponentEventHandler
153
+ end
154
+
155
+ # Event for when a user interacts with a select role component.
156
+
157
+ # Event for when a user interacts with a select role component.
158
+ class RoleSelectEvent < ComponentEvent
159
+ # @return [Array<Role>] Selected values.
160
+ attr_reader :values
161
+
162
+ # @!visibility private
163
+ def initialize(data, bot)
164
+ super
165
+
166
+ @values = data['data']['values'].map { |e| bot.server(data['guild_id']).role(e) }
167
+ end
168
+ end
169
+
170
+ # Event handler for a select role component.
171
+
172
+ # Event handler for a select role component.
173
+ class RoleSelectEventHandler < ComponentEventHandler
174
+ end
175
+
176
+ # Event for when a user interacts with a select mentionable component.
177
+
178
+ # Event for when a user interacts with a select mentionable component.
179
+ class MentionableSelectEvent < ComponentEvent
180
+ # @return [Hash<Symbol => Array<User>, Symbol => Array<Role>>] Selected values.
181
+ attr_reader :values
182
+
183
+ # @!visibility private
184
+ def initialize(data, bot)
185
+ super
186
+
187
+ users = data['data']['resolved']['users'].map { |_, user| @bot.ensure_user(user) }
188
+ roles = data['data']['resolved']['roles'] ? data['data']['resolved']['roles'].keys.map { |e| bot.server(data['guild_id']).role(e) } : []
189
+ @values = { users: users, roles: roles }
190
+ end
191
+ end
192
+
193
+ # Event handler for a select mentionable component.
194
+
195
+ # Event handler for a select mentionable component.
196
+ class MentionableSelectEventHandler < ComponentEventHandler
197
+ end
198
+
199
+ # Event for when a user interacts with a select channel component.
200
+
201
+ # Event for when a user interacts with a select channel component.
202
+ class ChannelSelectEvent < ComponentEvent
203
+ # @return [Array<Channel>] Selected values.
204
+ attr_reader :values
205
+
206
+ # @!visibility private
207
+ def initialize(data, bot)
208
+ super
209
+
210
+ @values = data['data']['values'].map { |e| bot.channel(e, bot.server(data['guild_id'])) }
211
+ end
212
+ end
213
+
214
+ # Event handler for a select channel component.
215
+
216
+ # Event handler for a select channel component.
217
+ class ChannelSelectEventHandler < ComponentEventHandler
218
+ end
219
+
220
+ # Event handler for an autocomplete option choices.
221
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'onyxcord/events/generic'
4
+ require 'onyxcord/models'
5
+
6
+ module OnyxCord::Events
7
+ # An event for whenever an application command's permissions are updated.
8
+ class ApplicationCommandPermissionsUpdateEvent < Event
9
+ # @return [Integer] the ID of the server where the command permissions were updated.
10
+ attr_reader :server_id
11
+
12
+ # @return [Integer, nil] the ID of the application command that was updated.
13
+ attr_reader :command_id
14
+
15
+ # @return [Array<ApplicationCommand::Permission>] the permissions that were updated.
16
+ attr_reader :permissions
17
+
18
+ # @return [Integer] the ID of the application whose commands were updated.
19
+ attr_reader :application_id
20
+
21
+ # @!visibility private
22
+ def initialize(data, bot)
23
+ @bot = bot
24
+ @server_id = data['guild_id'].to_i
25
+ @application_id = data['application_id'].to_i
26
+ @command_id = data['id'].to_i if data['id'].to_i != @application_id
27
+ @permissions = data['permissions'].map do |permission|
28
+ OnyxCord::ApplicationCommand::Permission.new(permission, data, bot)
29
+ end
30
+ end
31
+
32
+ # @return [Server] the server where the command's permissions were updated.
33
+ def server
34
+ @bot.server(@server_id)
35
+ end
36
+ end
37
+
38
+ # Event handler for the APPLICATION_COMMAND_PERMISSIONS_UPDATE event.
39
+
40
+ # Event handler for the APPLICATION_COMMAND_PERMISSIONS_UPDATE event.
41
+ class ApplicationCommandPermissionsUpdateEventHandler < EventHandler
42
+ # @!visibility private
43
+ def matches?(event)
44
+ return false unless event.is_a?(ApplicationCommandPermissionsUpdateEvent)
45
+
46
+ [
47
+ matches_all(@attributes[:server], event.server_id) { |a, e| a.resolve_id == e },
48
+ matches_all(@attributes[:command_id], event.command_id) { |a, e| a.resolve_id == e },
49
+ matches_all(@attributes[:application_id], event.application_id) { |a, e| a.resolve_id == e }
50
+ ].reduce(&:&)
51
+ end
52
+ end
53
+ end