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,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # API calls for User object
4
- module OnyxCord::API::User
4
+ module OnyxCord::REST::User
5
5
  module_function
6
6
 
7
7
  # Get user data
8
8
  # https://discord.com/developers/docs/resources/user#get-user
9
9
  def resolve(token, user_id)
10
- OnyxCord::API.request(
10
+ OnyxCord::REST.request(
11
11
  :users_uid,
12
12
  nil,
13
13
  :get,
14
- "#{OnyxCord::API.api_base}/users/#{user_id}",
14
+ "#{OnyxCord::REST.api_base}/users/#{user_id}",
15
15
  Authorization: token
16
16
  )
17
17
  end
@@ -19,23 +19,23 @@ module OnyxCord::API::User
19
19
  # Get profile data
20
20
  # https://discord.com/developers/docs/resources/user#get-current-user
21
21
  def profile(token)
22
- OnyxCord::API.request(
22
+ OnyxCord::REST.request(
23
23
  :users_me,
24
24
  nil,
25
25
  :get,
26
- "#{OnyxCord::API.api_base}/users/@me",
26
+ "#{OnyxCord::REST.api_base}/users/@me",
27
27
  Authorization: token
28
28
  )
29
29
  end
30
30
 
31
- # @deprecated Please use {OnyxCord::API::Server.update_current_member} instead.
31
+ # @deprecated Please use {OnyxCord::REST::Server.update_current_member} instead.
32
32
  # https://discord.com/developers/docs/resources/user#modify-current-user-nick
33
33
  def change_own_nickname(token, server_id, nick, reason = nil)
34
- OnyxCord::API.request(
34
+ OnyxCord::REST.request(
35
35
  :guilds_sid_members_me_nick,
36
36
  server_id, # This is technically a guild endpoint
37
37
  :patch,
38
- "#{OnyxCord::API.api_base}/guilds/#{server_id}/members/@me/nick",
38
+ "#{OnyxCord::REST.api_base}/guilds/#{server_id}/members/@me/nick",
39
39
  { nick: nick }.to_json,
40
40
  Authorization: token,
41
41
  content_type: :json,
@@ -52,11 +52,11 @@ module OnyxCord::API::User
52
52
  # Update the properties of the user for the current bot.
53
53
  # https://discord.com/developers/docs/resources/user#modify-current-user
54
54
  def update_current_user(token, username = :undef, avatar = :undef, banner = :undef)
55
- OnyxCord::API.request(
55
+ OnyxCord::REST.request(
56
56
  :users_me,
57
57
  nil,
58
58
  :patch,
59
- "#{OnyxCord::API.api_base}/users/@me",
59
+ "#{OnyxCord::REST.api_base}/users/@me",
60
60
  { username: username, avatar: avatar, banner: banner }.reject { |_, value| value == :undef }.to_json,
61
61
  Authorization: token,
62
62
  content_type: :json
@@ -66,11 +66,11 @@ module OnyxCord::API::User
66
66
  # Get the servers a user is connected to
67
67
  # https://discord.com/developers/docs/resources/user#get-current-user-guilds
68
68
  def servers(token)
69
- OnyxCord::API.request(
69
+ OnyxCord::REST.request(
70
70
  :users_me_guilds,
71
71
  nil,
72
72
  :get,
73
- "#{OnyxCord::API.api_base}/users/@me/guilds",
73
+ "#{OnyxCord::REST.api_base}/users/@me/guilds",
74
74
  Authorization: token
75
75
  )
76
76
  end
@@ -78,11 +78,11 @@ module OnyxCord::API::User
78
78
  # Leave a server
79
79
  # https://discord.com/developers/docs/resources/user#leave-guild
80
80
  def leave_server(token, server_id)
81
- OnyxCord::API.request(
81
+ OnyxCord::REST.request(
82
82
  :users_me_guilds_sid,
83
83
  nil,
84
84
  :delete,
85
- "#{OnyxCord::API.api_base}/users/@me/guilds/#{server_id}",
85
+ "#{OnyxCord::REST.api_base}/users/@me/guilds/#{server_id}",
86
86
  Authorization: token
87
87
  )
88
88
  end
@@ -90,11 +90,11 @@ module OnyxCord::API::User
90
90
  # Get the DMs for the current user
91
91
  # https://discord.com/developers/docs/resources/user#get-user-dms
92
92
  def user_dms(token)
93
- OnyxCord::API.request(
93
+ OnyxCord::REST.request(
94
94
  :users_me_channels,
95
95
  nil,
96
96
  :get,
97
- "#{OnyxCord::API.api_base}/users/@me/channels",
97
+ "#{OnyxCord::REST.api_base}/users/@me/channels",
98
98
  Authorization: token
99
99
  )
100
100
  end
@@ -102,11 +102,11 @@ module OnyxCord::API::User
102
102
  # Create a DM to another user
103
103
  # https://discord.com/developers/docs/resources/user#create-dm
104
104
  def create_pm(token, recipient_id)
105
- OnyxCord::API.request(
105
+ OnyxCord::REST.request(
106
106
  :users_me_channels,
107
107
  nil,
108
108
  :post,
109
- "#{OnyxCord::API.api_base}/users/@me/channels",
109
+ "#{OnyxCord::REST.api_base}/users/@me/channels",
110
110
  { recipient_id: recipient_id }.to_json,
111
111
  Authorization: token,
112
112
  content_type: :json
@@ -116,11 +116,11 @@ module OnyxCord::API::User
116
116
  # Get information about a user's connections
117
117
  # https://discord.com/developers/docs/resources/user#get-users-connections
118
118
  def connections(token)
119
- OnyxCord::API.request(
119
+ OnyxCord::REST.request(
120
120
  :users_me_connections,
121
121
  nil,
122
122
  :get,
123
- "#{OnyxCord::API.api_base}/users/@me/connections",
123
+ "#{OnyxCord::REST.api_base}/users/@me/connections",
124
124
  Authorization: token
125
125
  )
126
126
  end
@@ -133,7 +133,7 @@ module OnyxCord::API::User
133
133
  else
134
134
  (discrim_id.to_i >> 22) % 5
135
135
  end
136
- "#{OnyxCord::API.cdn_url}/embed/avatars/#{index}.png"
136
+ "#{OnyxCord::REST.cdn_url}/embed/avatars/#{index}.png"
137
137
  end
138
138
 
139
139
  # Make an avatar URL from the user and avatar IDs
@@ -143,7 +143,7 @@ module OnyxCord::API::User
143
143
  else
144
144
  'webp'
145
145
  end
146
- "#{OnyxCord::API.cdn_url}/avatars/#{user_id}/#{avatar_id}.#{format}"
146
+ "#{OnyxCord::REST.cdn_url}/avatars/#{user_id}/#{avatar_id}.#{format}"
147
147
  end
148
148
 
149
149
  # Make a banner URL from the user and banner IDs
@@ -153,6 +153,6 @@ module OnyxCord::API::User
153
153
  else
154
154
  'png'
155
155
  end
156
- "#{OnyxCord::API.cdn_url}/banners/#{user_id}/#{banner_id}.#{format}"
156
+ "#{OnyxCord::REST.cdn_url}/banners/#{user_id}/#{banner_id}.#{format}"
157
157
  end
158
158
  end
@@ -1,36 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'onyxcord/message_components'
3
+ require 'onyxcord/internal/message_payload'
4
4
 
5
5
  # API calls for Webhook object
6
- module OnyxCord::API::Webhook
6
+ module OnyxCord::REST::Webhook
7
7
  module_function
8
8
 
9
9
  # Build attachment metadata payload for multipart uploads.
10
10
  # Returns an array of { id:, filename: } hashes.
11
11
  def attachment_payload(attachments)
12
- Array(attachments).map.with_index do |attachment, index|
13
- { id: index, filename: File.basename(attachment.path) }
14
- end
12
+ OnyxCord::MessagePayload.attachment_payload(attachments)
15
13
  end
16
14
 
17
15
  # Build multipart body with named file fields and JSON payload.
18
16
  def multipart_body(body, attachments)
19
- files = Array(attachments).map.with_index.to_h do |attachment, index|
20
- ["files[#{index}]", attachment]
21
- end
22
-
23
- { **files, payload_json: body.to_json }
17
+ OnyxCord::MessagePayload.multipart_body(body, attachments)
24
18
  end
25
19
 
26
20
  # Get a webhook
27
21
  # https://discord.com/developers/docs/resources/webhook#get-webhook
28
22
  def webhook(token, webhook_id)
29
- OnyxCord::API.request(
23
+ OnyxCord::REST.request(
30
24
  :webhooks_wid,
31
25
  nil,
32
26
  :get,
33
- "#{OnyxCord::API.api_base}/webhooks/#{webhook_id}",
27
+ "#{OnyxCord::REST.api_base}/webhooks/#{webhook_id}",
34
28
  Authorization: token
35
29
  )
36
30
  end
@@ -38,20 +32,23 @@ module OnyxCord::API::Webhook
38
32
  # Get a webhook via webhook token
39
33
  # https://discord.com/developers/docs/resources/webhook#get-webhook-with-token
40
34
  def token_webhook(webhook_token, webhook_id)
41
- OnyxCord::API.request(
35
+ OnyxCord::REST.request(
42
36
  :webhooks_wid,
43
37
  nil,
44
38
  :get,
45
- "#{OnyxCord::API.api_base}/webhooks/#{webhook_id}/#{webhook_token}"
39
+ "#{OnyxCord::REST.api_base}/webhooks/#{webhook_id}/#{webhook_token}"
46
40
  )
47
41
  end
48
42
 
49
43
  # Execute a webhook via token.
50
44
  # https://discord.com/developers/docs/resources/webhook#execute-webhook
51
45
  def token_execute_webhook(webhook_token, webhook_id, wait = false, content = nil, username = nil, avatar_url = nil, tts = nil, file = nil, embeds = nil, allowed_mentions = nil, flags = nil, components = nil, attachments = nil, poll = nil)
46
+ raise ArgumentError, 'cannot mix file and attachments' if file && attachments
47
+
52
48
  components = OnyxCord::MessageComponents.payload(components) unless components.nil?
53
49
  flags = OnyxCord::MessageComponents.apply_v2_flag(flags, components)
54
- body = { content: content, username: username, avatar_url: avatar_url, tts: tts, embeds: embeds&.map(&:to_hash), allowed_mentions: allowed_mentions, flags: flags, components: components, attachments: attachments ? attachment_payload(attachments) : nil, poll: poll }.compact
50
+ OnyxCord::MessagePayload.validate!(content: content, embeds: embeds, components: components, flags: flags, attachments: attachments, poll: poll)
51
+ body = { content: content, username: username, avatar_url: avatar_url, tts: tts == true ? true : nil, embeds: embeds&.map(&:to_hash), allowed_mentions: allowed_mentions, flags: flags, components: components&.any? ? components : nil, attachments: attachments ? attachment_payload(attachments) : nil, poll: poll }.compact
55
52
 
56
53
  body = if file
57
54
  { file: file, payload_json: body.to_json }
@@ -65,11 +62,11 @@ module OnyxCord::API::Webhook
65
62
  with_components = components&.any? || nil
66
63
  query = URI.encode_www_form({ wait: wait, with_components: with_components }.compact)
67
64
 
68
- OnyxCord::API.request(
65
+ OnyxCord::REST.request(
69
66
  :webhooks_wid,
70
67
  webhook_id,
71
68
  :post,
72
- "#{OnyxCord::API.api_base}/webhooks/#{webhook_id}/#{webhook_token}?#{query}",
69
+ "#{OnyxCord::REST.api_base}/webhooks/#{webhook_id}/#{webhook_token}?#{query}",
73
70
  body,
74
71
  headers
75
72
  )
@@ -78,11 +75,11 @@ module OnyxCord::API::Webhook
78
75
  # Update a webhook
79
76
  # https://discord.com/developers/docs/resources/webhook#modify-webhook
80
77
  def update_webhook(token, webhook_id, data, reason = nil)
81
- OnyxCord::API.request(
78
+ OnyxCord::REST.request(
82
79
  :webhooks_wid,
83
80
  webhook_id,
84
81
  :patch,
85
- "#{OnyxCord::API.api_base}/webhooks/#{webhook_id}",
82
+ "#{OnyxCord::REST.api_base}/webhooks/#{webhook_id}",
86
83
  data.to_json,
87
84
  Authorization: token,
88
85
  content_type: :json,
@@ -93,11 +90,11 @@ module OnyxCord::API::Webhook
93
90
  # Update a webhook via webhook token
94
91
  # https://discord.com/developers/docs/resources/webhook#modify-webhook-with-token
95
92
  def token_update_webhook(webhook_token, webhook_id, data, reason = nil)
96
- OnyxCord::API.request(
93
+ OnyxCord::REST.request(
97
94
  :webhooks_wid,
98
95
  webhook_id,
99
96
  :patch,
100
- "#{OnyxCord::API.api_base}/webhooks/#{webhook_id}/#{webhook_token}",
97
+ "#{OnyxCord::REST.api_base}/webhooks/#{webhook_id}/#{webhook_token}",
101
98
  data.to_json,
102
99
  content_type: :json,
103
100
  'X-Audit-Log-Reason': reason
@@ -107,11 +104,11 @@ module OnyxCord::API::Webhook
107
104
  # Deletes a webhook
108
105
  # https://discord.com/developers/docs/resources/webhook#delete-webhook
109
106
  def delete_webhook(token, webhook_id, reason = nil)
110
- OnyxCord::API.request(
107
+ OnyxCord::REST.request(
111
108
  :webhooks_wid,
112
109
  webhook_id,
113
110
  :delete,
114
- "#{OnyxCord::API.api_base}/webhooks/#{webhook_id}",
111
+ "#{OnyxCord::REST.api_base}/webhooks/#{webhook_id}",
115
112
  Authorization: token,
116
113
  'X-Audit-Log-Reason': reason
117
114
  )
@@ -120,11 +117,11 @@ module OnyxCord::API::Webhook
120
117
  # Deletes a webhook via webhook token
121
118
  # https://discord.com/developers/docs/resources/webhook#delete-webhook-with-token
122
119
  def token_delete_webhook(webhook_token, webhook_id, reason = nil)
123
- OnyxCord::API.request(
120
+ OnyxCord::REST.request(
124
121
  :webhooks_wid,
125
122
  webhook_id,
126
123
  :delete,
127
- "#{OnyxCord::API.api_base}/webhooks/#{webhook_id}/#{webhook_token}",
124
+ "#{OnyxCord::REST.api_base}/webhooks/#{webhook_id}/#{webhook_token}",
128
125
  'X-Audit-Log-Reason': reason
129
126
  )
130
127
  end
@@ -132,11 +129,11 @@ module OnyxCord::API::Webhook
132
129
  # Get a message that was created by the webhook corresponding to the provided token.
133
130
  # https://discord.com/developers/docs/resources/webhook#get-webhook-message
134
131
  def token_get_message(webhook_token, webhook_id, message_id)
135
- OnyxCord::API.request(
132
+ OnyxCord::REST.request(
136
133
  :webhooks_wid_messages_mid,
137
134
  webhook_id,
138
135
  :get,
139
- "#{OnyxCord::API.api_base}/webhooks/#{webhook_id}/#{webhook_token}/messages/#{message_id}"
136
+ "#{OnyxCord::REST.api_base}/webhooks/#{webhook_id}/#{webhook_token}/messages/#{message_id}"
140
137
  )
141
138
  end
142
139
 
@@ -145,7 +142,8 @@ module OnyxCord::API::Webhook
145
142
  def token_edit_message(webhook_token, webhook_id, message_id, content = nil, embeds = nil, allowed_mentions = nil, components = nil, attachments = nil, flags = nil, poll = nil)
146
143
  components = OnyxCord::MessageComponents.payload(components) unless components.nil?
147
144
  flags = OnyxCord::MessageComponents.apply_v2_flag(flags, components)
148
- body = { content: content, embeds: embeds, allowed_mentions: allowed_mentions, components: components, attachments: attachments ? attachment_payload(attachments) : nil, flags: flags, poll: poll }.compact
145
+ OnyxCord::MessagePayload.validate!(content: content, embeds: embeds, components: components, flags: flags, attachments: attachments, poll: poll)
146
+ body = OnyxCord::MessagePayload.edit_body(content, embeds).merge({ allowed_mentions: allowed_mentions, components: components, attachments: attachments ? attachment_payload(attachments) : nil, flags: flags, poll: poll }.compact)
149
147
 
150
148
  body = if attachments
151
149
  multipart_body(body, attachments)
@@ -155,11 +153,11 @@ module OnyxCord::API::Webhook
155
153
 
156
154
  headers = { content_type: :json } unless attachments
157
155
 
158
- OnyxCord::API.request(
156
+ OnyxCord::REST.request(
159
157
  :webhooks_wid_messages,
160
158
  webhook_id,
161
159
  :patch,
162
- "#{OnyxCord::API.api_base}/webhooks/#{webhook_id}/#{webhook_token}/messages/#{message_id}",
160
+ "#{OnyxCord::REST.api_base}/webhooks/#{webhook_id}/#{webhook_token}/messages/#{message_id}",
163
161
  body,
164
162
  headers
165
163
  )
@@ -168,11 +166,11 @@ module OnyxCord::API::Webhook
168
166
  # Delete a webhook message via webhook token.
169
167
  # https://discord.com/developers/docs/resources/webhook#delete-webhook-message
170
168
  def token_delete_message(webhook_token, webhook_id, message_id)
171
- OnyxCord::API.request(
169
+ OnyxCord::REST.request(
172
170
  :webhooks_wid_messages,
173
171
  webhook_id,
174
172
  :delete,
175
- "#{OnyxCord::API.api_base}/webhooks/#{webhook_id}/#{webhook_token}/messages/#{message_id}"
173
+ "#{OnyxCord::REST.api_base}/webhooks/#{webhook_id}/#{webhook_token}/messages/#{message_id}"
176
174
  )
177
175
  end
178
176
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'onyxcord/id_object'
3
+ require 'onyxcord/utils/id_object'
4
4
 
5
5
  module OnyxCord
6
6
  # Builder class for `allowed_mentions` when sending messages.
@@ -30,6 +30,14 @@ module OnyxCord
30
30
  @replied_user = replied_user
31
31
  end
32
32
 
33
+ def self.none
34
+ new(parse: [], users: [], roles: [], replied_user: false)
35
+ end
36
+
37
+ def self.all
38
+ new(parse: %w[users roles everyone], replied_user: true)
39
+ end
40
+
33
41
  # @!visibility private
34
42
  def to_hash
35
43
  {
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OnyxCord
4
+ # A timestamp referenced in a message via markdown.
5
+ class TimestampMarkdown
6
+ # Mapping of timestamp styles.
7
+ STYLES = {
8
+ short_time: 't', # 16:20
9
+ long_time: 'T', # 16:20:30
10
+ short_date: 'd', # 20/04/2021
11
+ long_date: 'D', # 20 April 2021
12
+ short_datetime: 'f', # 20 April 2021 16:20
13
+ long_datetime: 'F', # Tuesday, 20 April 2021 16:20
14
+ relative: 'R', # 2 months ago
15
+ simple_datetime: 's', # 20/04/2021, 16:20
16
+ medium_datetime: 'S' # 20/04/2021, 16:20:30
17
+ }.freeze
18
+
19
+ # @return [Time] the time that the timestamp is referencing.
20
+ attr_reader :time
21
+
22
+ # @!visibility private
23
+ def initialize(time, style)
24
+ @time = time
25
+ @style = style
26
+ end
27
+
28
+ # Get the specifier used to determine the style of the timestamp.
29
+ # @return [String] the formatting specifier used to display the timestamp.
30
+ def style
31
+ @style || 'f'
32
+ end
33
+
34
+ # Get a string that will allow you to display the time in the Discord client.
35
+ # @return [String] The timestamp serialized as a string for the Discord client.
36
+ def to_s
37
+ OnyxCord.timestamp(@time, @style)
38
+ end
39
+
40
+ # @!visibility private
41
+ def inspect
42
+ "<TimestampMarkdown time=#{@time.to_i} style=\"#{style}\">"
43
+ end
44
+
45
+ # @!method short_time?
46
+ # @return [true, false] whether or not the timestamp is displayed in a format such as `16:20`.
47
+ # @!method long_time?
48
+ # @return [true, false] whether or not the timestamp is displayed in a format such as `16:20:30`.
49
+ # @!method short_date?
50
+ # @return [true, false] whether or not the timestamp is displayed in a format such as `20/04/2021`.
51
+ # @!method long_date?
52
+ # @return [true, false] whether or not the timestamp is displayed in a format such as `20 April 2021`.
53
+ # @!method short_datetime?
54
+ # @return [true, false] whether or not the timestamp is displayed in a format such as `20 April 2021 16:20`.
55
+ # @!method long_datetime?
56
+ # @return [true, false] whether or not the timestamp is displayed in a format such as `Tuesday, 20 April 2021 16:20`.
57
+ # @!method relative?
58
+ # @return [true, false] whether or not the timestamp is displayed in a format such as `2 months ago`.
59
+ # @!method simple_datetime?
60
+ # @return [true, false] whether or not the timestamp is displayed in a format such as `20/04/2021, 16:20`.
61
+ # @!method medium_datetime?
62
+ # @return [true, false] whether or not the timestamp is displayed in a format such as ` 20/04/2021, 16:20:30`.
63
+ STYLES.each do |name, value|
64
+ define_method("#{name}?") do
65
+ style == value
66
+ end
67
+ end
68
+ end
69
+ end
@@ -3,7 +3,7 @@
3
3
  require 'onyxcord/voice/encoder'
4
4
  require 'onyxcord/voice/network'
5
5
  require 'onyxcord/voice/timer'
6
- require 'onyxcord/logger'
6
+ require 'onyxcord/core/logger'
7
7
  require 'ffi'
8
8
 
9
9
  # Voice support
@@ -20,9 +20,9 @@ module OnyxCord::Voice
20
20
  #
21
21
  # onyxcord does latency adjustments every now and then to improve playback quality. I made sure to put useful
22
22
  # defaults for the adjustment parameters, but if the sound is patchy or too fast (or the speed varies a lot) you
23
- # should check the parameters and adjust them to your connection: {VoiceBot#adjust_interval},
24
- # {VoiceBot#adjust_offset}, and {VoiceBot#adjust_average}.
25
- class VoiceBot
23
+ # should check the parameters and adjust them to your connection: {Client#adjust_interval},
24
+ # {Client#adjust_offset}, and {Client#adjust_average}.
25
+ class Client
26
26
  # @return [Channel] the current voice channel
27
27
  attr_reader :channel
28
28
 
@@ -18,7 +18,7 @@ module OnyxCord::Voice
18
18
  # @return [true, false] whether avconv should be used instead of ffmpeg.
19
19
  attr_accessor :use_avconv
20
20
 
21
- # @see VoiceBot#filter_volume=
21
+ # @see Client#filter_volume=
22
22
  # @return [Integer] the volume used as a filter to ffmpeg/avconv.
23
23
  attr_accessor :filter_volume
24
24
 
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OnyxCord::Voice
4
+ class VoiceUDP
5
+ # @return [true, false] whether or not UDP communications are encrypted.
6
+ # @deprecated Discord no longer supports unencrypted voice communication.
7
+ attr_accessor :encrypted
8
+ alias_method :encrypted?, :encrypted
9
+
10
+ # Sets the secret key used for encryption
11
+ attr_writer :secret_key
12
+
13
+ # The UDP encryption mode
14
+ attr_reader :mode
15
+
16
+ # @!visibility private
17
+ attr_writer :mode
18
+
19
+ # Creates a new UDP connection. Only creates a socket as the discovery reply may come before the data is
20
+ # initialized.
21
+ def initialize
22
+ @socket = UDPSocket.new
23
+ @encrypted = true
24
+ end
25
+
26
+ # Initializes the UDP socket with data obtained from opcode 2.
27
+ # @param ip [String] The IP address to connect to.
28
+ # @param port [Integer] The port to connect to.
29
+ # @param ssrc [Integer] The Super Secret Relay Code (SSRC). Discord uses this to identify different voice users
30
+ # on the same endpoint.
31
+ def connect(ip, port, ssrc)
32
+ @ip = ip
33
+ @port = port
34
+ @ssrc = ssrc
35
+ end
36
+
37
+ # Waits for a UDP discovery reply, and returns the sent data.
38
+ # @return [Array(String, Integer)] the IP and port received from the discovery reply.
39
+ def receive_discovery_reply
40
+ # Wait for a UDP message
41
+ message = @socket.recv(74)
42
+ ip = message[8..-3].delete("\0")
43
+ port = message[-2..].unpack1('n')
44
+ [ip, port]
45
+ end
46
+
47
+ # Makes an audio packet from a buffer and sends it to Discord.
48
+ # @param buf [String] The audio data to send, must be exactly one Opus frame
49
+ # @param sequence [Integer] The packet sequence number, incremented by one for subsequent packets
50
+ # @param time [Integer] When this packet should be played back, in no particular unit (essentially just the
51
+ # sequence number multiplied by 960)
52
+ def send_audio(buf, sequence, time)
53
+ # Header of the audio packet
54
+ header = generate_header(sequence, time)
55
+
56
+ nonce = generate_nonce
57
+ buf = encrypt_audio(buf, header, nonce)
58
+ data = header + buf + nonce.byteslice(0, 4)
59
+
60
+ send_packet(data)
61
+ end
62
+
63
+ # Sends the UDP discovery packet with the internally stored SSRC. Discord will send a reply afterwards which can
64
+ # be received using {#receive_discovery_reply}
65
+ def send_discovery
66
+ # Create empty packet
67
+ discovery_packet = ''
68
+
69
+ # Add Type request (0x1 = request, 0x2 = response)
70
+ discovery_packet += [0x1].pack('n')
71
+
72
+ # Add Length (excluding Type and itself = 70)
73
+ discovery_packet += [70].pack('n')
74
+
75
+ # Add SSRC
76
+ discovery_packet += [@ssrc].pack('N')
77
+
78
+ # Add 66 zeroes so the packet is 74 bytes long
79
+ discovery_packet += "\0" * 66
80
+
81
+ send_packet(discovery_packet)
82
+ end
83
+
84
+ def close
85
+ @socket.close unless @socket.closed?
86
+ end
87
+
88
+ private
89
+
90
+ # Encrypts audio data using libsodium
91
+ # @param buf [String] The encoded audio data to be encrypted
92
+ # @param header [String] The RTP header of the packet, used as associated data
93
+ # @param nonce [String] The nonce to be used to encrypt the data
94
+ # @return [String] the audio data, encrypted
95
+ def encrypt_audio(buf, header, nonce)
96
+ raise 'No secret key found, despite encryption being enabled!' unless @secret_key
97
+
98
+ case @mode
99
+ when 'aead_xchacha20_poly1305_rtpsize'
100
+ OnyxCord::Voice::XChaCha20AEAD.encrypt(buf, header, nonce, @secret_key)
101
+ else
102
+ raise "`#{@mode}' is not a supported encryption mode"
103
+ end
104
+ end
105
+
106
+ def send_packet(packet)
107
+ @socket.send(packet, 0, @ip, @port)
108
+ end
109
+
110
+ # @return [String]
111
+ def generate_nonce
112
+ case @mode
113
+ when 'aead_xchacha20_poly1305_rtpsize'
114
+ case @incremental_nonce
115
+ when nil, 0xff_ff_ff_ff
116
+ @incremental_nonce = 0
117
+ else
118
+ @incremental_nonce += 1
119
+ end
120
+ [@incremental_nonce].pack('N').ljust(24, "\0")
121
+ else
122
+ raise "`#{@mode}' is not a supported encryption mode"
123
+ end
124
+ end
125
+
126
+ # @return [String]
127
+ def generate_header(sequence, time)
128
+ [0x80, 0x78, sequence, time, @ssrc].pack('CCnNN')
129
+ end
130
+ end
131
+
132
+ # Represents a websocket client connection to the voice server. The websocket connection (sometimes called vWS) is
133
+ # used to manage general data about the connection, such as sending the speaking packet, which determines the green
134
+ # circle around users on Discord, and obtaining UDP connection info.
135
+ end