discorb 0.10.0 → 0.11.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.
- checksums.yaml +4 -4
- data/Changelog.md +29 -0
- data/Rakefile +1 -1
- data/docs/application_command.md +28 -1
- data/docs/cli/init.md +3 -3
- data/docs/cli/run.md +5 -1
- data/docs/extension.md +51 -7
- data/docs/faq.md +27 -5
- data/docs/tutorial.md +4 -2
- data/examples/extension/message_expander.rb +3 -1
- data/lib/discorb/app_command.rb +8 -3
- data/lib/discorb/client.rb +17 -3
- data/lib/discorb/common.rb +1 -1
- data/lib/discorb/components.rb +1 -0
- data/lib/discorb/exe/{init.rb → new.rb} +1 -1
- data/lib/discorb/exe/run.rb +20 -3
- data/lib/discorb/extension.rb +9 -8
- data/lib/discorb/http.rb +14 -34
- data/lib/discorb/integration.rb +1 -1
- data/lib/discorb/interaction.rb +82 -1
- data/lib/discorb/member.rb +1 -10
- data/lib/discorb/modules.rb +1 -1
- data/lib/discorb/rate_limit.rb +15 -2
- data/lib/discorb/role.rb +24 -4
- data/lib/discorb/voice_state.rb +1 -1
- data/template-replace/scripts/version.rb +7 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c80c426387c9e5ba44589c5851e7c1a4d54a5de99c82d5b3571c4200dcaf135
|
4
|
+
data.tar.gz: 2aa6db0900cafe2120793b295b68e5de357e97e0797cd416a06caca9491b09e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: afe14b35796820b8b7af5baaab6a79a5a770c55d11d30d25b2a9647034658e27346e918be42fb8d4a30edbf27873bd367cf3551cf1b091e82c49150c886ef03e
|
7
|
+
data.tar.gz: 9c817738b2a4b3763d94182e2b47f583aaa7129a8769cdc9b8f7fc7e10f0656f43183f0d416d72aa20112b6b34addfdd38e36b7710c6405d2f29f658cb238c4c
|
data/Changelog.md
CHANGED
@@ -2,8 +2,37 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
## v0.11
|
6
|
+
|
7
|
+
### v0.11.0
|
8
|
+
|
9
|
+
- Add: Improve documents
|
10
|
+
- Add: Implement global rate limits
|
11
|
+
- Add: Add support autocomplete
|
12
|
+
- Add: Add role icon editting
|
13
|
+
- Change: Use `include Discorb::Extension` instead of `< Discorb::Extension`
|
14
|
+
- Fix: Fix role operation
|
15
|
+
|
5
16
|
## v0.10
|
6
17
|
|
18
|
+
### v0.10.3
|
19
|
+
|
20
|
+
- Add: Support role icons
|
21
|
+
- Fix: Fix version order
|
22
|
+
- Change: Use `exec` instead of `system` in `discorb run`
|
23
|
+
- Add: Add `Extension.loaded`
|
24
|
+
|
25
|
+
### v0.10.2
|
26
|
+
|
27
|
+
- Change: `discorb init` is now `discorb new`
|
28
|
+
- Add: Add `:channel_types` parameter to `ApplicationCommand::Handler#slash` and some
|
29
|
+
|
30
|
+
### v0.10.1
|
31
|
+
|
32
|
+
- Add: Add `Client#extensions`
|
33
|
+
- Change: `Client#load_extension` allows instance of `Extension`
|
34
|
+
- Add: Add `-b` option to `discorb run`
|
35
|
+
|
7
36
|
### v0.10.0
|
8
37
|
|
9
38
|
- Change: Sort versions
|
data/Rakefile
CHANGED
@@ -156,7 +156,7 @@ namespace :document do
|
|
156
156
|
Rake::Task["document:replace:html"].execute
|
157
157
|
Rake::Task["document:replace:css"].execute
|
158
158
|
Rake::Task["document:replace:eol"].execute
|
159
|
-
tags = `git tag`.force_encoding("utf-8").split("\n")
|
159
|
+
tags = `git tag`.force_encoding("utf-8").split("\n").sort_by { |t| t[1..].split(".").map(&:to_i) }
|
160
160
|
tags.each do |tag|
|
161
161
|
sh "git checkout #{tag} -f"
|
162
162
|
iputs "Building #{tag}"
|
data/docs/application_command.md
CHANGED
@@ -68,6 +68,8 @@ In `options`, hash should be like this:
|
|
68
68
|
| `:type` | `Object` | Type of the option. |
|
69
69
|
| `:choice` | `Hash{String => String, Integer, Float}` | Type of the option. |
|
70
70
|
| `:default` | `Object` | Default value of the option. |
|
71
|
+
| `:channel_types` | `Array<Class<Discorb::Channel>>` | Type of the channel option. |
|
72
|
+
| `:autocomplete` | `Proc` | Autocomplete function. |
|
71
73
|
|
72
74
|
`choices` should be unspecified if you don't want to use it.
|
73
75
|
`choices` is hash like this:
|
@@ -106,7 +108,7 @@ In `type`, You must use one of the following:
|
|
106
108
|
| `:channel` | Channel argument. | None |
|
107
109
|
| `:role` | Role argument. | None |
|
108
110
|
|
109
|
-
|
111
|
+
#### Group Slash Commands
|
110
112
|
|
111
113
|
To register a group of slash commands, use {Discorb::ApplicationCommand::Handler#slash_group}.
|
112
114
|
|
@@ -238,6 +240,31 @@ end
|
|
238
240
|
|
239
241
|
Same as above, you can use block for register commands since v0.5.1.
|
240
242
|
|
243
|
+
#### Use Auto Completing
|
244
|
+
|
245
|
+
Since v0.11.0, you can use auto completion by setting Proc to `:autocomplete` in options.
|
246
|
+
The proc will be called with interaction object and the argument.
|
247
|
+
The proc should return an hash of the autocomplete result.
|
248
|
+
|
249
|
+
```ruby
|
250
|
+
client.slash("hello2", "Greet for you", {
|
251
|
+
"target" => {
|
252
|
+
type: :string,
|
253
|
+
description: "Person to greet",
|
254
|
+
autocomplete: ->(interaction, target) {
|
255
|
+
{
|
256
|
+
"You" => interaction.target.to_s
|
257
|
+
}
|
258
|
+
},
|
259
|
+
},
|
260
|
+
}) do |interaction, target|
|
261
|
+
interaction.post("Hello, #{target}!")
|
262
|
+
end
|
263
|
+
```
|
264
|
+
|
265
|
+
In the above example, `You` will be displayed in the user menu.
|
266
|
+
Due to the limitation of Discord API, the proc must return the result in less than 3 second.
|
267
|
+
|
241
268
|
### Register User Context Menu Command
|
242
269
|
|
243
270
|
```ruby
|
data/docs/cli/init.md
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
# @title CLI: discorb
|
1
|
+
# @title CLI: discorb new
|
2
2
|
|
3
|
-
# discorb
|
3
|
+
# discorb new
|
4
4
|
|
5
5
|
This command will create a new project in the directory.
|
6
6
|
|
7
7
|
## Usage
|
8
8
|
|
9
9
|
```bash
|
10
|
-
discorb
|
10
|
+
discorb new [options] [dir]
|
11
11
|
```
|
12
12
|
|
13
13
|
## Options
|
data/docs/cli/run.md
CHANGED
@@ -53,4 +53,8 @@ Whether to setup application commands.
|
|
53
53
|
|
54
54
|
#### `-e`, `--env`
|
55
55
|
|
56
|
-
The name of the environment variable to use for token, or just `-t` or `--token` for intractive prompt.
|
56
|
+
The name of the environment variable to use for token, or just `-t` or `--token` for intractive prompt.
|
57
|
+
|
58
|
+
#### `-b`, `--bundler`
|
59
|
+
|
60
|
+
Whether to use bundler to load the script.
|
data/docs/extension.md
CHANGED
@@ -2,16 +2,18 @@
|
|
2
2
|
|
3
3
|
# Extension
|
4
4
|
|
5
|
-
Extension allows you to seperate
|
5
|
+
Extension allows you to seperate events.
|
6
6
|
|
7
7
|
# @since
|
8
8
|
|
9
9
|
## Make a new extension
|
10
10
|
|
11
|
-
Make a new class that
|
11
|
+
Make a new class that includes Extension.
|
12
12
|
|
13
13
|
```ruby
|
14
|
-
class MyExtension
|
14
|
+
class MyExtension
|
15
|
+
include Discorb::Extension
|
16
|
+
|
15
17
|
# ...
|
16
18
|
end
|
17
19
|
```
|
@@ -21,7 +23,9 @@ end
|
|
21
23
|
Use {Discorb::Extension.event} to register event, or {Discorb::Extension.once_event} to register event only once.
|
22
24
|
|
23
25
|
```ruby
|
24
|
-
class MyExtension
|
26
|
+
class MyExtension
|
27
|
+
include Discorb::Extension
|
28
|
+
|
25
29
|
event :message do |message|
|
26
30
|
# ...
|
27
31
|
end
|
@@ -39,7 +43,9 @@ Note block will be binded to the extension instance.
|
|
39
43
|
Use `Discorb::Extension.command` to register command, see {Discorb::ApplicationCommand::Handler} for more information.
|
40
44
|
|
41
45
|
```ruby
|
42
|
-
class MyExtension
|
46
|
+
class MyExtension
|
47
|
+
include Discorb::Extension
|
48
|
+
|
43
49
|
slash("command", "Command") do |interaction|
|
44
50
|
# ...
|
45
51
|
end
|
@@ -64,7 +70,9 @@ end
|
|
64
70
|
Use {Discorb::Client#load_extension} to load extension.
|
65
71
|
|
66
72
|
```ruby
|
67
|
-
class MyExtension
|
73
|
+
class MyExtension
|
74
|
+
include Discorb::Extension
|
75
|
+
|
68
76
|
event :message do |message|
|
69
77
|
# ...
|
70
78
|
end
|
@@ -78,9 +86,45 @@ client.load_extension(MyExtension)
|
|
78
86
|
You can access {Discorb::Client} from extension with `@client`.
|
79
87
|
|
80
88
|
```ruby
|
81
|
-
class MyExtension
|
89
|
+
class MyExtension
|
90
|
+
include Discorb::Extension
|
91
|
+
|
82
92
|
event :standby do |message|
|
83
93
|
puts "Logged in as #{@client.user}"
|
84
94
|
end
|
85
95
|
end
|
86
96
|
```
|
97
|
+
|
98
|
+
## Receiving Arguments on load
|
99
|
+
|
100
|
+
You can receive arguments by adding some arguments to `#initialize`.
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
class MyExtension
|
104
|
+
include Discorb::Extension
|
105
|
+
|
106
|
+
def initialize(client, arg1, arg2)
|
107
|
+
super(client)
|
108
|
+
# @client = client will also work, but it's not recommended.
|
109
|
+
@arg1 = arg1
|
110
|
+
@arg2 = arg2
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
client.load_extension(MyExtension, "arg1", "arg2")
|
115
|
+
|
116
|
+
```
|
117
|
+
|
118
|
+
## Do something on load
|
119
|
+
|
120
|
+
You can do something on load by overriding `.loaded`. Client and arguments will be passed to it.
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
class MyExtension
|
124
|
+
include Discorb::Extension
|
125
|
+
|
126
|
+
def self.loaded(client)
|
127
|
+
puts "This extension is loaded to #{client}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
```
|
data/docs/faq.md
CHANGED
@@ -2,13 +2,25 @@
|
|
2
2
|
|
3
3
|
# Fequently asked questions
|
4
4
|
|
5
|
-
## What is
|
5
|
+
## What is ...?
|
6
|
+
|
7
|
+
### What is `Async::Task`?
|
6
8
|
|
7
9
|
Async::Task is a object for asynchronous tasks.
|
8
10
|
|
9
11
|
https://socketry.github.io/async/ for more information.
|
10
12
|
|
11
|
-
|
13
|
+
### What is `Guild`?
|
14
|
+
|
15
|
+
It means a `server` of Discord.
|
16
|
+
|
17
|
+
### What is difference between `User` and `Member`?
|
18
|
+
|
19
|
+
`User` is a object for account, `Member` is a object for user in guild.
|
20
|
+
|
21
|
+
## How can I ...?
|
22
|
+
|
23
|
+
### How can I do something with sent messages?
|
12
24
|
|
13
25
|
Use `Async::Task#wait` method.
|
14
26
|
|
@@ -22,11 +34,12 @@ message = channel.post("Hello world!").wait # => Message
|
|
22
34
|
message.pin
|
23
35
|
```
|
24
36
|
|
25
|
-
|
37
|
+
|
38
|
+
### How can I send DM to a user?
|
26
39
|
|
27
40
|
Use {Discorb::User#post} method, {Discorb::User} includes {Discorb::Messageable}.
|
28
41
|
|
29
|
-
|
42
|
+
### How can I edit status?
|
30
43
|
|
31
44
|
Use {Discorb::Client#update_presence} method.
|
32
45
|
|
@@ -47,7 +60,7 @@ client.on :ready do
|
|
47
60
|
end
|
48
61
|
```
|
49
62
|
|
50
|
-
|
63
|
+
### How can I send files?
|
51
64
|
|
52
65
|
Use {Discorb::File} class.
|
53
66
|
|
@@ -62,6 +75,15 @@ message.channel.post "File!", files: [Discorb::File.new(File.open("./README.md")
|
|
62
75
|
message.channel.post file: Discorb::File.from_string("Hello world!", "hello.txt")
|
63
76
|
```
|
64
77
|
|
78
|
+
### How can I add reactions?
|
79
|
+
|
80
|
+
Use {Discorb::Message#add_reaction} method.
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
message.add_reaction Discorb::UnicodeEmoji["🤔"]
|
84
|
+
message.add_reaction Discorb::UnicodeEmoji["thinking"]
|
85
|
+
```
|
86
|
+
|
65
87
|
# Not fequently asked questions
|
66
88
|
|
67
89
|
## How can I pronounce `discorb`?
|
data/docs/tutorial.md
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
# Tutorial
|
4
4
|
|
5
|
-
Welcome to discorb! This lib allows you to create a discord bot with
|
5
|
+
Welcome to discorb! This lib allows you to create a discord bot with Ruby.
|
6
|
+
Let's get started!
|
6
7
|
|
7
8
|
## Requirements
|
8
9
|
|
@@ -22,6 +23,7 @@ Welcome to discorb! This lib allows you to create a discord bot with ease. So, l
|
|
22
23
|
- [Sublime Text](https://www.sublimetext.com/)
|
23
24
|
- [Brackets](https://brackets.io/)
|
24
25
|
- [Notepad++](https://notepad-plus-plus.org/)
|
26
|
+
- [Vim](https://www.vim.org/)
|
25
27
|
- Git
|
26
28
|
- Bundler
|
27
29
|
|
@@ -74,7 +76,7 @@ Create a new directory and go to it.
|
|
74
76
|
Open terminal and type:
|
75
77
|
|
76
78
|
```
|
77
|
-
discorb
|
79
|
+
discorb new
|
78
80
|
```
|
79
81
|
|
80
82
|
Specify `--git` if you want to use git.
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require "discorb"
|
2
2
|
|
3
|
-
class MessageExpander
|
3
|
+
class MessageExpander
|
4
|
+
include Discorb::Extension
|
5
|
+
|
4
6
|
@@message_regex = Regexp.new(
|
5
7
|
'(?!<)https://(?:ptb\.|canary\.)?discord(?:app)?\.com/channels/' \
|
6
8
|
"(?<guild>[0-9]{18})/(?<channel>[0-9]{18})/(?<message>[0-9]{18})(?!>)"
|
data/lib/discorb/app_command.rb
CHANGED
@@ -25,6 +25,8 @@ module Discorb
|
|
25
25
|
# | `:type` | `Object` | Type of the option. |
|
26
26
|
# | `:choice` | `Hash{String => String, Integer, Float}` | Type of the option. |
|
27
27
|
# | `:default` | `Object` | Default value of the option. |
|
28
|
+
# | `:channel_types` | `Array<Class<Discorb::Channel>>` | Type of the channel option. |
|
29
|
+
# | `:autocomplete` | `Proc` | Autocomplete function. |
|
28
30
|
#
|
29
31
|
# @param [Array<#to_s>, false, nil] guild_ids Guild IDs to set the command to. `false` to global command, `nil` to use default.
|
30
32
|
# @param [Proc] block Command block.
|
@@ -235,9 +237,12 @@ module Discorb
|
|
235
237
|
description: value[:description],
|
236
238
|
required: value[:required].nil? ? !value[:optional] : value[:required],
|
237
239
|
}
|
238
|
-
|
239
|
-
|
240
|
-
|
240
|
+
|
241
|
+
ret[:choices] = value[:choices].map { |t| { name: t[0], value: t[1] } } if value[:choices]
|
242
|
+
|
243
|
+
ret[:channel_types] = value[:channel_types].map(&:channel_type) if value[:channel_types]
|
244
|
+
|
245
|
+
ret[:autocomplete] = !!value[:autocomplete] if value[:autocomplete]
|
241
246
|
ret
|
242
247
|
end
|
243
248
|
{
|
data/lib/discorb/client.rb
CHANGED
@@ -52,6 +52,8 @@ module Discorb
|
|
52
52
|
attr_reader :status
|
53
53
|
# @return [Integer] The session ID of connection.
|
54
54
|
attr_reader :session_id
|
55
|
+
# @return [Hash{String => Discorb::Extension}] The loaded extensions.
|
56
|
+
attr_reader :extensions
|
55
57
|
# @private
|
56
58
|
attr_reader :bottom_commands
|
57
59
|
|
@@ -97,6 +99,7 @@ module Discorb
|
|
97
99
|
@status = :initialized
|
98
100
|
@fetch_member = fetch_member
|
99
101
|
@title = title
|
102
|
+
@extensions = {}
|
100
103
|
set_default_events
|
101
104
|
end
|
102
105
|
|
@@ -369,12 +372,19 @@ module Discorb
|
|
369
372
|
#
|
370
373
|
# Load the extension.
|
371
374
|
#
|
372
|
-
# @param [Class] ext The extension to load.
|
375
|
+
# @param [Class, Discorb::Extension] ext The extension to load.
|
373
376
|
# @param [Object] ... The arguments to pass to the `ext#initialize`.
|
374
377
|
#
|
375
378
|
def load_extension(ext, ...)
|
376
|
-
|
377
|
-
|
379
|
+
if ext.is_a?(Class)
|
380
|
+
raise ArgumentError, "#{ext} is not a extension" unless ext < Discorb::Extension
|
381
|
+
ins = ext.new(self, ...)
|
382
|
+
elsif ext.is_a?(Discorb::Extension)
|
383
|
+
ins = ext
|
384
|
+
else
|
385
|
+
raise ArgumentError, "#{ext} is not a extension"
|
386
|
+
end
|
387
|
+
|
378
388
|
@events.each_value do |event|
|
379
389
|
event.delete_if { |c| c.metadata[:extension] == ins.class.name }
|
380
390
|
end
|
@@ -391,7 +401,11 @@ module Discorb
|
|
391
401
|
cmd.define_singleton_method(:extension) { ins.name }
|
392
402
|
@commands << cmd
|
393
403
|
end
|
404
|
+
|
405
|
+
cls = ins.class
|
406
|
+
cls.loaded(self, ...) if cls.respond_to? :loaded
|
394
407
|
@bottom_commands += ins.class.bottom_commands
|
408
|
+
@extensions[ins.class.name] = ins
|
395
409
|
ins
|
396
410
|
end
|
397
411
|
|
data/lib/discorb/common.rb
CHANGED
@@ -4,7 +4,7 @@ module Discorb
|
|
4
4
|
# @return [String] The API base URL.
|
5
5
|
API_BASE_URL = "https://discord.com/api/v9"
|
6
6
|
# @return [String] The version of discorb.
|
7
|
-
VERSION = "0.
|
7
|
+
VERSION = "0.11.0"
|
8
8
|
# @return [String] The user agent for the bot.
|
9
9
|
USER_AGENT = "DiscordBot (https://discorb-lib.github.io #{VERSION}) Ruby/#{RUBY_VERSION}"
|
10
10
|
|
data/lib/discorb/components.rb
CHANGED
data/lib/discorb/exe/run.rb
CHANGED
@@ -22,6 +22,7 @@ options = {
|
|
22
22
|
log_color: nil,
|
23
23
|
setup: nil,
|
24
24
|
token: false,
|
25
|
+
bundler: :default,
|
25
26
|
}
|
26
27
|
opt.on("-l", "--log-level LEVEL", "Log level.") do |v|
|
27
28
|
unless LOG_LEVELS.include? v.downcase
|
@@ -36,6 +37,7 @@ opt.on("-c", "--[no-]log-color", "Whether to colorize log output.") { |v| option
|
|
36
37
|
opt.on("-s", "--setup", "Whether to setup application commands.") { |v| options[:setup] = v }
|
37
38
|
opt.on("-e", "--env [ENV]", "The name of the environment variable to use for token, or just `-e` or `--env` for intractive prompt.") { |v| options[:token] = v }
|
38
39
|
opt.on("-t", "--title TITLE", "The title of process.") { |v| options[:title] = v }
|
40
|
+
opt.on("-b", "--[no-]bundler", "Whether to use bundler. Default to true if Gemfile exists, otherwise false.") { |v| options[:bundler] = v }
|
39
41
|
opt.parse!(ARGV)
|
40
42
|
|
41
43
|
script = ARGV[0]
|
@@ -54,10 +56,25 @@ elsif options[:token].nil? || options[:token] == "-"
|
|
54
56
|
puts ""
|
55
57
|
end
|
56
58
|
|
59
|
+
if options[:bundler] == :default
|
60
|
+
dir = Dir.pwd.split("/")
|
61
|
+
options[:bundler] = false
|
62
|
+
dir.length.times.reverse_each do |i|
|
63
|
+
if File.exist? "#{dir[0..i].join("/")}/Gemfile"
|
64
|
+
options[:bundler] = true
|
65
|
+
break
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
57
70
|
ENV["DISCORB_CLI_TITLE"] = options[:title]
|
58
71
|
|
59
|
-
|
60
|
-
|
61
|
-
|
72
|
+
if File.exist? script
|
73
|
+
if options[:bundler]
|
74
|
+
exec "bundle exec ruby #{script}"
|
75
|
+
else
|
76
|
+
exec "ruby #{script}"
|
77
|
+
end
|
78
|
+
else
|
62
79
|
eputs "Could not load script: \e[31m#{script}\e[91m"
|
63
80
|
end
|
data/lib/discorb/extension.rb
CHANGED
@@ -3,15 +3,11 @@
|
|
3
3
|
module Discorb
|
4
4
|
#
|
5
5
|
# Abstract class to make extension.
|
6
|
-
#
|
6
|
+
# Include from this module to make your own extension.
|
7
7
|
# @see file:docs/extension.md
|
8
8
|
# @abstract
|
9
9
|
#
|
10
|
-
|
11
|
-
extend Discorb::ApplicationCommand::Handler
|
12
|
-
|
13
|
-
@events = {}
|
14
|
-
|
10
|
+
module Extension
|
15
11
|
def initialize(client)
|
16
12
|
@client = client
|
17
13
|
end
|
@@ -27,7 +23,12 @@ module Discorb
|
|
27
23
|
@events = ret
|
28
24
|
end
|
29
25
|
|
30
|
-
|
26
|
+
def self.included(base)
|
27
|
+
base.extend(ClassMethods)
|
28
|
+
end
|
29
|
+
|
30
|
+
module ClassMethods
|
31
|
+
include Discorb::ApplicationCommand::Handler
|
31
32
|
undef setup_commands
|
32
33
|
|
33
34
|
#
|
@@ -69,7 +70,7 @@ module Discorb
|
|
69
70
|
# @private
|
70
71
|
attr_reader :bottom_commands
|
71
72
|
|
72
|
-
def
|
73
|
+
def self.extended(klass)
|
73
74
|
klass.instance_variable_set(:@commands, [])
|
74
75
|
klass.instance_variable_set(:@bottom_commands, [])
|
75
76
|
klass.instance_variable_set(:@events, {})
|
data/lib/discorb/http.rb
CHANGED
@@ -36,13 +36,7 @@ module Discorb
|
|
36
36
|
resp = http.get(get_path(path), get_headers(headers, "", audit_log_reason), **kwargs)
|
37
37
|
data = get_response_data(resp)
|
38
38
|
@ratelimit_handler.save("GET", path, resp)
|
39
|
-
|
40
|
-
@client.log.warn "Ratelimit exceeded for #{path}, trying again in #{data[:retry_after]} seconds."
|
41
|
-
task.sleep(data[:retry_after])
|
42
|
-
get(path, headers: headers, audit_log_reason: audit_log_reason, **kwargs).wait
|
43
|
-
else
|
44
|
-
[resp, data]
|
45
|
-
end)
|
39
|
+
handle_response(:patch, resp, data, path, nil, headers, audit_log_reason, kwargs)
|
46
40
|
end
|
47
41
|
end
|
48
42
|
|
@@ -67,12 +61,7 @@ module Discorb
|
|
67
61
|
resp = http.post(get_path(path), get_body(body), get_headers(headers, body, audit_log_reason), **kwargs)
|
68
62
|
data = get_response_data(resp)
|
69
63
|
@ratelimit_handler.save("POST", path, resp)
|
70
|
-
|
71
|
-
task.sleep(data[:retry_after])
|
72
|
-
post(path, body, headers: headers, audit_log_reason: audit_log_reason, **kwargs).wait
|
73
|
-
else
|
74
|
-
[resp, data]
|
75
|
-
end)
|
64
|
+
handle_response(:post, resp, data, path, body, headers, audit_log_reason, kwargs)
|
76
65
|
end
|
77
66
|
end
|
78
67
|
|
@@ -97,12 +86,7 @@ module Discorb
|
|
97
86
|
resp = http.patch(get_path(path), get_body(body), get_headers(headers, body, audit_log_reason), **kwargs)
|
98
87
|
data = get_response_data(resp)
|
99
88
|
@ratelimit_handler.save("PATCH", path, resp)
|
100
|
-
|
101
|
-
task.sleep(data[:retry_after])
|
102
|
-
patch(path, body, headers: headers, audit_log_reason: audit_log_reason, **kwargs).wait
|
103
|
-
else
|
104
|
-
[resp, data]
|
105
|
-
end)
|
89
|
+
handle_response(:patch, resp, data, path, body, headers, audit_log_reason, kwargs)
|
106
90
|
end
|
107
91
|
end
|
108
92
|
|
@@ -127,12 +111,7 @@ module Discorb
|
|
127
111
|
resp = http.put(get_path(path), get_body(body), get_headers(headers, body, audit_log_reason), **kwargs)
|
128
112
|
data = get_response_data(resp)
|
129
113
|
@ratelimit_handler.save("PUT", path, resp)
|
130
|
-
|
131
|
-
task.sleep(data[:retry_after])
|
132
|
-
put(path, body, headers: headers, audit_log_reason: audit_log_reason, **kwargs).wait
|
133
|
-
else
|
134
|
-
[resp, data]
|
135
|
-
end)
|
114
|
+
handle_response(:put, resp, data, path, body, headers, audit_log_reason, kwargs)
|
136
115
|
end
|
137
116
|
end
|
138
117
|
|
@@ -151,17 +130,12 @@ module Discorb
|
|
151
130
|
# @raise [Discorb::HTTPError] The request was failed.
|
152
131
|
#
|
153
132
|
def delete(path, headers: nil, audit_log_reason: nil, **kwargs)
|
154
|
-
Async do
|
133
|
+
Async do
|
155
134
|
@ratelimit_handler.wait("DELETE", path)
|
156
135
|
resp = http.delete(get_path(path), get_headers(headers, "", audit_log_reason))
|
157
136
|
data = get_response_data(resp)
|
158
137
|
@ratelimit_handler.save("DELETE", path, resp)
|
159
|
-
|
160
|
-
task.sleep(data[:retry_after])
|
161
|
-
delete(path, headers: headers, audit_log_reason: audit_log_reason, **kwargs).wait
|
162
|
-
else
|
163
|
-
[resp, data]
|
164
|
-
end)
|
138
|
+
handle_response(:delete, resp, data, path, nil, headers, audit_log_reason, kwargs)
|
165
139
|
end
|
166
140
|
end
|
167
141
|
|
@@ -198,9 +172,15 @@ module Discorb
|
|
198
172
|
|
199
173
|
private
|
200
174
|
|
201
|
-
def
|
202
|
-
resp, data = *ary
|
175
|
+
def handle_response(method, resp, data, path, body, headers, audit_log_reason, kwargs)
|
203
176
|
case resp.code
|
177
|
+
when "429"
|
178
|
+
sleep(data[:retry_after])
|
179
|
+
if body
|
180
|
+
__send__(method, path, body, headers: headers, audit_log_reason: audit_log_reason, **kwargs).wait
|
181
|
+
else
|
182
|
+
__send__(method, path, headers: headers, audit_log_reason: audit_log_reason, **kwargs).wait
|
183
|
+
end
|
204
184
|
when "400"
|
205
185
|
raise BadRequestError.new(resp, data)
|
206
186
|
when "401"
|
data/lib/discorb/integration.rb
CHANGED
data/lib/discorb/interaction.rb
CHANGED
@@ -364,7 +364,7 @@ module Discorb
|
|
364
364
|
end
|
365
365
|
|
366
366
|
unless (command = @client.bottom_commands.find { |c| c.to_s == name && c.type_raw == 1 })
|
367
|
-
@client.log.warn "Unknown command name #{name},
|
367
|
+
@client.log.warn "Unknown command name #{name}, ignoring"
|
368
368
|
next
|
369
369
|
end
|
370
370
|
|
@@ -451,6 +451,87 @@ module Discorb
|
|
451
451
|
end
|
452
452
|
end
|
453
453
|
|
454
|
+
#
|
455
|
+
# Represents auto complete interaction.
|
456
|
+
#
|
457
|
+
class AutoComplete < Interaction
|
458
|
+
@interaction_type = 4
|
459
|
+
@interaction_name = :auto_complete
|
460
|
+
|
461
|
+
def _set_data(data)
|
462
|
+
super
|
463
|
+
Sync do
|
464
|
+
name = data[:name]
|
465
|
+
options = nil
|
466
|
+
if (option = data[:options]&.first)
|
467
|
+
case option[:type]
|
468
|
+
when 1
|
469
|
+
name += " #{option[:name]}"
|
470
|
+
options = option[:options]
|
471
|
+
when 2
|
472
|
+
name += " #{option[:name]}"
|
473
|
+
if (option_sub = option[:options]&.first)
|
474
|
+
if option_sub[:type] == 1
|
475
|
+
name += " #{option_sub[:name]}"
|
476
|
+
options = option_sub[:options]
|
477
|
+
else
|
478
|
+
options = option[:options]
|
479
|
+
end
|
480
|
+
end
|
481
|
+
else
|
482
|
+
options = data[:options]
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
unless (command = @client.bottom_commands.find { |c| c.to_s == name && c.type_raw == 1 })
|
487
|
+
@client.log.warn "Unknown command name #{name}, ignoring"
|
488
|
+
next
|
489
|
+
end
|
490
|
+
|
491
|
+
option_map = command.options.map { |k, v| [k.to_s, v[:default]] }.to_h
|
492
|
+
options ||= []
|
493
|
+
options.each_with_index do |option|
|
494
|
+
val = case option[:type]
|
495
|
+
when 3, 4, 5, 10
|
496
|
+
option[:value]
|
497
|
+
when 6
|
498
|
+
guild.members[option[:value]] || guild.fetch_member(option[:value]).wait
|
499
|
+
when 7
|
500
|
+
guild.channels[option[:value]] || guild.fetch_channels.wait.find { |channel| channel.id == option[:value] }
|
501
|
+
when 8
|
502
|
+
guild.roles[option[:value]] || guild.fetch_roles.wait.find { |role| role.id == option[:value] }
|
503
|
+
when 9
|
504
|
+
guild.members[option[:value]] || guild.roles[option[:value]] || guild.fetch_member(option[:value]).wait || guild.fetch_roles.wait.find { |role| role.id == option[:value] }
|
505
|
+
end
|
506
|
+
option_map[option[:name]] = val
|
507
|
+
end
|
508
|
+
focused_index = options.find_index { |o| o[:focused] }
|
509
|
+
val = command.options.values[focused_index][:autocomplete]&.call(self, *command.options.map { |k, v| option_map[k.to_s] })
|
510
|
+
send_complete_result(val)
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
def send_complete_result(val)
|
515
|
+
@client.http.post("/interactions/#{@id}/#{@token}/callback", {
|
516
|
+
type: 8,
|
517
|
+
data: {
|
518
|
+
choices: val.map do |vk, vv|
|
519
|
+
{
|
520
|
+
name: vk,
|
521
|
+
value: vv,
|
522
|
+
}
|
523
|
+
end,
|
524
|
+
},
|
525
|
+
}).wait
|
526
|
+
rescue Discorb::NotFoundError
|
527
|
+
@client.log.warn "Failed to send auto complete result, This may be caused by the suggestion is taking too long (over 3 seconds) to respond", fallback: $stderr
|
528
|
+
end
|
529
|
+
|
530
|
+
class << self
|
531
|
+
alias make_interaction new
|
532
|
+
end
|
533
|
+
end
|
534
|
+
|
454
535
|
#
|
455
536
|
# Represents a message component interaction.
|
456
537
|
# @abstract
|
data/lib/discorb/member.rb
CHANGED
@@ -71,21 +71,12 @@ module Discorb
|
|
71
71
|
_set_data(user_data, member_data)
|
72
72
|
end
|
73
73
|
|
74
|
-
#
|
75
|
-
# Format the member to `@name` style.
|
76
|
-
#
|
77
|
-
# @return [String] The formatted member.
|
78
|
-
#
|
79
|
-
def to_s
|
80
|
-
"@#{name}"
|
81
|
-
end
|
82
|
-
|
83
74
|
#
|
84
75
|
# Format the member to `Username#Discriminator` style.
|
85
76
|
#
|
86
77
|
# @return [String] The formatted member.
|
87
78
|
#
|
88
|
-
def
|
79
|
+
def to_s
|
89
80
|
"#{username}##{discriminator}"
|
90
81
|
end
|
91
82
|
|
data/lib/discorb/modules.rb
CHANGED
@@ -94,7 +94,7 @@ module Discorb
|
|
94
94
|
#
|
95
95
|
def delete_message!(message_id, reason: nil)
|
96
96
|
Async do
|
97
|
-
@client.http.delete("/channels/#{channel_id.wait}/messages/#{message_id}",
|
97
|
+
@client.http.delete("/channels/#{channel_id.wait}/messages/#{message_id}", audit_log_reason: reason).wait
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
data/lib/discorb/rate_limit.rb
CHANGED
@@ -11,6 +11,7 @@ module Discorb
|
|
11
11
|
@client = client
|
12
12
|
@ratelimit_hash = {}
|
13
13
|
@path_ratelimit_hash = {}
|
14
|
+
@global = false
|
14
15
|
end
|
15
16
|
|
16
17
|
#
|
@@ -22,6 +23,14 @@ module Discorb
|
|
22
23
|
def wait(method, path)
|
23
24
|
return if path.start_with?("https://")
|
24
25
|
|
26
|
+
if @global
|
27
|
+
time = b[:reset_at] - Time.now.to_i
|
28
|
+
@client.log.info("Global ratelimit reached, waiting #{time} seconds")
|
29
|
+
sleep(time)
|
30
|
+
@global = false
|
31
|
+
|
32
|
+
end
|
33
|
+
|
25
34
|
return unless hash = @path_ratelimit_hash[method + path]
|
26
35
|
|
27
36
|
return unless b = @ratelimit_hash[hash]
|
@@ -32,8 +41,9 @@ module Discorb
|
|
32
41
|
end
|
33
42
|
return if b[:remaining] > 0
|
34
43
|
|
35
|
-
|
36
|
-
|
44
|
+
time = b[:reset_at] - Time.now.to_i
|
45
|
+
@client.log.info("Ratelimit reached, waiting #{time} seconds")
|
46
|
+
sleep(time)
|
37
47
|
end
|
38
48
|
|
39
49
|
#
|
@@ -44,6 +54,9 @@ module Discorb
|
|
44
54
|
# @param [Net::HTTPResponse] resp The response.
|
45
55
|
#
|
46
56
|
def save(method, path, resp)
|
57
|
+
if resp["X-Ratelimit-Global"] == "true"
|
58
|
+
@global = Time.now.to_i + JSON.parse(resp.body, symbolize_names: true)[:retry_after]
|
59
|
+
end
|
47
60
|
return unless resp["X-RateLimit-Remaining"]
|
48
61
|
|
49
62
|
@path_ratelimit_hash[method + path] = resp["X-RateLimit-Bucket"]
|
data/lib/discorb/role.rb
CHANGED
@@ -26,6 +26,10 @@ module Discorb
|
|
26
26
|
# @return [Boolean] Whether the role is a default role.
|
27
27
|
attr_reader :mentionable
|
28
28
|
alias mentionable? mentionable
|
29
|
+
# @return [Discorb::Asset, nil] The icon of the role.
|
30
|
+
attr_reader :custom_icon
|
31
|
+
# @return [Discorb::Emoji, nil] The emoji of the role.
|
32
|
+
attr_reader :emoji
|
29
33
|
|
30
34
|
# @!attribute [r] mention
|
31
35
|
# @return [String] The mention of the role.
|
@@ -33,6 +37,8 @@ module Discorb
|
|
33
37
|
# @return [Boolean] Whether the role has a color.
|
34
38
|
# @!attribute [r] tag
|
35
39
|
# @return [Discorb::Role::Tag] The tag of the role.
|
40
|
+
# @!attribute [r] icon
|
41
|
+
# @return [Discorb::Asset, Discorb::Emoji] The icon of the role.
|
36
42
|
|
37
43
|
include Comparable
|
38
44
|
|
@@ -44,6 +50,10 @@ module Discorb
|
|
44
50
|
_set_data(data)
|
45
51
|
end
|
46
52
|
|
53
|
+
def icon
|
54
|
+
@custom_icon || @emoji
|
55
|
+
end
|
56
|
+
|
47
57
|
#
|
48
58
|
# Compares two roles by their position.
|
49
59
|
#
|
@@ -88,7 +98,7 @@ module Discorb
|
|
88
98
|
#
|
89
99
|
def move(position, reason: nil)
|
90
100
|
Async do
|
91
|
-
@client.http.patch("/guilds/#{@
|
101
|
+
@client.http.patch("/guilds/#{@guild.id}/roles", { id: @id, position: position }, audit_log_reason: reason).wait
|
92
102
|
end
|
93
103
|
end
|
94
104
|
|
@@ -103,9 +113,10 @@ module Discorb
|
|
103
113
|
# @param [Discorb::Color] color The new color of the role.
|
104
114
|
# @param [Boolean] hoist Whether the role should be hoisted.
|
105
115
|
# @param [Boolean] mentionable Whether the role should be mentionable.
|
116
|
+
# @param [Discorb::Image, Discorb::UnicodeEmoji] icon The new icon or emoji of the role.
|
106
117
|
# @param [String] reason The reason for editing the role.
|
107
118
|
#
|
108
|
-
def edit(name: :unset, position: :unset, color: :unset, hoist: :unset, mentionable: :unset, reason: nil)
|
119
|
+
def edit(name: :unset, position: :unset, color: :unset, hoist: :unset, mentionable: :unset, icon: :unset, reason: nil)
|
109
120
|
Async do
|
110
121
|
payload = {}
|
111
122
|
payload[:name] = name if name != :unset
|
@@ -113,7 +124,14 @@ module Discorb
|
|
113
124
|
payload[:color] = color.to_i if color != :unset
|
114
125
|
payload[:hoist] = hoist if hoist != :unset
|
115
126
|
payload[:mentionable] = mentionable if mentionable != :unset
|
116
|
-
|
127
|
+
if icon != :unset
|
128
|
+
if icon.is_a?(Discorb::Image)
|
129
|
+
payload[:icon] = icon.to_s
|
130
|
+
else
|
131
|
+
payload[:unicode_emoji] = icon.to_s
|
132
|
+
end
|
133
|
+
end
|
134
|
+
@client.http.patch("/guilds/#{@guild.id}/roles/#{@id}", payload, audit_log_reason: reason).wait
|
117
135
|
end
|
118
136
|
end
|
119
137
|
|
@@ -126,7 +144,7 @@ module Discorb
|
|
126
144
|
#
|
127
145
|
def delete!(reason: nil)
|
128
146
|
Async do
|
129
|
-
@client.http.delete("/guilds/#{@
|
147
|
+
@client.http.delete("/guilds/#{@guild.id}/roles/#{@id}", audit_log_reason: reason).wait
|
130
148
|
end
|
131
149
|
end
|
132
150
|
|
@@ -182,6 +200,8 @@ module Discorb
|
|
182
200
|
@managed = data[:managed]
|
183
201
|
@mentionable = data[:mentionable]
|
184
202
|
@tags = data[:tags] || {}
|
203
|
+
@custom_icon = data[:icon] ? Asset.new(self, data[:icon], path: "role-icons/#{@id}") : nil
|
204
|
+
@emoji = data[:unicode_emoji] ? UnicodeEmoji.new(data[:unicode_emoji]) : nil
|
185
205
|
@guild.roles[@id] = self unless data[:no_cache]
|
186
206
|
@data.update(data)
|
187
207
|
end
|
data/lib/discorb/voice_state.rb
CHANGED
@@ -193,7 +193,7 @@ module Discorb
|
|
193
193
|
#
|
194
194
|
def delete!(reason: nil)
|
195
195
|
Async do
|
196
|
-
@client.http.delete("/stage-instances/#{@channel_id}",
|
196
|
+
@client.http.delete("/stage-instances/#{@channel_id}", audit_log_reason: reason).wait
|
197
197
|
self
|
198
198
|
end
|
199
199
|
end
|
@@ -4,7 +4,12 @@ def build_version_sidebar(dir, version)
|
|
4
4
|
raw.gsub!(template, "")
|
5
5
|
res = +""
|
6
6
|
i = 0
|
7
|
-
`git tag
|
7
|
+
`git tag`
|
8
|
+
.force_encoding("utf-8")
|
9
|
+
.split("\n")
|
10
|
+
.sort_by { |v| Gem::Version.new(v[1..]) }
|
11
|
+
.reverse
|
12
|
+
.each.with_index do |tag|
|
8
13
|
i += 1
|
9
14
|
sha = `git rev-parse #{tag}`.force_encoding("utf-8").strip
|
10
15
|
tag_version = tag.delete_prefix("v")
|
@@ -32,7 +37,7 @@ def build_version_sidebar(dir, version)
|
|
32
37
|
cls = i % 2 == 0 ? "even" : "odd"
|
33
38
|
res.insert 0, template
|
34
39
|
.gsub("!version!", "Latest")
|
35
|
-
.gsub("!path!", "
|
40
|
+
.gsub("!path!", "")
|
36
41
|
.gsub("!class!", cls)
|
37
42
|
.gsub("!sha!", "Latest on RubyGems")
|
38
43
|
File.write(dir + "/version_list.html", raw.gsub("<!--replace-->", res))
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: discorb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sevenc-nanashi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-10-
|
11
|
+
date: 2021-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|
@@ -142,8 +142,8 @@ files:
|
|
142
142
|
- lib/discorb/error.rb
|
143
143
|
- lib/discorb/event.rb
|
144
144
|
- lib/discorb/exe/about.rb
|
145
|
-
- lib/discorb/exe/init.rb
|
146
145
|
- lib/discorb/exe/irb.rb
|
146
|
+
- lib/discorb/exe/new.rb
|
147
147
|
- lib/discorb/exe/run.rb
|
148
148
|
- lib/discorb/exe/setup.rb
|
149
149
|
- lib/discorb/exe/show.rb
|