onyxcord 1.1.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 (133) hide show
  1. checksums.yaml +7 -0
  2. data/.devcontainer/Dockerfile +13 -0
  3. data/.devcontainer/devcontainer.json +29 -0
  4. data/.devcontainer/postcreate.sh +4 -0
  5. data/.github/CONTRIBUTING.md +13 -0
  6. data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  7. data/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
  8. data/.github/pull_request_template.md +37 -0
  9. data/.github/workflows/ci.yml +78 -0
  10. data/.github/workflows/codeql.yml +65 -0
  11. data/.github/workflows/deploy.yml +54 -0
  12. data/.github/workflows/release.yml +51 -0
  13. data/.gitignore +16 -0
  14. data/.markdownlint.json +4 -0
  15. data/.overcommit.yml +7 -0
  16. data/.rspec +2 -0
  17. data/.rubocop.yml +129 -0
  18. data/.yardopts +1 -0
  19. data/CHANGELOG.md +0 -0
  20. data/Gemfile +7 -0
  21. data/LICENSE.txt +21 -0
  22. data/README.md +305 -0
  23. data/Rakefile +17 -0
  24. data/bin/console +15 -0
  25. data/bin/setup +7 -0
  26. data/lib/onyxcord/allowed_mentions.rb +43 -0
  27. data/lib/onyxcord/api/application.rb +316 -0
  28. data/lib/onyxcord/api/channel.rb +700 -0
  29. data/lib/onyxcord/api/interaction.rb +67 -0
  30. data/lib/onyxcord/api/invite.rb +44 -0
  31. data/lib/onyxcord/api/server.rb +775 -0
  32. data/lib/onyxcord/api/user.rb +158 -0
  33. data/lib/onyxcord/api/webhook.rb +163 -0
  34. data/lib/onyxcord/api.rb +335 -0
  35. data/lib/onyxcord/await.rb +51 -0
  36. data/lib/onyxcord/bot.rb +1971 -0
  37. data/lib/onyxcord/cache.rb +326 -0
  38. data/lib/onyxcord/colour_rgb.rb +43 -0
  39. data/lib/onyxcord/commands/command_bot.rb +511 -0
  40. data/lib/onyxcord/commands/container.rb +112 -0
  41. data/lib/onyxcord/commands/events.rb +11 -0
  42. data/lib/onyxcord/commands/parser.rb +327 -0
  43. data/lib/onyxcord/commands/rate_limiter.rb +144 -0
  44. data/lib/onyxcord/configuration.rb +125 -0
  45. data/lib/onyxcord/container.rb +988 -0
  46. data/lib/onyxcord/data/activity.rb +271 -0
  47. data/lib/onyxcord/data/application.rb +341 -0
  48. data/lib/onyxcord/data/attachment.rb +91 -0
  49. data/lib/onyxcord/data/audit_logs.rb +438 -0
  50. data/lib/onyxcord/data/avatar_decoration.rb +26 -0
  51. data/lib/onyxcord/data/call.rb +22 -0
  52. data/lib/onyxcord/data/channel.rb +1355 -0
  53. data/lib/onyxcord/data/channel_tag.rb +69 -0
  54. data/lib/onyxcord/data/collectibles.rb +47 -0
  55. data/lib/onyxcord/data/component.rb +583 -0
  56. data/lib/onyxcord/data/embed.rb +258 -0
  57. data/lib/onyxcord/data/emoji.rb +123 -0
  58. data/lib/onyxcord/data/install_params.rb +24 -0
  59. data/lib/onyxcord/data/integration.rb +144 -0
  60. data/lib/onyxcord/data/interaction.rb +1141 -0
  61. data/lib/onyxcord/data/invite.rb +137 -0
  62. data/lib/onyxcord/data/member.rb +528 -0
  63. data/lib/onyxcord/data/message.rb +612 -0
  64. data/lib/onyxcord/data/message_activity.rb +41 -0
  65. data/lib/onyxcord/data/overwrite.rb +109 -0
  66. data/lib/onyxcord/data/poll.rb +365 -0
  67. data/lib/onyxcord/data/primary_server.rb +60 -0
  68. data/lib/onyxcord/data/profile.rb +79 -0
  69. data/lib/onyxcord/data/reaction.rb +64 -0
  70. data/lib/onyxcord/data/recipient.rb +34 -0
  71. data/lib/onyxcord/data/role.rb +449 -0
  72. data/lib/onyxcord/data/role_connection_data.rb +69 -0
  73. data/lib/onyxcord/data/role_subscription.rb +41 -0
  74. data/lib/onyxcord/data/scheduled_event.rb +513 -0
  75. data/lib/onyxcord/data/server.rb +1614 -0
  76. data/lib/onyxcord/data/server_preview.rb +68 -0
  77. data/lib/onyxcord/data/snapshot.rb +112 -0
  78. data/lib/onyxcord/data/team.rb +98 -0
  79. data/lib/onyxcord/data/timestamp.rb +69 -0
  80. data/lib/onyxcord/data/user.rb +324 -0
  81. data/lib/onyxcord/data/voice_region.rb +46 -0
  82. data/lib/onyxcord/data/voice_state.rb +41 -0
  83. data/lib/onyxcord/data/webhook.rb +238 -0
  84. data/lib/onyxcord/data.rb +57 -0
  85. data/lib/onyxcord/errors.rb +246 -0
  86. data/lib/onyxcord/event_executor.rb +80 -0
  87. data/lib/onyxcord/events/await.rb +48 -0
  88. data/lib/onyxcord/events/bans.rb +60 -0
  89. data/lib/onyxcord/events/channels.rb +225 -0
  90. data/lib/onyxcord/events/generic.rb +129 -0
  91. data/lib/onyxcord/events/guilds.rb +269 -0
  92. data/lib/onyxcord/events/integrations.rb +100 -0
  93. data/lib/onyxcord/events/interactions.rb +624 -0
  94. data/lib/onyxcord/events/invites.rb +127 -0
  95. data/lib/onyxcord/events/lifetime.rb +31 -0
  96. data/lib/onyxcord/events/members.rb +110 -0
  97. data/lib/onyxcord/events/message.rb +399 -0
  98. data/lib/onyxcord/events/polls.rb +118 -0
  99. data/lib/onyxcord/events/presence.rb +131 -0
  100. data/lib/onyxcord/events/raw.rb +74 -0
  101. data/lib/onyxcord/events/reactions.rb +218 -0
  102. data/lib/onyxcord/events/roles.rb +87 -0
  103. data/lib/onyxcord/events/scheduled_events.rb +171 -0
  104. data/lib/onyxcord/events/threads.rb +100 -0
  105. data/lib/onyxcord/events/typing.rb +73 -0
  106. data/lib/onyxcord/events/voice_server_update.rb +48 -0
  107. data/lib/onyxcord/events/voice_state_update.rb +106 -0
  108. data/lib/onyxcord/events/webhooks.rb +65 -0
  109. data/lib/onyxcord/gateway.rb +890 -0
  110. data/lib/onyxcord/id_object.rb +39 -0
  111. data/lib/onyxcord/light/data.rb +62 -0
  112. data/lib/onyxcord/light/integrations.rb +73 -0
  113. data/lib/onyxcord/light/light_bot.rb +58 -0
  114. data/lib/onyxcord/light.rb +8 -0
  115. data/lib/onyxcord/logger.rb +120 -0
  116. data/lib/onyxcord/message_components.rb +70 -0
  117. data/lib/onyxcord/paginator.rb +60 -0
  118. data/lib/onyxcord/permissions.rb +255 -0
  119. data/lib/onyxcord/rate_limiter/gateway.rb +42 -0
  120. data/lib/onyxcord/rate_limiter/rest.rb +89 -0
  121. data/lib/onyxcord/version.rb +7 -0
  122. data/lib/onyxcord/voice/encoder.rb +115 -0
  123. data/lib/onyxcord/voice/network.rb +380 -0
  124. data/lib/onyxcord/voice/opcodes.rb +29 -0
  125. data/lib/onyxcord/voice/sodium.rb +157 -0
  126. data/lib/onyxcord/voice/timer.rb +19 -0
  127. data/lib/onyxcord/voice/voice_bot.rb +386 -0
  128. data/lib/onyxcord/webhooks.rb +14 -0
  129. data/lib/onyxcord/websocket.rb +62 -0
  130. data/lib/onyxcord.rb +180 -0
  131. data/onyxcord-webhooks.gemspec +30 -0
  132. data/onyxcord.gemspec +50 -0
  133. metadata +421 -0
