async-discord 0.1.0 → 0.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 33834a7af00dffadb4f4c2c050e62dda6aa9823401a7be3814616422bce948a1
4
- data.tar.gz: 40e8682837b6325b3d1a14bdb8913b535cccc96d5cd569e81822a63851275850
3
+ metadata.gz: fda03ce79f4fbac7dac03a5290af0a07c7a159fa160a4fa7dfd3ec072d214f38
4
+ data.tar.gz: 1ebd9eb42de4f3d916820797e45d49a3657ac77c021e9099137cde15134359dc
5
5
  SHA512:
6
- metadata.gz: d07684c7f494a3cc8893b345190d2fd495b5ec57251be6a11f158e22c12aeade6a6f975ae078287bc7e1171db4adaf942f426009a685caf39df731725f0ad96d
7
- data.tar.gz: d316e91be104bf9634f4ec8242c7c9f4410e0a823de3627c62232d23c7c7c85cf099c158cfb3e7adba9150d1ce1808bdd0e3b54a62774a5f18414891f5e8415e
6
+ metadata.gz: bb9aaa5be5d7e133bff407105dada36e5bd89accd5c8fbd2c32fa6ff114daeb5445247bdfce906e3c1b077c988943b64b615c6c5f886113c800856c995ff223c
7
+ data.tar.gz: 246bce63ba164bd1a3621045d71569aa47f50339d657249c019b67f3b9d73d9bcee41fd2d4d6155a036e3b94108ba3d41f5d218c0bc7f1d7da0dac463c9f0b6c
checksums.yaml.gz.sig CHANGED
Binary file
@@ -1,11 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
5
+
1
6
  require_relative "representation"
2
7
 
3
8
  module Async
4
9
  module Discord
10
+ # Represents a message in a channel.
5
11
  class Message < Representation
6
12
  end
7
13
 
14
+ # Represents a channel in a guild.
8
15
  class Channel < Representation
16
+ # Send a message to this channel.
17
+ #
18
+ # @parameter content [String] The content of the message.
9
19
  def send_message(content)
