discorb 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|