@@ -0,0 +1,271 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OnyxCord
4
+ # Contains information about user activities such as the game they are playing,
5
+ # music they are listening to, or their live stream.
6
+ class Activity
7
+ # Values corresponding to the flags bitmask
8
+ FLAGS = {
9
+ instance: 1 << 0, # this activity is an instanced game session
10
+ join: 1 << 1, # this activity is joinable
11
+ spectate: 1 << 2, # this activity can be spectated
12
+ join_request: 1 << 3, # this activity allows asking to join
13
+ sync: 1 << 4, # this activity is a spotify track
14
+ play: 1 << 5 # this game can be played or opened from discord
15
+ }.freeze
16
+
17
+ # @return [String] the activity's name
18
+ attr_reader :name
19
+
20
+ # @return [Integer, nil] activity type. Can be {GAME}, {STREAMING}, {LISTENING}, {CUSTOM}, or {COMPETING}
21
+ attr_reader :type
22
+
23
+ # @return [String, nil] stream URL, when the activity type is {STREAMING}
24
+ attr_reader :url
25
+
26
+ # @return [String, nil] the application ID for the game
27
+ attr_reader :application_id
28
+
29
+ # @return [String, nil] details about what the player is currently doing
30
+ attr_reader :details
31
+
32
+ # @return [String, nil] the user's current party status
33
+ attr_reader :state
34
+
35
+ # @return [true, false] whether or not the activity is an instanced game session
36
+ attr_reader :instance
37
+
38
+ # @return [Integer] a bitmask of activity flags
39
+ # @see FLAGS
40
+ attr_reader :flags
41
+
42
+ # @return [Timestamps, nil] times for the start and/or end of the activity
43
+ attr_reader :timestamps
44
+
45
+ # @return [Secrets, nil] secrets for rich presence, joining, and spectating
46
+ attr_reader :secrets
47
+
48
+ # @return [Assets, nil] images for the presence and their texts
49
+ attr_reader :assets
50
+
51
+ # @return [Party, nil] information about the player's current party
52
+ attr_reader :party
53
+
54
+ # @return [Emoji, nil] emoji data for custom statuses
55
+ attr_reader :emoji
56
+
57
+ # @return [Time] the time when the activity was added to the user's session
58
+ attr_reader :created_at
59
+
60
+ # Type indicating the activity is for a game
61
+ GAME = 0
62
+ # Type indicating the activity is a stream
63
+ STREAMING = 1
64
+ # Type indicating the activity is for music
65
+ LISTENING = 2
66
+ # This type is currently unused in the client but can be reported by bots
67
+ WATCHING = 3
68
+ # Type indicating the activity is a custom status
69
+ CUSTOM = 4
70
+ # Type indicating the activity is for a competitive game
71
+ COMPETING = 5
72
+
73
+ # @!visibility private
74
+ def initialize(data, bot)
75
+ @name = data['name']
76
+ @type = data['type']
77
+ @url = data['url']
78
+ @application_id = data['application_id']
79
+ @details = data['details']
80
+ @state = data['state']
81
+ @instance = data['instance']
82
+ @flags = data['flags'] || 0
83
+ @created_at = Time.at(data['created_at'].to_i)
84
+
85
+ @timestamps = Timestamps.new(data['timestamps']) if data['timestamps']
86
+ @secrets = Secrets.new(data['secrets']) if data['secrets']
87
+ @assets = Assets.new(data['assets'], @application_id) if data['assets']
88
+ @party = Party.new(data['party']) if data['party']
89
+ @emoji = Emoji.new(data['emoji'], bot, nil) if data['emoji']
90
+ end
91
+
92
+ # @return [true, false] Whether or not the `join` flag is set for this activity
93
+ def join?
94
+ flag_set? :join
95
+ end
96
+
97
+ # @return [true, false] Whether or not the `spectate` flag is set for this activity
98
+ def spectate?
99
+ flag_set? :spectate
100
+ end
101
+
102
+ # @return [true, false] Whether or not the `join_request` flag is set for this activity
103
+ def join_request?
104
+ flag_set? :join_request
105
+ end
106
+
107
+ # @return [true, false] Whether or not the `sync` flag is set for this activity
108
+ def sync?
109
+ flag_set? :sync
110
+ end
111
+
112
+ # @return [true, false] Whether or not the `play` flag is set for this activity
113
+ def play?
114
+ flag_set? :play
115
+ end
116
+
117
+ # @return [true, false] Whether or not the `instance` flag is set for this activity
118
+ def instance?
119
+ @instance || flag_set?(:instance)
120
+ end
121
+
122
+ # @!visibility private
123
+ def flag_set?(sym)
124
+ !@flags.nobits?(FLAGS[sym])
125
+ end
126
+
127
+ # Timestamps for the start and end of instanced activities
128
+ class Timestamps
129
+ # @return [Time, nil]
130
+ attr_reader :start
131
+
132
+ # @return [Time, nil]
133
+ attr_reader :end
134
+
135
+ # @!visibility private
136
+ def initialize(data)
137
+ @start = Time.at(data['start'] / 1000) if data['start']
138
+ @end = Time.at(data['end'] / 1000) if data['end']
139
+ end
140
+ end
141
+
142
+ # Contains secrets used for rich presence
143
+ class Secrets
144
+ # @return [String, nil] secret for joining a party
145
+ attr_reader :join
146
+
147
+ # @return [String, nil] secret for spectating
148
+ attr_reader :spectate
149
+
150
+ # @return [String, nil] secret for a specific instanced match
151
+ attr_reader :match
152
+
153
+ # @!visibility private
154
+ def initialize(data)
155
+ @join = data['join']
156
+ @spectate = data['spectate']
157
+ @match = data['match']
158
+ end
159
+ end
160
+
161
+ # Assets for rich presence images and hover text
162
+ class Assets
163
+ # @return [String, nil] the asset ID for the large image of this activity
164
+ attr_reader :large_image_id
165
+
166
+ # @return [String, nil] text displayed when hovering over the large iamge
167
+ attr_reader :large_text
168
+
169
+ # @return [String, nil] the asset ID for the small image of this activity
170
+ attr_reader :small_image_id
171
+
172
+ # @return [String, nil]
173
+ attr_reader :small_text
174
+
175
+ # @return [String, nil] the application ID for these assets.
176
+ attr_reader :application_id
177
+
178
+ # @!visibility private
179
+ def initialize(data, application_id)
180
+ @application_id = application_id
181
+ @large_image_id = data['large_image']
182
+ @large_text = data['large_text']
183
+ @small_image_id = data['small_image']
184
+ @small_text = data['small_text']
185
+ end
186
+
187
+ # Utility function to get an Asset's large image URL.
188
+ # @param format [String, nil] If `nil`, the URL will default to `webp`. You can otherwise specify one of `webp`, `jpg`, or `png`.
189
+ # @return [String] the URL to the large image asset.
190
+ def large_image_url(format = 'webp')
191
+ API.asset_url(@application_id, @large_image_id, format)
192
+ end
193
+
194
+ # Utility function to get an Asset's large image URL.
195
+ # @param format [String, nil] If `nil`, the URL will default to `webp`. You can otherwise specify one of `webp`, `jpg`, or `png`.
196
+ # @return [String] the URL to the small image asset.
197
+ def small_image_url(format = 'webp')
198
+ API.asset_url(@application_id, @small_image_id, format)
199
+ end
200
+ end
201
+
202
+ # Contains information about an activity's party
203
+ class Party
204
+ # @return [String, nil]
205
+ attr_reader :id
206
+
207
+ # @return [Integer, nil]
208
+ attr_reader :current_size
209
+
210
+ # @return [Integer, nil]
211
+ attr_reader :max_size
212
+
213
+ # @!visibility private
214
+ def initialize(data)
215
+ @id = data['id']
216
+ @current_size, @max_size = data['size']
217
+ end
218
+ end
219
+ end
220
+
221
+ # A collection of the user's activities.
222
+ class ActivitySet
223
+ include Enumerable
224
+
225
+ # @!visibility private
226
+ def initialize(activities = [])
227
+ @activities = activities
228
+ end
229
+
230
+ # @!visibility private
231
+ # Implement each for Enumerable
232
+ def each(&block)
233
+ @activities.each(&block)
234
+ end
235
+
236
+ # @return [Array<Activity>] all activities
237
+ def to_a
238
+ @activities
239
+ end
240
+
241
+ # @return [Array<Activity>] all activities of type {Activity::GAME}
242
+ def games
243
+ @activities.select { |act| act.type == Activity::GAME }
244
+ end
245
+
246
+ # @return [Array<Activity>] all activities of type {Activity::STREAMING}
247
+ def streaming
248
+ @activities.select { |act| act.type == Activity::STREAMING }
249
+ end
250
+
251
+ # @return [Array<Activity>] all activities of type {Activity::LISTENING}
252
+ def listening
253
+ @activities.select { |act| act.type == Activity::LISTENING }
254
+ end
255
+
256
+ # @return [Array<Activity>] all activities of type {Activity::WATCHING}
257
+ def watching
258
+ @activities.select { |act| act.type == Activity::WATCHING }
259
+ end
260
+
261
+ # @return [Array<Activity>] all activities of type {Activity::CUSTOM}
262
+ def custom_status
263
+ @activities.select { |act| act.type == Activity::CUSTOM }
264
+ end
265
+
266
+ # @return [Array<Activity>] all activities of type {Activity::COMPETING}
267
+ def competing
268
+ @activities.select { |act| act.type == Activity::COMPETING }
269
+ end
270
+ end
271
+ end
@@ -0,0 +1,341 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OnyxCord
4
+ # Information about a bot's associated application.
5
+ class Application
6
+ include IDObject
7
+
8
+ # Map of application flags.
9
+ FLAGS = {
10
+ automod_rule_badge: 1 << 6,
11
+ approved_presence_intent: 1 << 12,
12
+ limited_presence_intent: 1 << 13,
13
+ approved_server_members_intent: 1 << 14,
14
+ limited_server_members_intent: 1 << 15,
15
+ pending_server_limit_verification: 1 << 16,
16
+ embedded: 1 << 17,
17
+ approved_message_content_intent: 1 << 18,
18
+ limited_message_content_intent: 1 << 19,
19
+ application_command_badge: 1 << 23
20
+ }.freeze
21
+
22
+ # @return [String] the application's name.
23
+ attr_reader :name
24
+
25
+ # @return [String] the application's description, or an empty string if the application doesn't have a description.
26
+ attr_reader :description
27
+
28
+ # @return [Array<String>] the application's origins permitted to use RPC.
29
+ attr_reader :rpc_origins
30
+
31
+ # @return [Integer] the application's public flags.
32
+ attr_reader :flags
33
+
34
+ # @return [User, nil] the user that owns the application, or nil if the application belongs to a team.
35
+ attr_reader :owner
36
+
37
+ # @return [String, nil] the ID of the application's icon. Can be used to generate an icon URL.
38
+ # @see #icon_url
39
+ attr_reader :icon_id
40
+
41
+ # @return [true, false] if users other than the bot owner can add the bot to servers.
42
+ attr_reader :public
43
+ alias_method :public?, :public
44
+
45
+ # @return [true, false] whether the bot requires the full OAuth2 code grant in order to join servers.
46
+ attr_reader :requires_code_grant
47
+ alias_method :requires_code_grant?, :requires_code_grant
48
+
49
+ # @return [String, nil] the URL to the application's terms of service.
50
+ attr_reader :terms_of_service_url
51
+
52
+ # @return [String, nil] the URL to the application's privacy policy.
53
+ attr_reader :privacy_policy_url
54
+
55
+ # @return [String] the hex encoded key for verification in interactions and the GameSDK.
56
+ attr_reader :verify_key
57
+
58
+ # @return [Team, nil] the team that owns this application, or `nil` if the application isn't owned by a team.
59
+ attr_reader :team
60
+
61
+ # @return [Integer, nil] the ID of the server that is associated with this application.
62
+ attr_reader :server_id
63
+
64
+ # @return [String, nil] the URL slug that links to the application's game store page.
65
+ attr_reader :slug
66
+
67
+ # @return [Integer, nil] the game SKU ID if this application is a game sold on Discord.
68
+ attr_reader :primary_sku_id
69
+
70
+ # @return [String, nil] the ID of the application's default rich presence invite cover image.
71
+ # Can be used to generate a cover image URL.
72
+ # @see #cover_image_url
73
+ attr_reader :cover_image_id
74
+
75
+ # @return [Integer] the approximate amount of server's the application has been added to.
76
+ attr_reader :server_install_count
77
+
78
+ # @return [Integer] the approximate amount of users that have installed the application with the
79
+ # `application.commands` oauth scope.
80
+ attr_reader :user_install_count
81
+
82
+ # @return [Integer] the approximate amount of users that have OAuth2 authorizations for the application.
83
+ attr_reader :user_authorization_count
84
+
85
+ # @return [Array<String>] an array of redirect URIs for the application.
86
+ attr_reader :redirect_uris
87
+ alias_method :redirect_urls, :redirect_uris
88
+
89
+ # @return [String, nil] the interactions endpoint URL for the application.
90
+ attr_reader :interactions_endpoint_url
91
+
92
+ # @return [String, nil] the role connections URL for the application.
93
+ attr_reader :role_connections_verification_url
94
+
95
+ # @return [String, nil] the webhook events URL used by the application to receive webhook events.
96
+ attr_reader :webhook_events_url
97
+
98
+ # @return [Integer] the status of the application's webhook events.
99
+ attr_reader :webhook_events_status
100
+
101
+ # @return [Array<String>] the webhook event types that the application is subscribed to.
102
+ attr_reader :webhook_event_types
103
+
104
+ # @return [Array<String>] an array of traits describing the content and functionality of the application.
105
+ attr_reader :tags
106
+
107
+ # @return [InstallParams] the settings for the application's default authorization link.
108
+ attr_reader :install_params
109
+
110
+ # @return [Hash<Integer => InstallParams>] the default scopes and permissions for each supported installation context.
111
+ attr_reader :integration_types
112
+
113
+ # @return [String, nil] the default custom authorization URL for the application.
114
+ attr_reader :custom_install_url
115
+
116
+ # @!visibility private
117
+ def initialize(data, bot)
118
+ @bot = bot
119
+ @id = data['id'].to_i
120
+ update_data(data)
121
+ end
122
+
123
+ # Get the server associated with this application.
124
+ # @return [Server, nil] This will be nil if the bot does not have an associated server set.
125
+ # @raise [OnyxCord::Errors::NoPermission] This can happen when the bot is not in the associated server.
126
+ def server
127
+ @bot.server(@server_id) if @server_id
128
+ end
129
+
130
+ # Utility method to get a application's icon URL.
131
+ # @param format [String] The URL will default to `webp`. You can otherwise specify one of `webp`, `jpg` or `png` to override this.
132
+ # @return [String, nil] The URL of the icon image (`nil` if no image is set).
133
+ def icon_url(format: 'webp')
134
+ API.app_icon_url(@id, @icon_id, format) if @icon_id
135
+ end
136
+
137
+ # Utility method to get a application's cover image URL.
138
+ # @param format [String] The URL will default to `webp`. You can otherwise specify one of `webp`, `jpg` or `png` to override this.
139
+ # @return [String, nil] The URL of the cover image (`nil` if no cover is set).
140
+ def cover_image_url(format: 'webp')
141
+ API.app_cover_url(@id, @cover_image_id, format) if @cover_image_id
142
+ end
143
+
144
+ # Delete an integration types config for the application.
145
+ # @param type [Integer, String] The type of the integration type to remove.
146
+ # @return [nil]
147
+ def delete_integration_type(type)
148
+ new_data = @integration_types.dup.tap { |i| i.delete(type.to_i) }
149
+ modify(integration_types: collect_integration_types(new_data))
150
+ end
151
+
152
+ # Add an integration types config for the application.
153
+ # @param type [Integer, String] The type of the integration type.
154
+ # @param scopes [Array<String, Symbol>, nil] The default Oauth scopes for the config.
155
+ # @param permissions [Permissions, String, Integer, nil] The default permissions for the config.
156
+ # @return [nil]
157
+ def add_integration_type(type:, scopes: nil, permissions: nil)
158
+ permissions = permisisons.bits if permissions.respond_to?(:bits)
159
+ new_data = @integration_types.dup
160
+
161
+ new_data[type.to_i] = {
162
+ scopes: scopes&.map(&:to_s),
163
+ permissions: permissions&.to_s
164
+ }
165
+
166
+ modify(integration_types: collect_integration_types(new_data.compact))
167
+ end
168
+
169
+ # Get the integration types config for when the application has been installed to a user.
170
+ # @return [InstallParams, nil] The default install params for when the application's is installed to a user.
171
+ def user_integration_type
172
+ @integration_types[1]
173
+ end
174
+
175
+ # Get the integration types config for when the application has been installed in a server.
176
+ # @return [InstallParams, nil] The defaults install params for when the application's is installed in a server.
177
+ def server_integration_type
178
+ @integration_types[0]
179
+ end
180
+
181
+ # Modify the properties of the application.
182
+ # @param icon [#read, nil] The new icon for the application. Must be a file-like object that response to `#read`.
183
+ # @param cover_image [#read, nil] The new rich presence cover image for the application. Must be a file-like object that response to `#read`.
184
+ # @param flags [Integer, Symbol, Array<Symbol, Integer>] The new flags to set for the application. Only limited intent flags can be updated.
185
+ # @param tags [Array<String, Symbol>, nil] The new tags representing the application's traits.
186
+ # @param description [String, nil] The new description of the application.
187
+ # @param custom_install_url [String, nil] The new default custom authorization URL for the application.
188
+ # @param webhook_events_url [String, nil] The new URL the application will use to receive webhook events via HTTP.
189
+ # @param webhook_events_status [Integer] The new status of the application's webhook events.
190
+ # @param webhook_event_types [Array<String, Symbol>, nil] The new types of webhook events that the application wishes to receive.
191
+ # @param interactions_endpoint_url [String, nil] The new URL the application will use to receive INTERACTION_CREATE events via HTTP.
192
+ # @param install_scopes [Array<String, Symbol>] The new default scopes to add the application to a server with.
193
+ # @param install_permissions [Permissions, Integer, String] The new default permissions to add the application to a server with.
194
+ # @param role_connections_verification_url [String, nil] The new role connections verification URL for the application.
195
+ # @param add_flags [Integer, Symbol, Array<Symbol, Integer>] The limited intent flags to add to the application.
196
+ # @param remove_flags [Integer, Symbol, Array<Symbol, Integer>] The limited intent flags to remove from the application.
197
+ # @param integration_types [#to_h] The new integration types configuration for the application.
198
+ # @note When using the `add_flags:` and `remove_flags:` parameters, The flags are removed first, and then added.
199
+ # @return [nil]
200
+ def modify(
201
+ icon: :undef, cover_image: :undef, flags: :undef, tags: :undef, description: :undef,
202
+ custom_install_url: :undef, webhook_events_url: :undef, webhook_events_status: :undef,
203
+ webhook_event_types: :undef, interactions_endpoint_url: :undef, install_scopes: :undef,
204
+ install_permissions: :undef, role_connections_verification_url: :undef, add_flags: :undef,
205
+ remove_flags: :undef, integration_types: :undef
206
+ )
207
+ data = {
208
+ icon: icon.respond_to?(:read) ? OnyxCord.encode64(icon) : icon,
209
+ cover_image: cover_image.respond_to?(:read) ? OnyxCord.encode64(cover_image) : cover_image,
210
+ flags: flags == :undef ? flags : [*flags].map { |bit| FLAGS[bit] || bit.to_i }.reduce(&:|),
211
+ tags: tags,
212
+ description: description,
213
+ custom_install_url: custom_install_url,
214
+ event_webhooks_url: webhook_events_url || '',
215
+ event_webhooks_status: webhook_events_status,
216
+ event_webhooks_types: webhook_event_types || [],
217
+ interactions_endpoint_url: interactions_endpoint_url,
218
+ role_connections_verification_url: role_connections_verification_url,
219
+ integration_types_config: integration_types == :undef ? integration_types : integration_types&.to_h
220
+ }
221
+
222
+ ((data[:install_params] ||= @install_params.to_h)[:scopes] = install_scopes) if install_scopes != :undef
223
+
224
+ if install_permissions != :undef
225
+ install_permissions = install_permissions.bits if install_permissions.respond_to?(:bits)
226
+ (data[:install_params] ||= @install_params.to_h)[:permissions] = install_permissions.to_s
227
+ end
228
+
229
+ if add_flags != :undef || remove_flags != :undef
230
+ raise ArgumentError, "'add_flags' and 'remove_flags' are mutually exclusive with 'flags'" if flags != :undef
231
+
232
+ to_flags = lambda do |value|
233
+ [*(value == :undef ? 0 : value)].map { |bit| FLAGS[bit] || bit.to_i }.reduce(&:|)
234
+ end
235
+
236
+ data[:flags] = ((@flags & ~to_flags.call(remove_flags)) | to_flags.call(add_flags))
237
+ end
238
+
239
+ update_data(JSON.parse(API::Application.update_current_application(@bot.token, **data)))
240
+ nil
241
+ end
242
+
243
+ # @!method automod_rule_badge?
244
+ # @return [true, false] whether or not the application has at least 100 automod rules across all of its servers.
245
+ # @!method approved_presence_intent?
246
+ # @return [true, false] whether or not the application is in less than 100 servers and has access to the server presences intent.
247
+ # @!method limited_presence_intent?
248
+ # @return [true, false] whether or not the application is in more than 100 servers and has access to the server presences intent.
249
+ # @!method approved_server_members_intent?
250
+ # @return [true, false] whether or not the application is in more than 100 servers and has access to the server members intent.
251
+ # @!method limited_server_members_intent?
252
+ # @return [true, false] whether or not the application is in less than 100 servers and has access to the server members intent.
253
+ # @!method pending_server_limit_verification?
254
+ # @return [true, false] whether or not the application has underwent unusual growth that is preventing it from being verified.
255
+ # @!method embedded?
256
+ # @return [true, false] whether or not the application is embedded within the Discord application (currently unavailable publicly).
257
+ # @!method approved_message_content_intent?
258
+ # @return [true, false] whether or not the application is in more than 100 servers and has access to the message content intent.
259
+ # @!method limited_message_content_intent?
260
+ # @return [true, false] whether or not the application is in less than 100 servers and has access to the message content intent.
261
+ # @!method application_command_badge?
262
+ # @return [true, false] whether or not the application has registered at least one global application command.
263
+ FLAGS.each do |name, value|
264
+ define_method("#{name}?") do
265
+ @flags.anybits?(value)
266
+ end
267
+ end
268
+
269
+ # Check if the application has the presence intent toggled on its dashboard.
270
+ # @return [true, false] Whether or not the application has access to the presence intent.
271
+ def presence_intent?
272
+ approved_presence_intent? || limited_presence_intent?
273
+ end
274
+
275
+ # Check if the application has the server members intent toggled on its dashboard.
276
+ # @return [true, false] Whether or not the application has access to the server members intent.
277
+ def server_members_intent?
278
+ approved_server_members_intent? || limited_server_members_intent?
279
+ end
280
+
281
+ # Check if the application has the message content intent toggled on its dashboard.
282
+ # @return [true, false] Whether or not the application has access to the message content intent.
283
+ def message_content_intent?
284
+ approved_message_content_intent? || limited_message_content_intent?
285
+ end
286
+
287
+ # @!visibility private
288
+ def inspect
289
+ "<Application name=#{@name} id=#{@id} public=#{@public} tags=#{@tags} flags=#{@flags}>"
290
+ end
291
+
292
+ private
293
+
294
+ # @!visibility private
295
+ def update_data(new_data)
296
+ @name = new_data['name']
297
+ @description = new_data['description']
298
+ @icon_id = new_data['icon']
299
+ @rpc_origins = new_data['rpc_origins'] || []
300
+ @flags = new_data['flags'] || 0
301
+ @owner = new_data['owner'] ? @bot.ensure_user(new_data['owner']) : nil
302
+
303
+ @public = new_data['bot_public']
304
+ @requires_code_grant = new_data['bot_require_code_grant']
305
+ @terms_of_service_url = new_data['terms_of_service_url']
306
+ @privacy_policy_url = new_data['privacy_policy_url']
307
+ @verify_key = new_data['verify_key']
308
+ @team = new_data['team'] ? Team.new(new_data['team'], @bot) : nil
309
+
310
+ @server_id = new_data['guild_id']&.to_i
311
+ @cover_image_id = new_data['cover_image']
312
+ @slug = new_data['slug']
313
+ @primary_sku_id = new_data['primary_sku_id']&.to_i
314
+ @server_install_count = new_data['approximate_guild_count'] || 0
315
+ @user_install_count = new_data['approximate_user_install_count'] || 0
316
+ @user_authorization_count = new_data['approximate_user_authorization_count'] || 0
317
+
318
+ @redirect_uris = new_data['redirect_uris'] || []
319
+ @interactions_endpoint_url = new_data['interactions_endpoint_url']
320
+ @role_connections_verification_url = new_data['role_connections_verification_url']
321
+ @webhook_events_url = new_data['event_webhooks_url']
322
+ @webhook_events_status = new_data['event_webhooks_status'] || 1
323
+
324
+ @webhook_event_types = new_data['event_webhooks_types'] || []
325
+ @tags = new_data['tags'] || []
326
+ @install_params = InstallParams.new(new_data['install_params'] || {}, @bot)
327
+ @custom_install_url = new_data['custom_install_url']
328
+
329
+ @integration_types = (new_data['integration_types_config'] || {}).to_h do |key, value|
330
+ [key.to_i, InstallParams.new(value['oauth2_install_params'] || {}, @bot)]
331
+ end
332
+ end
333
+
334
+ # @!visibility private
335
+ def collect_integration_types(integration_types)
336
+ integration_types.each_with_object({}) do |(key, value), result|
337
+ result[key.to_s] = value.to_h.any? ? { oauth2_install_params: value.to_h } : {}
338
+ end
339
+ end
340
+ end
341
+ end