10
20
  payload = {
11
21
  content: content
@@ -14,20 +24,32 @@ module Async
14
24
  Message.post(@resource.with(path: "messages"), payload)
15
25
  end
16
26
 
27
+ # The unique identifier for this channel.
17
28
  def id
18
29
  self.value[:id]
19
30
  end
20
31
 
32
+ # Whether this channel is a text channel.
33
+ #
34
+ # @returns [Boolean] if this channel is a text channel.
21
35
  def text?
22
36
  self.value[:type] == 0
23
37
  end
24
38
 
39
+ # Whether this channel is a voice channel.
40
+ #
41
+ # @returns [Boolean] if this channel is a voice channel.
25
42
  def voice?
26
43
  self.value[:type] == 2
27
44
  end
28
45
  end
29
46
 
47
+ # Represents a collection of channels.
30
48
  class Channels < Representation
49
+ # Enumerate over each channel.
50
+ #
51
+ # @yields {|channel| ...}
52
+ # @parameter channel [Channel] The channel.
31
53
  def each(&block)
32
54
  return to_enum unless block_given?
33
55
 
@@ -38,6 +60,9 @@ module Async
38
60
  end
39
61
  end
40
62
 
63
+ # Convert this collection to an array.
64
+ #
65
+ # @returns [Array(Channel)] an array of channels.
41
66
  def to_a
42
67
  each.to_a
43
68
  end
@@ -1,36 +1,28 @@
1
- # frozen_string_literals: true
2
- #
3
- # Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
1
+ # frozen_string_literal: true
22
2
 
23
- require_relative 'representation'
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
24
5
 
25
- require_relative 'guilds'
26
- require_relative 'gateway'
6
+ require_relative "representation"
7
+
8
+ require_relative "guilds"
9
+ require_relative "gateway"
27
10
 
28
11
  module Async
29
12
  module Discord
13
+ # A client for interacting with Discord.
30
14
  class Client < Async::REST::Resource
15
+ # The default endpoint for Discord.
31
16
  ENDPOINT = Async::HTTP::Endpoint.parse("https://discord.com/api/v10/")
17
+
18
+ # The default user agent for this client.
32
19
  USER_AGENT = "#{self.name} (https://github.com/socketry/async-discord, v#{Async::Discord::VERSION})"
33
20
 
21
+ # Authenticate the client, either with a bot or bearer token.
22
+ #
23
+ # @parameter bot [String] The bot token.
24
+ # @parameter bearer [String] The bearer token.
25
+ # @returns [Client] a new client with the given authentication.
34
26
  def authenticated(bot: nil, bearer: nil)
35
27
  headers = {}
36
28
 
@@ -47,14 +39,17 @@ module Async
47
39
  return self.with(headers: headers)
48
40
  end
49
41
 
42
+ # @returns [Guilds] a collection of guilds the bot is a member of.
50
43
  def guilds
51
44
  Guilds.new(self.with(path: "users/@me/guilds"))
52
45
  end
53
46
 
47
+ # @returns [Gateway] the gateway for the bot.
54
48
  def gateway
55
49
  Gateway.new(self.with(path: "gateway/bot"))
56
50
  end
57
51
 
52
+ # @returns [Channel] a channel by its unique identifier.
58
53
  def channel(id)
59
54
  Channel.new(self.with(path: "channels/#{id}"))
60
55
  end
@@ -1,9 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
5
+
1
6
  require_relative "representation"
2
7
 
3
8
  require "async/websocket"
4
9
 
5
10
  module Async
6
11
  module Discord
12
+ # Represents a gateway connection to Discord, which can be used to send and receive messages via a WebSocket connection.
7
13
  class GatewayConnection < Async::WebSocket::Connection
8
14
  # Gateway Opcodes:
9
15
  DISPATCH = 0
@@ -19,7 +25,7 @@ module Async
19
25
  HEARTBEAT_ACK = 11
20
26
  REQUEST_SOUNDBOARD_SOUNDS = 31
21
27
 
22
- # Gateway Error Codes
28
+ # Gateway Error Codes.
23
29
  ERROR_CODES = {
24
30
  4000 => "UNKNOWN_ERROR",
25
31
  4001 => "UNKNOWN_OPCODE",
@@ -37,7 +43,7 @@ module Async
37
43
  4014 => "DISALLOWED_INTENT"
38
44
  }
39
45
 
40
- # Guild Intents:
46
+ # Guild Intents.
41
47
  module Intent
42
48
  GUILDS = 1 << 0
43
49
  GUILD_MEMBERS = 1 << 1
@@ -62,20 +68,24 @@ module Async
62
68
  DIRECT_MESSAGE_POLLS = 1 << 25
63
69
  end
64
70
 
71
+ # Default intent for a bot.
65
72
  DEFAULT_INTENT = Intent::GUILDS | Intent::GUILD_MESSAGES | Intent::DIRECT_MESSAGES
66
73
 
74
+ # Default properties for a bot.
67
75
  DEFAULT_PROPERTIES = {
68
76
  os: RUBY_PLATFORM,
69
77
  browser: Async::Discord.name,
70
78
  device: Async::Discord.name,
71
79
  }
72
80
 
81
+ # Default presence for a bot.
73
82
  DEFAULT_PRESENCE = {
74
83
  status: "online",
75
84
  afk: false,
76
85
  activities: [],
77
86
  }
78
87
 
88
+ # Initialize the gateway connection.
79
89
  def initialize(...)
80
90
  super
81
91
 
@@ -83,6 +93,7 @@ module Async
83
93
  @sequence = nil
84
94
  end
85
95
 
96
+ # Close the gateway connection, including the heartbeat task.
86
97
  def close(...)
87
98
  if heartbeat_task = @heartbeat_task
88
99
  @heartbeat_task = nil
@@ -92,6 +103,9 @@ module Async
92
103
  super
93
104
  end
94
105
 
106
+ # Identify the bot with the given identity.
107
+ #
108
+ # @returns [Hash] the payload from the READY event.
95
109
  def identify(**identity)
96
110
  while message = self.read
97
111
  payload = message.parse
@@ -131,6 +145,10 @@ module Async
131
145
  end
132
146
  end
133
147
 
148
+ # Listen for events from the gateway.
149
+ #
150
+ # @yields {|payload| ...}
151
+ # @parameter payload [Hash] The parsed payload.
134
152
  def listen
135
153
  while message = self.read
136
154
  payload = message.parse
@@ -153,6 +171,7 @@ module Async
153
171
 
154
172
  private
155
173
 
174
+ # Run a heartbeat task at the given interval.
156
175
  def run_heartbeat(duration_ms)
157
176
  duration = duration_ms / 1000.0
158
177
  Console.debug(self, "Running heartbeat every #{duration} seconds.")
@@ -172,19 +191,30 @@ module Async
172
191
  end
173
192
  end
174
193
 
194
+ # Represents a gateway for the bot.
175
195
  class Gateway < Representation
196
+ # The URL of the gateway, used for connecting to the WebSocket server.
176
197
  def url
177
198
  self.value[:url]
178
199
  end
179
200
 
201
+ # The number of shards to use.
180
202
  def shards
181
203
  self.value[:shards]
182
204
  end
183
205
 
206
+ # Limits associated with this bot connecting to the gateway. You should respect these limits to avoid being rate limited.
207
+ #
208
+ # @returns [Hash] the limits, including `:total`, `:remaining`, `:reset_after`, and `:max_concurrency`.
184
209
  def session_start_limit
185
210
  self.value[:session_start_limit]
186
211
  end
187
212
 
213
+ # Connect to the gateway, yielding the connection.
214
+ #
215
+ # @yields {|connection| ...} if a block is given.
216
+ # @parameter connection [GatewayConnection] The connection to the gateway.
217
+ # @returns [GatewayConnection] the connection to the gateway.
188
218
  def connect(shard: nil, &block)
189
219
  endpoint = Async::HTTP::Endpoint.parse(self.url, alpn_protocols: Async::HTTP::Protocol::HTTP11.names)
190
220
 
@@ -1,19 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
5
+
1
6
  require_relative "representation"
2
7
  require_relative "channels"
3
8
 
4
9
  module Async
5
10
  module Discord
11
+ # Represents a guild in Discord.
6
12
  class Guild < Representation
13
+ # @returns [Channels] a collection of channels in this guild.
7
14
  def channels
8
15
  Channels.new(@resource.with(path: "channels"))
9
16
  end
10
17
 
18
+ # The unique identifier for this guild.
11
19
  def id
12
20
  self.value[:id]
13
21
  end
14
22
  end
15
23
 
24
+ # Represents a collection of guilds.
16
25
  class Guilds < Representation
26
+ # Enumerate over each guild.
27
+ #
28
+ # @yields {|guild| ...} if a block is given.
29
+ # @parameter guild [Guild] The guild.
30
+ # @returns [Enumerator] if no block is given.
17
31
  def each(&block)
18
32
  return to_enum unless block_given?
19
33
 
@@ -24,9 +38,17 @@ module Async
24
38
  end
25
39
  end
26
40
 
41
+ # Convert the collection to an array.
42
+ #
43
+ # @returns [Array(Guild)] the collection as an array.
27
44
  def to_a
28
45
  each.to_a
29
46
  end
47
+
48
+ # @returns [Boolean] if the collection is empty.
49
+ def empty?
50
+ self.value.empty?
51
+ end
30
52
  end
31
53
  end
32
54
  end
@@ -1,33 +1,18 @@
1
- # frozen_string_literals: true
2
- #
3
- # Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
1
+ # frozen_string_literal: true
22
2
 
23
- require 'async/rest/representation'
24
- require 'async/rest/wrapper/form'
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
5
+
6
+ require "async/rest/representation"
7
+ require "async/rest/wrapper/form"
25
8
 
26
9
  module Async
27
10
  module Discord
11
+ # The default wrapper for Discord.
28
12
  class Wrapper < Async::REST::Wrapper::JSON
29
13
  end
30
14
 
15
+ # The default representation for Discord.
31
16
  class Representation < Async::REST::Representation[Wrapper]
32
17
  end
33
18
  end
@@ -5,6 +5,6 @@
5
5
 
6
6
  module Async
7
7
  module Discord
8
- VERSION = "0.1.0"
8
+ VERSION = "0.1.1"
9
9
  end
10
10
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
5
+
6
+ require_relative "discord/version"
7
+ require_relative "discord/client"
8
+
9
+ # @namespace
10
+ module Async
11
+ # @namespace
12
+ module Discord
13
+ end
14
+ end
15
+
data/readme.md CHANGED
@@ -1,3 +1,37 @@
1
1
  # Async::Discord
2
2
 
3
3
  Provides a simple `Async::REST` client for interacting with the Discord API.
4
+
5
+ [![Development Status](https://github.com/socketry/async-discord/workflows/Test/badge.svg)](https://github.com/socketry/async-discord/actions?workflow=Test)
6
+
7
+ ## Usage
8
+
9
+ Please see the [project documentation](https://socketry.github.io/async-discord/) for more details.
10
+
11
+ - [Getting Started](https://socketry.github.io/async-discord/guides/getting-started/index) - This guide explains how to create a bot for Discord using the `async-discord` gem.
12
+
13
+ ## Releases
14
+
15
+ Please see the [project releases](https://socketry.github.io/async-discord/releases/index) for all releases.
16
+
17
+ ### v0.1.0
18
+
19
+ - Initial release.
20
+
21
+ ## Contributing
22
+
23
+ We welcome contributions to this project.
24
+
25
+ 1. Fork it.
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`).
28
+ 4. Push to the branch (`git push origin my-new-feature`).
29
+ 5. Create new Pull Request.
30
+
31
+ ### Developer Certificate of Origin
32
+
33
+ In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
34
+
35
+ ### Community Guidelines
36
+
37
+ This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
data/releases.md ADDED
@@ -0,0 +1,5 @@
1
+ # Releases
2
+
3
+ ## v0.1.0
4
+
5
+ - Initial release.
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,11 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-discord
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain:
11
10
  - |
@@ -37,22 +36,22 @@ cert_chain:
37
36
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
38
37
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
39
38
  -----END CERTIFICATE-----
40
- date: 2024-11-25 00:00:00.000000000 Z
39
+ date: 2025-01-28 00:00:00.000000000 Z
41
40
  dependencies:
42
41
  - !ruby/object:Gem::Dependency
43
42
  name: async-rest
44
43
  requirement: !ruby/object:Gem::Requirement
45
44
  requirements:
46
- - - ">="
45
+ - - "~>"
47
46
  - !ruby/object:Gem::Version
48
- version: '0'
47
+ version: '0.19'
49
48
  type: :runtime
50
49
  prerelease: false
51
50
  version_requirements: !ruby/object:Gem::Requirement
52
51
  requirements:
53
- - - ">="
52
+ - - "~>"
54
53
  - !ruby/object:Gem::Version
55
- version: '0'
54
+ version: '0.19'
56
55
  - !ruby/object:Gem::Dependency
57
56
  name: async-websocket
58
57
  requirement: !ruby/object:Gem::Requirement
@@ -67,12 +66,11 @@ dependencies:
67
66
  - - ">="
68
67
  - !ruby/object:Gem::Version
69
68
  version: '0'
70
- description:
71
- email:
72
69
  executables: []
73
70
  extensions: []
74
71
  extra_rdoc_files: []
75
72
  files:
73
+ - lib/async/discord.rb
76
74
  - lib/async/discord/channels.rb
77
75
  - lib/async/discord/client.rb
78
76
  - lib/async/discord/gateway.rb
@@ -81,12 +79,13 @@ files:
81
79
  - lib/async/discord/version.rb
82
80
  - license.md
83
81
  - readme.md
82
+ - releases.md
84
83
  homepage: https://github.com/socketry/async-discord
85
84
  licenses:
86
85
  - MIT
87
86
  metadata:
87
+ documentation_uri: https://socketry.github.io/async-discord/
88
88
  source_code_uri: https://github.com/socketry/async-discord.git
89
- post_install_message:
90
89
  rdoc_options: []
91
90
  require_paths:
92
91
  - lib
@@ -101,8 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
100
  - !ruby/object:Gem::Version
102
101
  version: '0'
103
102
  requirements: []
104
- rubygems_version: 3.5.22
105
- signing_key:
103
+ rubygems_version: 3.6.2
106
104
  specification_version: 4
107
105
  summary: Build Discord bots and use real time messaging.
108
106
  test_files: []
metadata.gz.sig CHANGED
Binary file