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
data/README.md ADDED
@@ -0,0 +1,305 @@
1
+ # OnyxCord
2
+
3
+ [![Gem](https://img.shields.io/gem/v/onyxcord.svg)](https://rubygems.org/gems/onyxcord)
4
+ [![Gem](https://img.shields.io/gem/dt/onyxcord.svg)](https://rubygems.org/gems/onyxcord)
5
+
6
+ OnyxCord é uma biblioteca Ruby para criar bots, integrações, webhooks e experiências interativas no Discord.
7
+
8
+ O projeto foi feito com base no `discordrb`, respeitando a base que tornou bots em Ruby simples de começar, mas trazendo uma direção nova para a comunidade: core mais leve, modo raw-first, suporte aos novos componentes de modal e suporte aos Components V2 do Discord.
9
+
10
+ A ideia é simples:
11
+
12
+ ```txt
13
+ Simples para começar, profundo para controlar.
14
+ ```
15
+
16
+ ## Destaques
17
+
18
+ - API Ruby amigável para bots do Discord.
19
+ - Eventos tradicionais com objetos para quem quer produtividade.
20
+ - Eventos raw para quem quer performance e menos alocação.
21
+ - Components V2 com `Text Display`, `Container`, `Section`, `Media Gallery`, `File`, `Separator` e `Thumbnail`.
22
+ - Novos componentes de modal, incluindo `Label`, `Text Display`, selects em modal, upload, radio group e checkbox group.
23
+ - Webhooks com embeds, arquivos e componentes.
24
+ - Rate limiter e executor de eventos preparados para o core moderno do OnyxCord.
25
+
26
+ ## Instalação
27
+
28
+ Com Bundler:
29
+
30
+ ```ruby
31
+ gem 'onyxcord'
32
+ ```
33
+
34
+ Depois:
35
+
36
+ ```sh
37
+ bundle install
38
+ ```
39
+
40
+ Ou direto pelo RubyGems:
41
+
42
+ ```sh
43
+ gem install onyxcord
44
+ ```
45
+
46
+ No Windows, use uma instalação Ruby com DevKit para compilar dependências nativas quando necessário.
47
+
48
+ ## Primeiro bot
49
+
50
+ Crie um arquivo `bot.rb`:
51
+
52
+ ```ruby
53
+ require 'onyxcord'
54
+
55
+ bot = OnyxCord::Bot.new(
56
+ token: ENV.fetch('DISCORD_TOKEN'),
57
+ intents: %i[servers server_messages direct_messages message_content],
58
+ mode: :hybrid
59
+ )
60
+
61
+ bot.message(content: 'ping') do |event|
62
+ event.respond!(content: 'pong')
63
+ end
64
+
65
+ bot.application_command(:ping) do |event|
66
+ event.respond(content: 'Pong via Slash Command!')
67
+ end
68
+
69
+ bot.run
70
+ ```
71
+
72
+ Execute:
73
+
74
+ ```sh
75
+ ruby bot.rb
76
+ ```
77
+
78
+ ## Eventos raw
79
+
80
+ Para bots que precisam de performance, o OnyxCord pode trabalhar direto com o payload do Gateway:
81
+
82
+ ```ruby
83
+ require 'onyxcord'
84
+
85
+ bot = OnyxCord::Bot.new(
86
+ token: ENV.fetch('DISCORD_TOKEN'),
87
+ mode: :raw,
88
+ intents: :minimal
89
+ )
90
+
91
+ bot.raw(:MESSAGE_CREATE) do |payload|
92
+ puts payload['d']['content']
93
+ end
94
+
95
+ bot.raw(/MESSAGE_/) do |payload|
96
+ puts "evento: #{payload['t']}"
97
+ end
98
+
99
+ bot.raw do |payload|
100
+ puts "op: #{payload['op']}"
101
+ end
102
+
103
+ bot.run
104
+ ```
105
+
106
+ Use `mode: :raw` quando quiser evitar a criação de objetos pesados por padrão e processar apenas os pacotes de Gateway diretamente.
107
+ **Importante:** O `OnyxCord` roda em `:raw` por padrão. Se você quiser usar os comandos de aplicação normais (`application_command`), modais e outros eventos em objeto, **você deve inicializar o bot com `mode: :hybrid`** ou `mode: :object`!
108
+
109
+ ## Components V2
110
+
111
+ Components V2 usam a flag `IS_COMPONENTS_V2` (`1 << 15`, valor `32768`). No OnyxCord, essa flag é aplicada automaticamente quando você usa componentes V2, mas você também pode deixar explícito com `components_v2: true`.
112
+
113
+ Importante: em mensagens V2, o Discord desativa `content`, `embeds`, `poll` e stickers tradicionais. O conteúdo visual deve ser enviado como componentes.
114
+
115
+ ```ruby
116
+ bot.message(content: '!painel') do |event|
117
+ event.send_message!(content: nil, components_v2: true) do |_builder, view|
118
+ view.text_display(content: '## Painel OnyxCord')
119
+ view.text_display(content: 'Escolha uma ação abaixo.')
120
+
121
+ view.row do |row|
122
+ row.button(
123
+ style: :primary,
124
+ label: 'Abrir',
125
+ custom_id: 'open_panel'
126
+ )
127
+
128
+ row.button(
129
+ style: :secondary,
130
+ label: 'Ajuda',
131
+ custom_id: 'help_panel'
132
+ )
133
+ end
134
+ end
135
+ end
136
+
137
+ bot.button(custom_id: 'open_panel') do |event|
138
+ event.respond(content: 'Painel aberto!', ephemeral: true)
139
+ end
140
+ ```
141
+
142
+ ## Container V2
143
+
144
+ Containers funcionam como uma estrutura visual rica para agrupar textos, botões, imagens e arquivos:
145
+
146
+ ```ruby
147
+ bot.message(content: '!status') do |event|
148
+ event.send_message!(content: nil) do |_builder, view|
149
+ view.container(color: '#8b5cf6') do |container|
150
+ container.text_display(content: '### Status do servidor')
151
+ container.separator(divider: true, spacing: :small)
152
+
153
+ container.section do |section|
154
+ section.text_display(content: 'Tudo funcionando normalmente.')
155
+ section.button(
156
+ style: :success,
157
+ label: 'Atualizar',
158
+ custom_id: 'refresh_status'
159
+ )
160
+ end
161
+ end
162
+ end
163
+ end
164
+ ```
165
+
166
+ Ao usar `container`, `section`, `text_display`, `media_gallery`, `file_display`, `separator` ou `thumbnail`, o OnyxCord detecta Components V2 e envia a flag correta.
167
+
168
+ ## Modais modernos
169
+
170
+ O OnyxCord também suporta os componentes novos de modal:
171
+
172
+ ```ruby
173
+ bot.register_application_command(
174
+ :feedback,
175
+ 'Enviar feedback',
176
+ server_id: ENV.fetch('DISCORD_SERVER_ID')
177
+ )
178
+
179
+ bot.application_command(:feedback) do |event|
180
+ event.show_modal(title: 'Feedback', custom_id: 'feedback_modal') do |modal|
181
+ modal.label(label: 'Mensagem') do |label|
182
+ label.text_input(
183
+ style: :paragraph,
184
+ custom_id: 'message',
185
+ required: true,
186
+ placeholder: 'Conte o que você achou...'
187
+ )
188
+ end
189
+
190
+ modal.label(label: 'Categoria') do |label|
191
+ label.string_select(custom_id: 'category', required: true) do |menu|
192
+ menu.option(label: 'Bug', value: 'bug')
193
+ menu.option(label: 'Ideia', value: 'idea')
194
+ menu.option(label: 'Outro', value: 'other')
195
+ end
196
+ end
197
+
198
+ modal.text_display(content: 'Obrigado por ajudar a melhorar a comunidade.')
199
+ end
200
+ end
201
+
202
+ bot.modal_submit(custom_id: 'feedback_modal') do |event|
203
+ categoria = event.values('category')&.first
204
+ mensagem = event.value('message')
205
+
206
+ event.respond(
207
+ content: "Feedback recebido em #{categoria}: #{mensagem}",
208
+ ephemeral: true
209
+ )
210
+ end
211
+ ```
212
+
213
+ ## Webhooks
214
+
215
+ Também existe um cliente de webhooks:
216
+
217
+ ```ruby
218
+ require 'onyxcord/webhooks'
219
+
220
+ client = OnyxCord::Webhooks::Client.new(
221
+ url: ENV.fetch('DISCORD_WEBHOOK_URL')
222
+ )
223
+
224
+ client.execute do |builder|
225
+ builder.content = 'Mensagem enviada por webhook.'
226
+
227
+ builder.add_embed do |embed|
228
+ embed.title = 'OnyxCord'
229
+ embed.description = 'Webhook funcionando.'
230
+ embed.timestamp = Time.now
231
+ end
232
+ end
233
+ ```
234
+
235
+ Webhook com Components V2:
236
+
237
+ ```ruby
238
+ client.execute(components_v2: true) do |builder, view|
239
+ builder.content = nil
240
+
241
+ view.text_display(content: '## Atualização da comunidade')
242
+ view.text_display(content: 'Nova versão do OnyxCord disponível.')
243
+ end
244
+ ```
245
+
246
+ Quando componentes são enviados por webhook, o OnyxCord adiciona `with_components=true` na URL automaticamente.
247
+
248
+ ## Dependências
249
+
250
+ Para bots normais:
251
+
252
+ - Ruby 3.2 ou superior.
253
+ - Bundler recomendado.
254
+ - Build tools para extensões nativas, principalmente no Windows.
255
+
256
+ Para recursos de voz:
257
+
258
+ - `libsodium`
259
+ - `libopus`
260
+ - `FFmpeg`
261
+
262
+ Você só precisa dessas dependências de voz se o bot for entrar em canais de voz, tocar áudio ou trabalhar com pacotes de voz. Bots de texto, comandos, interactions, modais, webhooks e Components V2 funcionam sem `libsodium`.
263
+
264
+ ## Exemplos
265
+
266
+ A pasta `examples/` contém exemplos prontos:
267
+
268
+ - `ping.rb`: bot simples de ping/pong.
269
+ - `commands.rb`: comandos tradicionais.
270
+ - `slash_commands.rb`: slash commands.
271
+ - `components.rb`: Components V2.
272
+ - `modals.rb`: modais modernos.
273
+ - `select_menus.rb`: menus de seleção.
274
+ - `webhooks.rb`: webhooks.
275
+ - `voice_send.rb`: envio de voz.
276
+
277
+ ## Desenvolvimento
278
+
279
+ Para trabalhar no OnyxCord localmente:
280
+
281
+ ```sh
282
+ bundle install
283
+ bundle exec rspec spec
284
+ ```
285
+
286
+ Se `libsodium` não estiver instalado, os testes de voz podem falhar. Para testar o restante:
287
+
288
+ ```sh
289
+ bundle exec rspec $(find spec -name '*_spec.rb' ! -name 'sodium_spec.rb' | sort)
290
+ ```
291
+
292
+ ## Créditos
293
+
294
+ OnyxCord foi criado a partir da base do `discordrb`, uma biblioteca Ruby importante para a comunidade de bots no Discord.
295
+
296
+ Este projeto continua essa ideia com uma proposta atualizada:
297
+
298
+ - manter Ruby acessível para bots do Discord;
299
+ - modernizar o core;
300
+ - adicionar suporte aos novos componentes do Discord;
301
+ - entregar uma base aberta para a comunidade evoluir.
302
+
303
+ ## Licença
304
+
305
+ Distribuído como open source sob a licença MIT.
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_helper'
4
+
5
+ namespace :main do
6
+ Bundler::GemHelper.install_tasks(name: 'onyxcord')
7
+ end
8
+
9
+ namespace :webhooks do
10
+ Bundler::GemHelper.install_tasks(name: 'onyxcord-webhooks')
11
+ end
12
+
13
+ task build: %i[main:build webhooks:build]
14
+ task release: %i[main:release webhooks:release]
15
+
16
+ # Make "build" the default task
17
+ task default: :build
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'onyxcord'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'onyxcord/id_object'
4
+
5
+ module OnyxCord
6
+ # Builder class for `allowed_mentions` when sending messages.
7
+ class AllowedMentions
8
+ # @return [Array<"users", "roles", "everyone">, nil]
9
+ attr_accessor :parse
10
+
11
+ # @return [Array<String, Integer>, nil]
12
+ attr_accessor :users
13
+
14
+ # @return [Array<String, Integer>, nil]
15
+ attr_accessor :roles
16
+
17
+ # @return [true, false, nil]
18
+ attr_accessor :replied_user
19
+ alias_method :replied_user?, :replied_user
20
+
21
+ # @param parse [Array<"users", "roles", "everyone">] Mention types that can be inferred from the message.
22
+ # `users` and `roles` allow for all mentions of the respective type to ping. `everyone` allows usage of `@everyone` and `@here`
23
+ # @param users [Array<User, String, Integer>] Users or user IDs that can be pinged. Cannot be used in conjunction with `"users"` in `parse`
24
+ # @param roles [Array<Role, String, Integer>] Roles or role IDs that can be pinged. Cannot be used in conjunction with `"roles"` in `parse`
25
+ # @param replied_user [true, false, nil] For replies, whether to mention the author of the message being replied to. Defaults to no mention
26
+ def initialize(parse: nil, users: nil, roles: nil, replied_user: nil)
27
+ @parse = parse
28
+ @users = users
29
+ @roles = roles
30
+ @replied_user = replied_user
31
+ end
32
+
33
+ # @!visibility private
34
+ def to_hash
35
+ {
36
+ parse: @parse,
37
+ users: @users&.map { |user| user.is_a?(IDObject) ? user.id : user },
38
+ roles: @roles&.map { |role| role.is_a?(IDObject) ? role.id : role },
39
+ replied_user: @replied_user
40
+ }.compact
41
+ end
42
+ end
43
+ end