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
@@ -1,1143 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'onyxcord/webhooks'
4
- require 'onyxcord/message_components'
5
-
6
- module OnyxCord
7
- # Base class for interaction objects.
8
- class Interaction
9
- include IDObject
10
-
11
- # Interaction types.
12
- # @see https://discord.com/developers/docs/interactions/slash-commands#interaction-interactiontype
13
- TYPES = {
14
- ping: 1,
15
- command: 2,
16
- component: 3,
17
- autocomplete: 4,
18
- modal_submit: 5
19
- }.freeze
20
-
21
- # Interaction response types.
22
- # @see https://discord.com/developers/docs/interactions/slash-commands#interaction-response-interactioncallbacktype
23
- CALLBACK_TYPES = {
24
- pong: 1,
25
- channel_message: 4,
26
- deferred_message: 5,
27
- deferred_update: 6,
28
- update_message: 7,
29
- autocomplete: 8,
30
- modal: 9
31
- }.freeze
32
-
33
- # Interaction context types.
34
- # @see https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-context-types
35
- CONTEXTS = {
36
- server: 0,
37
- bot_dm: 1,
38
- private_channel: 2
39
- }.freeze
40
-
41
- # Application integration types.
42
- # @see https://discord.com/developers/docs/resources/application#application-object-application-integration-types
43
- INTEGRATION_TYPES = {
44
- server: 0,
45
- user: 1
46
- }.freeze
47
-
48
- # @return [User, Member] The user that initiated the interaction.
49
- attr_reader :user
50
-
51
- # @return [Integer, nil] The ID of the server this interaction originates from.
52
- attr_reader :server_id
53
-
54
- # @return [Integer] The ID of the channel this interaction originates from.
55
- attr_reader :channel_id
56
-
57
- # @return [Channel] The channel where this interaction originates from.
58
- attr_reader :channel
59
-
60
- # @return [Integer] The ID of the application associated with this interaction.
61
- attr_reader :application_id
62
-
63
- # @return [String] The interaction token.
64
- attr_reader :token
65
-
66
- # @!visibility private
67
- # @return [Integer] Currently pointless
68
- attr_reader :version
69
-
70
- # @return [Integer] The type of this interaction.
71
- # @see TYPES
72
- attr_reader :type
73
-
74
- # @return [Hash] The interaction data.
75
- attr_reader :data
76
-
77
- # @return [Interactions::Message, nil] The message associated with this interaction.
78
- attr_reader :message
79
-
80
- # @return [Array<ActionRow>] The modal components associated with this interaction.
81
- attr_reader :components
82
-
83
- # @return [Permissions] The permissions the application has where this interaction originates from.
84
- attr_reader :application_permissions
85
-
86
- # @return [String] The selected language of the user that initiated this interaction.
87
- attr_reader :user_locale
88
-
89
- # @return [String, nil] The selected language of the server this interaction originates from.
90
- attr_reader :server_locale
91
-
92
- # @return [Integer] The context of where this interaction was initiated from.
93
- attr_reader :context
94
-
95
- # @return [Integer] The maximum number of bytes an attachment can have when responding to this interaction.
96
- attr_reader :max_attachment_size
97
-
98
- # @return [Array<Symbol>] The features of the server where this interaction was initiated from.
99
- attr_reader :server_features
100
-
101
- # @!visibility private
102
- def initialize(data, bot)
103
- @bot = bot
104
-
105
- @id = data['id'].to_i
106
- @application_id = data['application_id'].to_i
107
- @type = data['type']
108
- @message = Interactions::Message.new(data['message'], @bot, self) if data['message']
109
- @data = data['data']
110
- @server_id = data['guild_id']&.to_i
111
- @channel_id = data['channel_id']&.to_i
112
- @channel = bot.ensure_channel(data['channel']) if data['channel']
113
- @user = begin
114
- if data['member'] && data['member']['user']
115
- data['member']['guild_id'] = @server_id
116
- server = bot.servers ? bot.servers[@server_id] : nil
117
- OnyxCord::Member.new(data['member'], server, bot)
118
- elsif data['user']
119
- bot.ensure_user(data['user'])
120
- end
121
- rescue StandardError => e
122
- OnyxCord::LOGGER.error("Failed to parse interaction user/member: #{e}")
123
- nil
124
- end
125
- @token = data['token']
126
- @version = data['version']
127
- @components = @data['components']&.filter_map { |component| Components.from_data(component, @bot) } || []
128
- @application_permissions = Permissions.new(data['app_permissions']) if data['app_permissions']
129
- @user_locale = data['locale']
130
- @server_locale = data['guild_locale']
131
- @context = data['context']
132
- @max_attachment_size = data['attachment_size_limit']
133
- @integration_owners = data['authorizing_integration_owners']&.to_h { |key, value| [key.to_i, value.to_i] }
134
- @server_features = data['guild'] ? data['guild']['features']&.map { |feature| feature.downcase.to_sym } : []
135
- end
136
-
137
- # Respond to the creation of this interaction. An interaction must be responded to or deferred,
138
- # The response may be modified with {Interaction#edit_response} or deleted with {Interaction#delete_response}.
139
- # Further messages can be sent with {Interaction#send_message}.
140
- # @param content [String] The content of the message.
141
- # @param tts [true, false]
142
- # @param embeds [Array<Hash, Webhooks::Embed>] The embeds for the message.
143
- # @param allowed_mentions [Hash, AllowedMentions] Mentions that can ping on this message.
144
- # @param flags [Integer] Message flags.
145
- # @param ephemeral [true, false] Whether this message should only be visible to the interaction initiator.
146
- # @param wait [true, false] Whether this method should return a Message object of the interaction response.
147
- # @param components [Array<#to_h>] An array of components.
148
- # @param attachments [Array<File>] Files that can be referenced in embeds and components via `attachment://file.png`.
149
- # @param has_components [true, false] Whether this message includes any V2 components. Enabling this disables sending content, polls, and embeds.
150
- # @param poll [Hash, Poll::Builder, Poll, nil] The poll that should be attached to this message.
151
- # @yieldparam builder [Webhooks::Builder] An optional message builder. Arguments passed to the method overwrite builder data.
152
- # @yieldparam view [Webhooks::View] A builder for creating interaction components.
153
- def respond(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: nil, wait: false, components: nil, attachments: nil, has_components: false, components_v2: false, poll: nil)
154
- flags |= 1 << 6 if ephemeral
155
-
156
- builder = OnyxCord::Webhooks::Builder.new
157
- view = OnyxCord::Webhooks::View.new
158
-
159
- # Set builder defaults from parameters
160
- prepare_builder(builder, content, embeds, allowed_mentions, poll)
161
- yield(builder, view) if block_given?
162
-
163
- components ||= view
164
- flags = OnyxCord::MessageComponents.apply_v2_flag(flags, components, force: has_components || components_v2)
165
- data = builder.to_json_hash
166
-
167
- response = OnyxCord::API::Interaction.create_interaction_response(@token, @id, CALLBACK_TYPES[:channel_message], data[:content], tts, data[:embeds], data[:allowed_mentions], flags, components.to_a, attachments, nil, wait, data[:poll])
168
- return unless wait
169
-
170
- Interactions::Message.new(JSON.parse(response)['resource']['message'], @bot, self)
171
- end
172
-
173
- # Defer an interaction, setting a temporary response that can be later overriden by {Interaction#send_message}.
174
- # This method is used when you want to use a single message for your response but require additional processing time, or to simply ack
175
- # an interaction so an error is not displayed.
176
- # @param flags [Integer] Message flags.
177
- # @param ephemeral [true, false] Whether this message should only be visible to the interaction initiator.
178
- def defer(flags: 0, ephemeral: true)
179
- flags |= 1 << 6 if ephemeral
180
-
181
- OnyxCord::API::Interaction.create_interaction_response(@token, @id, CALLBACK_TYPES[:deferred_message], nil, nil, nil, nil, flags)
182
- nil
183
- end
184
-
185
- # Defer an update to an interaction. This is can only currently used by Button interactions.
186
- def defer_update
187
- OnyxCord::API::Interaction.create_interaction_response(@token, @id, CALLBACK_TYPES[:deferred_update])
188
- end
189
-
190
- # Create a modal as a response.
191
- # @param title [String] The title of the modal being shown.
192
- # @param custom_id [String] The custom_id used to identify the modal and store data.
193
- # @param components [Array<Component, Hash>, nil] An array of components. These can be defined through the block as well.
194
- # @yieldparam [OnyxCord::Webhooks::Modal] A builder for the modal's components.
195
- def show_modal(title:, custom_id:, components: nil)
196
- if block_given?
197
- modal_builder = OnyxCord::Webhooks::Modal.new
198
- yield modal_builder
199
-
200
- components = modal_builder.to_a
201
- end
202
-
203
- OnyxCord::API::Interaction.create_interaction_modal_response(@token, @id, custom_id, title, components.to_a) unless type == Interaction::TYPES[:modal_submit]
204
- nil
205
- end
206
-
207
- # Respond to the creation of this interaction. An interaction must be responded to or deferred,
208
- # The response may be modified with {Interaction#edit_response} or deleted with {Interaction#delete_response}.
209
- # Further messages can be sent with {Interaction#send_message}.
210
- # @param content [String] The content of the message.
211
- # @param tts [true, false]
212
- # @param embeds [Array<Hash, Webhooks::Embed>] The embeds for the message.
213
- # @param allowed_mentions [Hash, AllowedMentions] Mentions that can ping on this message.
214
- # @param flags [Integer] Message flags.
215
- # @param ephemeral [true, false] Whether this message should only be visible to the interaction initiator.
216
- # @param wait [true, false] Whether this method should return a Message object of the interaction response.
217
- # @param components [Array<#to_h>] An array of components.
218
- # @param attachments [Array<File>] Files that can be referenced in embeds and components via `attachment://file.png`.
219
- # @param has_components [true, false] Whether this message includes any V2 components. Enabling this disables sending content, polls, and embeds.
220
- # @param poll [Hash, Poll::Builder, Poll, nil] The poll that should be attached to this message.
221
- # @yieldparam builder [Webhooks::Builder] An optional message builder. Arguments passed to the method overwrite builder data.
222
- # @yieldparam view [Webhooks::View] A builder for creating interaction components.
223
- def update_message(content: nil, tts: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: nil, wait: false, components: nil, attachments: nil, has_components: false, components_v2: false, poll: nil)
224
- flags |= 1 << 6 if ephemeral
225
-
226
- builder = OnyxCord::Webhooks::Builder.new
227
- view = OnyxCord::Webhooks::View.new
228
-
229
- prepare_builder(builder, content, embeds, allowed_mentions, poll)
230
- yield(builder, view) if block_given?
231
-
232
- components ||= view
233
- flags = OnyxCord::MessageComponents.apply_v2_flag(flags, components, force: has_components || components_v2)
234
- data = builder.to_json_hash
235
-
236
- response = OnyxCord::API::Interaction.create_interaction_response(@token, @id, CALLBACK_TYPES[:update_message], data[:content], tts, data[:embeds], data[:allowed_mentions], flags, components.to_a, attachments, nil, wait, data[:poll])
237
- return unless wait
238
-
239
- Interactions::Message.new(JSON.parse(response)['resource']['message'], @bot, self)
240
- end
241
-
242
- # Edit the original response to this interaction.
243
- # @param content [String] The content of the message.
244
- # @param embeds [Array<Hash, Webhooks::Embed>] The embeds for the message.
245
- # @param allowed_mentions [Hash, AllowedMentions] Mentions that can ping on this message.
246
- # @param flags [Integer] Message flags.
247
- # @param components [Array<#to_h>] An array of components.
248
- # @param attachments [Array<File>] Files that can be referenced in embeds and components via `attachment://file.png`.
249
- # @param has_components [true, false] Whether this message includes any V2 components. Enabling this disables sending content, polls, and embeds.
250
- # @param poll [Hash, Poll::Builder, Poll, nil] The poll that should be attached to this message.
251
- # @return [InteractionMessage] The updated response message.
252
- # @yieldparam builder [Webhooks::Builder] An optional message builder. Arguments passed to the method overwrite builder data.
253
- def edit_response(content: nil, embeds: nil, allowed_mentions: nil, flags: 0, components: nil, attachments: nil, has_components: false, components_v2: false, poll: nil)
254
- builder = OnyxCord::Webhooks::Builder.new
255
- view = OnyxCord::Webhooks::View.new
256
-
257
- prepare_builder(builder, content, embeds, allowed_mentions, poll)
258
- yield(builder, view) if block_given?
259
-
260
- components ||= view
261
- flags = OnyxCord::MessageComponents.apply_v2_flag(flags, components, force: has_components || components_v2)
262
- data = builder.to_json_hash
263
- resp = OnyxCord::API::Interaction.edit_original_interaction_response(@token, @application_id, data[:content], data[:embeds], data[:allowed_mentions], components.to_a, attachments, flags, data[:poll])
264
-
265
- Interactions::Message.new(JSON.parse(resp), @bot, self)
266
- end
267
-
268
- # Delete the original interaction response.
269
- def delete_response
270
- OnyxCord::API::Interaction.delete_original_interaction_response(@token, @application_id)
271
- end
272
-
273
- # @param content [String] The content of the message.
274
- # @param tts [true, false]
275
- # @param embeds [Array<Hash, Webhooks::Embed>] The embeds for the message.
276
- # @param allowed_mentions [Hash, AllowedMentions] Mentions that can ping on this message.
277
- # @param flags [Integer] Message flags.
278
- # @param ephemeral [true, false] Whether this message should only be visible to the interaction initiator.
279
- # @param attachments [Array<File>] Files that can be referenced in embeds and components via `attachment://file.png`.
280
- # @param has_components [true, false] Whether this message includes any V2 components. Enabling this disables sending content, polls, and embeds.
281
- # @param poll [Hash, Poll::Builder, Poll, nil] The poll that should be attached to this message.
282
- # @yieldparam builder [Webhooks::Builder] An optional message builder. Arguments passed to the method overwrite builder data.
283
- def send_message(content: nil, embeds: nil, tts: false, allowed_mentions: nil, flags: 0, ephemeral: false, components: nil, attachments: nil, has_components: false, components_v2: false, poll: nil)
284
- flags |= 64 if ephemeral
285
-
286
- builder = OnyxCord::Webhooks::Builder.new
287
- view = OnyxCord::Webhooks::View.new
288
-
289
- prepare_builder(builder, content, embeds, allowed_mentions, poll)
290
- yield(builder, view) if block_given?
291
-
292
- components ||= view
293
- flags = OnyxCord::MessageComponents.apply_v2_flag(flags, components, force: has_components || components_v2)
294
- data = builder.to_json_hash
295
-
296
- resp = OnyxCord::API::Webhook.token_execute_webhook(
297
- @token, @application_id, true, data[:content], nil, nil, tts, nil, data[:embeds], data[:allowed_mentions], flags, components.to_a, attachments, data[:poll]
298
- )
299
- Interactions::Message.new(JSON.parse(resp), @bot, self)
300
- end
301
-
302
- alias edit_original edit_response
303
- alias delete_original delete_response
304
- alias followup send_message
305
-
306
- # @param message [String, Integer, InteractionMessage, Message] The message created by this interaction to be edited.
307
- # @param content [String] The message content.
308
- # @param embeds [Array<Hash, Webhooks::Embed>] The embeds for the message.
309
- # @param allowed_mentions [Hash, AllowedMentions] Mentions that can ping on this message.
310
- # @param attachments [Array<File>] Files that can be referenced in embeds via `attachment://file.png`.
311
- # @param flags [Integer] Message flags.
312
- # @param has_components [true, false] Whether this message includes any V2 components. Enabling this disables sending content, polls, and embeds.
313
- # @param poll [Hash, Poll::Builder, Poll, nil] The poll that should be attached to this message.
314
- # @yieldparam builder [Webhooks::Builder] An optional message builder. Arguments passed to the method overwrite builder data.
315
- def edit_message(message, content: nil, embeds: nil, allowed_mentions: nil, components: nil, attachments: nil, flags: 0, has_components: false, components_v2: false, poll: nil)
316
- builder = OnyxCord::Webhooks::Builder.new
317
- view = OnyxCord::Webhooks::View.new
318
-
319
- prepare_builder(builder, content, embeds, allowed_mentions, poll)
320
- yield(builder, view) if block_given?
321
-
322
- components ||= view
323
- flags = OnyxCord::MessageComponents.apply_v2_flag(flags, components, force: has_components || components_v2)
324
- data = builder.to_json_hash
325
-
326
- resp = OnyxCord::API::Webhook.token_edit_message(
327
- @token, @application_id, message.resolve_id, data[:content], data[:embeds], data[:allowed_mentions], components.to_a, attachments, flags, data[:poll]
328
- )
329
- Interactions::Message.new(JSON.parse(resp), @bot, self)
330
- end
331
-
332
- # @param message [Integer, String, InteractionMessage, Message] The message created by this interaction to be deleted.
333
- def delete_message(message)
334
- OnyxCord::API::Webhook.token_delete_message(@token, @application_id, message.resolve_id)
335
- nil
336
- end
337
-
338
- # Show autocomplete choices as a response.
339
- # @param choices [Array<Hash>, Hash] Array of autocomplete choices to show the user.
340
- def show_autocomplete_choices(choices)
341
- choices = choices.map { |name, value| { name: name, value: value } } unless choices.is_a?(Array)
342
- OnyxCord::API::Interaction.create_interaction_response(@token, @id, CALLBACK_TYPES[:autocomplete], nil, nil, nil, nil, nil, nil, nil, choices)
343
- nil
344
- end
345
-
346
- # Get the server associated with the interaction.
347
- # @return [Server, nil] This will be nil for interactions that occur in DM channels or servers where the bot
348
- # does not have the `bot` scope.
349
- def server
350
- @bot.server(@server_id)
351
- end
352
-
353
- # Get the button component that triggered the interaction.
354
- # @return [Components::Button, nil] The button that triggered this interaction if applicable, otherwise `nil`.
355
- def button
356
- @type == TYPES[:component] ? get_component(@data['custom_id']) : nil
357
- end
358
-
359
- # Get the text input components associated with the interaction.
360
- # @return [Array<TextInput>] The text input components associated with this interaction.
361
- def text_inputs
362
- @components.filter_map do |entity|
363
- entity.component if entity.is_a?(Components::Label) && entity.component.is_a?(Components::TextInput)
364
- end
365
- end
366
-
367
- # Get a component by its custom ID.
368
- # @param custom_id [String] the custom ID of the component to find.
369
- # @return [TextInput, Button, SelectMenu, Checkbox, ModalActionGroup, nil] The component associated with the custom ID, or `nil`.
370
- def get_component(custom_id)
371
- components = flatten_components((@message&.components || []) + @components)
372
- components.find { |component| component.respond_to?(:custom_id) && component.custom_id == custom_id }
373
- end
374
-
375
- # @return [true, false] whether the application was installed by the user who initiated this interaction.
376
- def user_integration?
377
- @integration_owners[1] == @user.id
378
- end
379
-
380
- # @return [true, false] whether the application was installed by the server where this interaction originates from.
381
- def server_integration?
382
- @server_id ? @integration_owners[0] == @server_id : false
383
- end
384
-
385
- private
386
-
387
- # Set builder defaults from parameters
388
- # @param builder [OnyxCord::Webhooks::Builder]
389
- # @param content [String, nil]
390
- # @param embeds [Array<Hash, OnyxCord::Webhooks::Embed>, nil]
391
- # @param allowed_mentions [AllowedMentions, Hash, nil]
392
- # @param poll [Poll, Poll::Builder, Hash, nil]
393
- def prepare_builder(builder, content, embeds, allowed_mentions, poll)
394
- builder.poll = poll
395
- builder.content = content
396
- builder.allowed_mentions = allowed_mentions
397
- embeds&.each { |embed| builder << embed }
398
- end
399
-
400
- # @!visibility private
401
- def flatten_components(components)
402
- components = components.flat_map do |entity|
403
- case entity
404
- when Components::ActionRow
405
- entity.components
406
- when Components::Label
407
- entity.component
408
- when Components::Section
409
- entity.accessory if entity.accessory.respond_to?(:custom_id)
410
- when Components::Container
411
- flatten_components(entity.components)
412
- else
413
- entity if entity.respond_to?(:custom_id)
414
- end
415
- end
416
-
417
- components.compact
418
- end
419
- end
420
-
421
- # An ApplicationCommand for slash commands.
422
- class ApplicationCommand
423
- # Command types. `chat_input` is a command that appears in the text input field. `user` and `message` types appear as context menus
424
- # for the respective resource.
425
- TYPES = {
426
- chat_input: 1,
427
- user: 2,
428
- message: 3
429
- }.freeze
430
-
431
- # @return [Integer]
432
- attr_reader :application_id
433
-
434
- # @return [Integer, nil]
435
- attr_reader :server_id
436
-
437
- # @return [String]
438
- attr_reader :name
439
-
440
- # @return [String]
441
- attr_reader :description
442
-
443
- # @return [true, false]
444
- attr_reader :default_permission
445
-
446
- # @return [Hash]
447
- attr_reader :options
448
-
449
- # @return [Integer]
450
- attr_reader :id
451
-
452
- # @return [true, false]
453
- attr_reader :nsfw
454
-
455
- # @return [Array<Integer>]
456
- attr_reader :contexts
457
-
458
- # @return [Array<Integer>]
459
- attr_reader :integration_types
460
-
461
- # @!visibility private
462
- def initialize(data, bot, server_id = nil)
463
- @bot = bot
464
- @id = data['id'].to_i
465
- @application_id = data['application_id'].to_i
466
- @server_id = server_id&.to_i
467
-
468
- @name = data['name']
469
- @description = data['description']
470
- @default_permission = data['default_permission']
471
- @options = data['options']
472
- @nsfw = data['nsfw'] || false
473
- @contexts = data['contexts'] || []
474
- @integration_types = data['integration_types'] || []
475
- end
476
-
477
- # @param subcommand [String, nil] The subcommand to mention.
478
- # @param subcommand_group [String, nil] The subcommand group to mention.
479
- # @return [String] the layout to mention it in a message
480
- def mention(subcommand_group: nil, subcommand: nil)
481
- if subcommand_group && subcommand
482
- "</#{name} #{subcommand_group} #{subcommand}:#{id}>"
483
- elsif subcommand_group
484
- "</#{name} #{subcommand_group}:#{id}>"
485
- elsif subcommand
486
- "</#{name} #{subcommand}:#{id}>"
487
- else
488
- "</#{name}:#{id}>"
489
- end
490
- end
491
-
492
- alias_method :to_s, :mention
493
-
494
- # @param name [String] The name to use for this command.
495
- # @param description [String] The description of this command.
496
- # @param default_permission [true, false] Whether this command is available with default permissions.
497
- # @param nsfw [true, false] Whether this command should be marked as age-restricted.
498
- # @yieldparam (see Bot#edit_application_command)
499
- # @return (see Bot#edit_application_command)
500
- def edit(name: nil, description: nil, default_permission: nil, nsfw: nil, &block)
501
- @bot.edit_application_command(@id, server_id: @server_id, name: name, description: description, default_permission: default_permission, nsfw: nsfw, &block)
502
- end
503
-
504
- # Delete this application command.
505
- # @return (see Bot#delete_application_command)
506
- def delete
507
- @bot.delete_application_command(@id, server_id: @server_id)
508
- end
509
-
510
- # Get the permission configuration for this application command in a specific server.
511
- # @param server_id [Integer, String, nil] The ID of the server to fetch command permissions for.
512
- # @return [Array<Permission>] the permissions for this application command in the given server.
513
- def permissions(server_id: nil)
514
- raise ArgumentError, 'A server ID must be provided for global application commands' if @server_id.nil? && server_id.nil?
515
-
516
- response = JSON.parse(API::Application.get_application_command_permissions(@bot.token, @bot.profile.id, @server_id || server_id&.resolve_id, @id))
517
- response['permissions'].map { |permission| Permission.new(permission, response, @bot) }
518
- rescue OnyxCord::Errors::UnknownError
519
- # If there aren't any explicit overwrites configured for the command, the response is a 400.
520
- []
521
- end
522
-
523
- # An application command permission for a channel, member, or a role.
524
- class Permission
525
- # Map of permission types.
526
- TYPES = {
527
- role: 1,
528
- member: 2,
529
- channel: 3
530
- }.freeze
531
-
532
- # @return [Integer] the type of this permission.
533
- # @see TYPES
534
- attr_reader :type
535
-
536
- # @return [Integer] the ID of the entity this permission is for.
537
- attr_reader :target_id
538
-
539
- # @return [Integer] the ID of the server this permission is for.
540
- attr_reader :server_id
541
-
542
- # @!visibility private
543
- def initialize(data, command, bot)
544
- @bot = bot
545
- @type = data['type']
546
- @target_id = data['id'].to_i
547
- @overwrite = data['permission']
548
- @command_id = command['id'].to_i
549
- @server_id = command['guild_id'].to_i
550
- @application_id = command['application_id'].to_i
551
- end
552
-
553
- # Whether this permission has been allowed, e.g has a green check in the UI.
554
- # @return [true, false]
555
- def allowed?
556
- @overwrite == true
557
- end
558
-
559
- # Whether this permission has been denied, e.g has a red X-mark in the UI.
560
- # @return [true, false]
561
- def denied?
562
- @overwrite == false
563
- end
564
-
565
- # Whether this permission is applied to the everyone role in the server.
566
- # @return [true, false]
567
- def everyone?
568
- @target_id == @server_id
569
- end
570
-
571
- # Get the ID of the application command this permission is for.
572
- # @return [Integer, nil] This will be `nil` if the permission is the
573
- # default permission.
574
- def command_id
575
- @command_id unless default?
576
- end
577
-
578
- # Whether this permission is the default for all commands that don't
579
- # contain explicit permission oerwrites.
580
- # @return [true, false]
581
- def default?
582
- @command_id == @application_id
583
- end
584
-
585
- # Whether this permission is applied to every channel in the server.
586
- # @return [true, false]
587
- def all_channels?
588
- @target_id == (@server_id - 1)
589
- end
590
-
591
- # Get the user, role, or channel(s) that this permission targets.
592
- # @return [Array<Channel>, Role, Member]
593
- def target
594
- case @type
595
- when TYPES[:role]
596
- @bot.server(@server_id).role(@target_id)
597
- when TYPES[:member]
598
- @bot.server(@server_id).member(@target_id)
599
- when TYPES[:channel]
600
- all_channels? ? @bot.server(@server_id).channels : [@bot.channel(@target_id)]
601
- end
602
- end
603
-
604
- alias_method :targets, :target
605
-
606
- # @!method role?
607
- # @return [true, false] whether this permission is for a role.
608
- # @!method member?
609
- # @return [true, false] whether this permission is for a member.
610
- # @!method channel?
611
- # @return [true, false] whether this permission is for a channel.
612
- TYPES.each do |name, value|
613
- define_method("#{name}?") do
614
- @type == value
615
- end
616
- end
617
- end
618
- end
619
-
620
- # Objects specific to Interactions.
621
- module Interactions
622
- # A builder for defining slash commands options.
623
- class OptionBuilder
624
- # @!visibility private
625
- TYPES = {
626
- subcommand: 1,
627
- subcommand_group: 2,
628
- string: 3,
629
- integer: 4,
630
- boolean: 5,
631
- user: 6,
632
- channel: 7,
633
- role: 8,
634
- mentionable: 9,
635
- number: 10,
636
- attachment: 11
637
- }.freeze
638
-
639
- # Channel types that can be provided to #channel
640
- CHANNEL_TYPES = {
641
- text: 0,
642
- dm: 1,
643
- voice: 2,
644
- group_dm: 3,
645
- category: 4,
646
- news: 5,
647
- store: 6,
648
- news_thread: 10,
649
- public_thread: 11,
650
- private_thread: 12,
651
- stage: 13
652
- }.freeze
653
-
654
- # @return [Array<Hash>]
655
- attr_reader :options
656
-
657
- # @!visibility private
658
- def initialize
659
- @options = []
660
- end
661
-
662
- # @param name [String, Symbol] The name of the subcommand.
663
- # @param description [String] A description of the subcommand.
664
- # @yieldparam [OptionBuilder]
665
- # @return (see #option)
666
- # @example
667
- # bot.register_application_command(:test, 'Test command') do |cmd|
668
- # cmd.subcommand(:echo) do |sub|
669
- # sub.string('message', 'What to echo back', required: true)
670
- # end
671
- # end
672
- def subcommand(name, description)
673
- builder = OptionBuilder.new
674
- yield builder if block_given?
675
-
676
- option(TYPES[:subcommand], name, description, options: builder.to_a)
677
- end
678
-
679
- # @param name [String, Symbol] The name of the subcommand group.
680
- # @param description [String] A description of the subcommand group.
681
- # @yieldparam [OptionBuilder]
682
- # @return (see #option)
683
- # @example
684
- # bot.register_application_command(:test, 'Test command') do |cmd|
685
- # cmd.subcommand_group(:fun) do |group|
686
- # group.subcommand(:8ball) do |sub|
687
- # sub.string(:question, 'What do you ask the mighty 8ball?')
688
- # end
689
- # end
690
- # end
691
- def subcommand_group(name, description)
692
- builder = OptionBuilder.new
693
- yield builder
694
-
695
- option(TYPES[:subcommand_group], name, description, options: builder.to_a)
696
- end
697
-
698
- # @param name [String, Symbol] The name of the argument.
699
- # @param description [String] A description of the argument.
700
- # @param required [true, false] Whether this option must be provided.
701
- # @param min_length [Integer] A minimum length for option value.
702
- # @param max_length [Integer] A maximum length for option value.
703
- # @param choices [Hash, nil] Available choices, mapped as `Name => Value`.
704
- # @param autocomplete [true, false] Whether this option can dynamically show choices.
705
- # @return (see #option)
706
- def string(name, description, required: nil, min_length: nil, max_length: nil, choices: nil, autocomplete: nil)
707
- option(TYPES[:string], name, description,
708
- required: required, min_length: min_length, max_length: max_length, choices: choices, autocomplete: autocomplete)
709
- end
710
-
711
- # @param name [String, Symbol] The name of the argument.
712
- # @param description [String] A description of the argument.
713
- # @param required [true, false] Whether this option must be provided.
714
- # @param min_value [Integer] A minimum value for option.
715
- # @param max_value [Integer] A maximum value for option.
716
- # @param choices [Hash, nil] Available choices, mapped as `Name => Value`.
717
- # @param autocomplete [true, false] Whether this option can dynamically show choices.
718
- # @return (see #option)
719
- def integer(name, description, required: nil, min_value: nil, max_value: nil, choices: nil, autocomplete: nil)
720
- option(TYPES[:integer], name, description,
721
- required: required, min_value: min_value, max_value: max_value, choices: choices, autocomplete: autocomplete)
722
- end
723
-
724
- # @param name [String, Symbol] The name of the argument.
725
- # @param description [String] A description of the argument.
726
- # @param required [true, false] Whether this option must be provided.
727
- # @return (see #option)
728
- def boolean(name, description, required: nil)
729
- option(TYPES[:boolean], name, description, required: required)
730
- end
731
-
732
- # @param name [String, Symbol] The name of the argument.
733
- # @param description [String] A description of the argument.
734
- # @param required [true, false] Whether this option must be provided.
735
- # @return (see #option)
736
- def user(name, description, required: nil)
737
- option(TYPES[:user], name, description, required: required)
738
- end
739
-
740
- # @param name [String, Symbol] The name of the argument.
741
- # @param description [String] A description of the argument.
742
- # @param required [true, false] Whether this option must be provided.
743
- # @param types [Array<Symbol, Integer>] See {CHANNEL_TYPES}
744
- # @return (see #option)
745
- def channel(name, description, required: nil, types: nil)
746
- types = types&.collect { |type| type.is_a?(Numeric) ? type : CHANNEL_TYPES[type] }
747
- option(TYPES[:channel], name, description, required: required, channel_types: types)
748
- end
749
-
750
- # @param name [String, Symbol] The name of the argument.
751
- # @param description [String] A description of the argument.
752
- # @param required [true, false] Whether this option must be provided.
753
- # @return (see #option)
754
- def role(name, description, required: nil)
755
- option(TYPES[:role], name, description, required: required)
756
- end
757
-
758
- # @param name [String, Symbol] The name of the argument.
759
- # @param description [String] A description of the argument.
760
- # @param required [true, false] Whether this option must be provided.
761
- # @return (see #option)
762
- def mentionable(name, description, required: nil)
763
- option(TYPES[:mentionable], name, description, required: required)
764
- end
765
-
766
- # @param name [String, Symbol] The name of the argument.
767
- # @param description [String] A description of the argument.
768
- # @param required [true, false] Whether this option must be provided.
769
- # @param min_value [Float] A minimum value for option.
770
- # @param max_value [Float] A maximum value for option.
771
- # @param autocomplete [true, false] Whether this option can dynamically show choices.
772
- # @return (see #option)
773
- def number(name, description, required: nil, min_value: nil, max_value: nil, choices: nil, autocomplete: nil)
774
- option(TYPES[:number], name, description,
775
- required: required, min_value: min_value, max_value: max_value, choices: choices, autocomplete: autocomplete)
776
- end
777
-
778
- # @param name [String, Symbol] The name of the argument.
779
- # @param description [String] A description of the argument.
780
- # @param required [true, false] Whether this option must be provided.
781
- # @return (see #option)
782
- def attachment(name, description, required: nil)
783
- option(TYPES[:attachment], name, description, required: required)
784
- end
785
-
786
- # @!visibility private
787
- # @param type [Integer] The argument type.
788
- # @param name [String, Symbol] The name of the argument.
789
- # @param description [String] A description of the argument.
790
- # @param required [true, false] Whether this option must be provided.
791
- # @param min_value [Integer, Float] A minimum value for integer and number options.
792
- # @param max_value [Integer, Float] A maximum value for integer and number options.
793
- # @param min_length [Integer] A minimum length for string option value.
794
- # @param max_length [Integer] A maximum length for string option value.
795
- # @param channel_types [Array<Integer>] Channel types that can be provides for channel options.
796
- # @param autocomplete [true, false] Whether this option can dynamically show options.
797
- # @return Hash
798
- def option(type, name, description, required: nil, choices: nil, options: nil, min_value: nil, max_value: nil,
799
- min_length: nil, max_length: nil, channel_types: nil, autocomplete: nil)
800
- opt = { type: type, name: name, description: description }
801
- choices = choices.map { |option_name, value| { name: option_name, value: value } } if choices
802
-
803
- opt.merge!({ required: required, choices: choices, options: options, min_value: min_value,
804
- max_value: max_value, min_length: min_length, max_length: max_length,
805
- channel_types: channel_types, autocomplete: autocomplete }.compact)
806
-
807
- @options << opt
808
- opt
809
- end
810
-
811
- # @return [Array<Hash>]
812
- def to_a
813
- @options
814
- end
815
- end
816
-
817
- # Builder for creating server application command permissions.
818
- # @deprecated This system is being replaced in the near future.
819
- class PermissionBuilder
820
- # Role permission type
821
- ROLE = 1
822
- # User permission type
823
- USER = 2
824
-
825
- # @!visibility hidden
826
- def initialize
827
- @permissions = []
828
- end
829
-
830
- # Allow a role to use this command.
831
- # @param role_id [Integer]
832
- # @return [PermissionBuilder]
833
- def allow_role(role_id)
834
- create_entry(role_id, ROLE, true)
835
- end
836
-
837
- # Deny a role usage of this command.
838
- # @param role_id [Integer]
839
- # @return [PermissionBuilder]
840
- def deny_role(role_id)
841
- create_entry(role_id, ROLE, false)
842
- end
843
-
844
- # Allow a user to use this command.
845
- # @param user_id [Integer]
846
- # @return [PermissionBuilder]
847
- def allow_user(user_id)
848
- create_entry(user_id, USER, true)
849
- end
850
-
851
- # Deny a user usage of this command.
852
- # @param user_id [Integer]
853
- # @return [PermissionBuilder]
854
- def deny_user(user_id)
855
- create_entry(user_id, USER, false)
856
- end
857
-
858
- # Allow an entity to use this command.
859
- # @param object [Role, User, Member]
860
- # @return [PermissionBuilder]
861
- # @raise [ArgumentError]
862
- def allow(object)
863
- case object
864
- when OnyxCord::User, OnyxCord::Member
865
- create_entry(object.id, USER, true)
866
- when OnyxCord::Role
867
- create_entry(object.id, ROLE, true)
868
- else
869
- raise ArgumentError, "Unable to create permission for unknown type: #{object.class}"
870
- end
871
- end
872
-
873
- # Deny an entity usage of this command.
874
- # @param object [Role, User, Member]
875
- # @return [PermissionBuilder]
876
- # @raise [ArgumentError]
877
- def deny(object)
878
- case object
879
- when OnyxCord::User, OnyxCord::Member
880
- create_entry(object.id, USER, false)
881
- when OnyxCord::Role
882
- create_entry(object.id, ROLE, false)
883
- else
884
- raise ArgumentError, "Unable to create permission for unknown type: #{object.class}"
885
- end
886
- end
887
-
888
- # @!visibility private
889
- # @return [Array<Hash>]
890
- def to_a
891
- @permissions
892
- end
893
-
894
- private
895
-
896
- def create_entry(id, type, permission)
897
- @permissions << { id: id, type: type, permission: permission }
898
- self
899
- end
900
- end
901
-
902
- # A message partial for interactions.
903
- class Message
904
- include IDObject
905
-
906
- # @return [Interaction] The interaction that created this message.
907
- attr_reader :interaction
908
-
909
- # @return [String, nil] The content of the message.
910
- attr_reader :content
911
-
912
- # @return [true, false] Whether this message is pinned in the channel it belongs to.
913
- attr_reader :pinned
914
-
915
- # @return [true, false]
916
- attr_reader :tts
917
-
918
- # @return [Time]
919
- attr_reader :timestamp
920
-
921
- # @return [Time, nil]
922
- attr_reader :edited_timestamp
923
-
924
- # @return [true, false]
925
- attr_reader :edited
926
-
927
- # @return [Integer]
928
- attr_reader :id
929
-
930
- # @return [User] The user of the application.
931
- attr_reader :author
932
-
933
- # @return [Attachment]
934
- attr_reader :attachments
935
-
936
- # @return [Array<Embed>]
937
- attr_reader :embeds
938
-
939
- # @return [Array<User>]
940
- attr_reader :mentions
941
-
942
- # @return [Integer]
943
- attr_reader :flags
944
-
945
- # @return [Integer]
946
- attr_reader :channel_id
947
-
948
- # @return [Hash, nil]
949
- attr_reader :message_reference
950
-
951
- # @return [Array<Component>]
952
- attr_reader :components
953
-
954
- # @!visibility private
955
- def initialize(data, bot, interaction)
956
- @data = data
957
- @bot = bot
958
- @interaction = interaction
959
- @content = data['content']
960
- @channel_id = data['channel_id'].to_i
961
- @pinned = data['pinned']
962
- @tts = data['tts']
963
-
964
- @message_reference = data['message_reference']
965
-
966
- @server_id = @interaction.server_id
967
-
968
- @timestamp = Time.parse(data['timestamp']) if data['timestamp']
969
- @edited_timestamp = data['edited_timestamp'].nil? ? nil : Time.parse(data['edited_timestamp'])
970
- @edited = !@edited_timestamp.nil?
971
-
972
- @id = data['id'].to_i
973
-
974
- @author = bot.ensure_user(data['author'] || data['member']['user'])
975
-
976
- @attachments = []
977
- @attachments = data['attachments'].map { |e| Attachment.new(e, self, @bot) } if data['attachments']
978
-
979
- @embeds = []
980
- @embeds = data['embeds'].map { |e| Embed.new(e, self) } if data['embeds']
981
-
982
- @mentions = []
983
-
984
- data['mentions']&.each do |element|
985
- @mentions << bot.ensure_user(element)
986
- end
987
-
988
- @mention_roles = data['mention_roles']
989
- @mention_everyone = data['mention_everyone']
990
- @flags = data['flags']
991
- @pinned = data['pinned']
992
- @components = data['components']&.filter_map { |component| Components.from_data(component, @bot) } || []
993
- end
994
-
995
- # @return [Member, nil] This will return nil if the bot does not have access to the
996
- # server the interaction originated in.
997
- def member
998
- server&.member(@user.id)
999
- end
1000
-
1001
- # @return [Server, nil] This will return nil if the bot does not have access to the
1002
- # server the interaction originated in.
1003
- def server
1004
- @bot.server(@server_id)
1005
- end
1006
-
1007
- # @return [Channel] The channel the interaction originates from.
1008
- # @raise [Errors::NoPermission] When the bot is not in the server associated with this interaction.
1009
- def channel
1010
- @bot.channel(@channel_id)
1011
- end
1012
-
1013
- # Respond to this message.
1014
- # @param (see Interaction#send_message)
1015
- # @yieldparam (see Interaction#send_message)
1016
- def respond(content: nil, embeds: nil, allowed_mentions: nil, flags: 0, ephemeral: true, components: nil, attachments: nil, &block)
1017
- @interaction.send_message(content: content, embeds: embeds, allowed_mentions: allowed_mentions, flags: flags, ephemeral: ephemeral, components: components, attachments: attachments, &block)
1018
- end
1019
-
1020
- # Delete this message.
1021
- def delete
1022
- @interaction.delete_message(@id)
1023
- end
1024
-
1025
- # Edit this message's data.
1026
- # @param content (see Interaction#send_message)
1027
- # @param embeds (see Interaction#send_message)
1028
- # @param allowed_mentions (see Interaction#send_message)
1029
- # @yieldparam (see Interaction#send_message)
1030
- def edit(content: nil, embeds: nil, allowed_mentions: nil, components: nil, attachments: nil, &block)
1031
- @interaction.edit_message(@id, content: content, embeds: embeds, allowed_mentions: allowed_mentions, components: components, attachments: attachments, &block)
1032
- end
1033
-
1034
- # @return [OnyxCord::Message]
1035
- def to_message
1036
- OnyxCord::Message.new(@data, @bot)
1037
- end
1038
-
1039
- alias_method :message, :to_message
1040
-
1041
- # @!visibility private
1042
- def inspect
1043
- "<Interaction::Message content=#{@content.inspect} embeds=#{@embeds.inspect} channel_id=#{@channel_id} server_id=#{@server_id} author=#{@author.inspect}>"
1044
- end
1045
- end
1046
-
1047
- # Supplemental metadata about an interaction.
1048
- class Metadata
1049
- include IDObject
1050
-
1051
- # @return [Integer] the type of the interaction.
1052
- attr_reader :type
1053
-
1054
- # @return [User] the user that initiated the interaction.
1055
- attr_reader :user
1056
-
1057
- # @return [User, nil] the user that the command was ran on.
1058
- attr_reader :target_user
1059
-
1060
- # @return [Integer, nil] the ID of the message the command was ran on.
1061
- attr_reader :target_message_id
1062
-
1063
- # @return [Metadata, nil] the metadata for the interaction that opened the modal.
1064
- attr_reader :triggering_metadata
1065
-
1066
- # @return [Integer, nil] the ID of the message that contained the interactive message component.
1067
- attr_reader :interacted_message_id
1068
-
1069
- # @return [Integer, nil] the ID the original response message; only present on follow-up messages.
1070
- attr_reader :original_response_message_id
1071
-
1072
- # @!visibility private
1073
- def initialize(data, message, bot)
1074
- @bot = bot
1075
- @message = message
1076
- @id = data['id'].to_i
1077
- @type = data['type']
1078
- @user = bot.ensure_user(data['user']) if data['user']
1079
- @target_user = bot.ensure_user(data['target_user']) if data['target_user']
1080
- @target_message_id = data['target_message_id']&.to_i
1081
- @triggering_metadata = Metadata.new(data['triggering_interaction_metadata'], @message, @bot) if data['triggering_interaction_metadata']
1082
- @interacted_message_id = data['interacted_message_id']&.to_i
1083
- @original_response_message_id = data['original_response_message_id']&.to_i
1084
- @integration_owners = data['authorizing_integration_owners']&.to_h { |key, value| [key.to_i, value.to_i] }
1085
- end
1086
-
1087
- # Check if the interaction was triggered by a user by installed the application.
1088
- # @return [true, false] whether or not the application was installed by the user
1089
- # who initiated this interaction.
1090
- def user_integration?
1091
- @integration_owners[1] == @user.id
1092
- end
1093
-
1094
- # Check if the interaction was triggered by a server by installed the application.
1095
- # @return [true, false] whether or not the application was installed by the server
1096
- # where this interaction originates from.
1097
- def server_integration?
1098
- @integration_owners[0] == @message.server.id
1099
- end
1100
-
1101
- # Attempt to fetch the target message of the interaction.
1102
- # @return [Message, nil] the target message of the interaction, or `nil` if it couldn't be found.
1103
- def target_message
1104
- return unless @target_message_id
1105
-
1106
- @target_message ||= @message.channel.message(@target_message_id)
1107
- end
1108
-
1109
- # Attempt to fetch the message that contained the interatctive component.
1110
- # @return [Message, nil] the interacted message with the component, or `nil` if it couldn't be found.
1111
- def interacted_message
1112
- return unless @interacted_message_id
1113
-
1114
- @interacted_message ||= @message.channel.message(@interacted_message_id)
1115
- end
1116
-
1117
- # Attempt to fetch the original response message of the interaction.
1118
- # @return [Message, nil] the original response message of the interaction, or `nil` if it couldn't be found.
1119
- def original_response_message
1120
- return unless @original_response_message_id
1121
-
1122
- @original_response_message ||= @message.channel.message(@original_response_message_id)
1123
- end
1124
-
1125
- # @!method command?
1126
- # @return [true, false] whether or not the interaction metadata is for an application command.
1127
- # @!method component?
1128
- # @return [true, false] whether or not the interaction metadata is for a message component.
1129
- # @!method modal_submit?
1130
- # @return [true, false] whether or not the interaction metadata is for a modal submission.
1131
- Interaction::TYPES.each do |name, value|
1132
- define_method("#{name}?") do
1133
- @type == value
1134
- end
1135
- end
1136
-
1137
- # @!visibility private
1138
- def inspect
1139
- "<Interactions::Metadata id=#{@id} type=#{@type} user=#{@user.inspect} target_user=#{@target_user.inspect}>"
1140
- end
1141
- end
1142
- end
1143
- end