discorb 0.12.2 → 0.13.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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_main.yml +1 -0
  3. data/.github/workflows/build_version.yml +1 -0
  4. data/.github/workflows/crowdin.yml +32 -0
  5. data/.gitignore +3 -1
  6. data/.yardopts +2 -0
  7. data/Changelog.md +399 -367
  8. data/Gemfile +5 -1
  9. data/README.md +1 -1
  10. data/Rakefile +139 -9
  11. data/crowdin.yml +2 -0
  12. data/discorb.gemspec +1 -1
  13. data/docs/Examples.md +2 -0
  14. data/docs/application_command.md +17 -12
  15. data/docs/cli/irb.md +2 -0
  16. data/docs/cli/new.md +2 -0
  17. data/docs/cli/run.md +3 -1
  18. data/docs/cli/setup.md +4 -2
  19. data/docs/cli.md +2 -0
  20. data/docs/events.md +59 -5
  21. data/docs/extension.md +2 -2
  22. data/docs/faq.md +4 -2
  23. data/docs/license.md +2 -0
  24. data/docs/tutorial.md +4 -3
  25. data/docs/voice_events.md +2 -0
  26. data/lib/discorb/app_command.rb +13 -7
  27. data/lib/discorb/application.rb +32 -2
  28. data/lib/discorb/audit_logs.rb +28 -16
  29. data/lib/discorb/channel.rb +112 -81
  30. data/lib/discorb/client.rb +17 -19
  31. data/lib/discorb/common.rb +28 -1
  32. data/lib/discorb/components.rb +12 -0
  33. data/lib/discorb/dictionary.rb +1 -1
  34. data/lib/discorb/embed.rb +4 -0
  35. data/lib/discorb/emoji.rb +9 -7
  36. data/lib/discorb/emoji_table.rb +3774 -3689
  37. data/lib/discorb/event.rb +266 -24
  38. data/lib/discorb/event_handler.rb +39 -0
  39. data/lib/discorb/exe/show.rb +2 -0
  40. data/lib/discorb/extension.rb +5 -5
  41. data/lib/discorb/file.rb +4 -0
  42. data/lib/discorb/flag.rb +5 -1
  43. data/lib/discorb/gateway.rb +65 -14
  44. data/lib/discorb/gateway_requests.rb +4 -0
  45. data/lib/discorb/guild.rb +169 -82
  46. data/lib/discorb/guild_template.rb +12 -9
  47. data/lib/discorb/http.rb +82 -37
  48. data/lib/discorb/image.rb +7 -5
  49. data/lib/discorb/integration.rb +4 -1
  50. data/lib/discorb/intents.rb +8 -3
  51. data/lib/discorb/interaction/autocomplete.rb +1 -1
  52. data/lib/discorb/interaction/command.rb +2 -2
  53. data/lib/discorb/interaction/response.rb +27 -25
  54. data/lib/discorb/interaction/root.rb +8 -0
  55. data/lib/discorb/invite.rb +3 -2
  56. data/lib/discorb/log.rb +4 -0
  57. data/lib/discorb/member.rb +42 -13
  58. data/lib/discorb/message.rb +32 -17
  59. data/lib/discorb/modules.rb +19 -26
  60. data/lib/discorb/permission.rb +4 -0
  61. data/lib/discorb/rate_limit.rb +6 -2
  62. data/lib/discorb/role.rb +15 -11
  63. data/lib/discorb/sticker.rb +17 -12
  64. data/lib/discorb/user.rb +8 -7
  65. data/lib/discorb/voice_state.rb +8 -5
  66. data/lib/discorb/webhook.rb +38 -47
  67. data/lib/discorb.rb +2 -2
  68. data/po/yard.pot +7775 -5157
  69. data/sig/discorb.rbs +3317 -3820
  70. data/template-replace/scripts/locale_ja.rb +62 -0
  71. data/template-replace/scripts/yard_replace.rb +6 -0
  72. metadata +7 -4
@@ -29,6 +29,10 @@ module Discorb
29
29
  @replied_user = replied_user
30
30
  end
31
31
 
32
+ def inspect
33
+ "#<#{self.class} @everyone=#{@everyone} @roles=#{@roles} @users=#{@users} @replied_user=#{@replied_user}>"
34
+ end
35
+
32
36
  # @private
33
37
  def to_hash(other = nil)
34
38
  payload = {
@@ -290,6 +294,7 @@ module Discorb
290
294
 
291
295
  #
292
296
  # Edit the message.
297
+ # @async
293
298
  #
294
299
  # @param [String] content The message content.
295
300
  # @param [Discorb::Embed] embed The embed to send.
@@ -298,6 +303,8 @@ module Discorb
298
303
  # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
299
304
  # @param [Boolean] supress Whether to supress embeds.
300
305
  #
306
+ # @return [Async::Task<void>] The task.
307
+ #
301
308
  def edit(content = nil, embed: nil, embeds: nil, allowed_mentions: nil,
302
309
  components: nil, supress: nil)
303
310
  Async do
@@ -308,9 +315,12 @@ module Discorb
308
315
 
309
316
  #
310
317
  # Delete the message.
318
+ # @async
311
319
  #
312
320
  # @param [String] reason The reason for deleting the message.
313
321
  #
322
+ # @return [Async::Task<void>] The task.
323
+ #
314
324
  def delete!(reason: nil)
315
325
  Async do
316
326
  channel.delete_message!(@id, reason: reason).wait
@@ -338,8 +348,7 @@ module Discorb
338
348
  end
339
349
 
340
350
  # Reply to the message.
341
- # @macro async
342
- # @macro http
351
+ # @async
343
352
  # @param (see #post)
344
353
  # @return [Async::Task<Discorb::Message>] The message.
345
354
  def reply(*args, **kwargs)
@@ -350,8 +359,9 @@ module Discorb
350
359
 
351
360
  #
352
361
  # Publish the message.
353
- # @macro async
354
- # @macro http
362
+ # @async
363
+ #
364
+ # @return [Async::Task<void>] The task.
355
365
  #
356
366
  def publish
357
367
  Async do
@@ -361,11 +371,12 @@ module Discorb
361
371
 
362
372
  #
363
373
  # Add a reaction to the message.
364
- # @macro async
365
- # @macro http
374
+ # @async
366
375
  #
367
376
  # @param [Discorb::Emoji] emoji The emoji to react with.
368
377
  #
378
+ # @return [Async::Task<void>] The task.
379
+ #
369
380
  def add_reaction(emoji)
370
381
  Async do
371
382
  @client.http.put("/channels/#{@channel_id}/messages/#{@id}/reactions/#{emoji.to_uri}/@me", nil).wait
@@ -376,11 +387,12 @@ module Discorb
376
387
 
377
388
  #
378
389
  # Remove a reaction from the message.
379
- # @macro async
380
- # @macro http
390
+ # @async
381
391
  #
382
392
  # @param [Discorb::Emoji] emoji The emoji to remove.
383
393
  #
394
+ # @return [Async::Task<void>] The task.
395
+ #
384
396
  def remove_reaction(emoji)
385
397
  Async do
386
398
  @client.http.delete("/channels/#{@channel_id}/messages/#{@id}/reactions/#{emoji.to_uri}/@me").wait
@@ -391,12 +403,13 @@ module Discorb
391
403
 
392
404
  #
393
405
  # Remove other member's reaction from the message.
394
- # @macro async
395
- # @macro http
406
+ # @async
396
407
  #
397
408
  # @param [Discorb::Emoji] emoji The emoji to remove.
398
409
  # @param [Discorb::Member] member The member to remove the reaction from.
399
410
  #
411
+ # @return [Async::Task<void>] The task.
412
+ #
400
413
  def remove_reaction_of(emoji, member)
401
414
  Async do
402
415
  @client.http.delete("/channels/#{@channel_id}/messages/#{@id}/reactions/#{emoji.to_uri}/#{member.is_a?(Member) ? member.id : member}").wait
@@ -407,8 +420,7 @@ module Discorb
407
420
 
408
421
  #
409
422
  # Fetch reacted users of reaction.
410
- # @macro async
411
- # @macro http
423
+ # @async
412
424
  #
413
425
  # @param [Discorb::Emoji] emoji The emoji to fetch.
414
426
  # @param [Integer, nil] limit The maximum number of users to fetch. `nil` for no limit.
@@ -441,11 +453,12 @@ module Discorb
441
453
 
442
454
  #
443
455
  # Pin the message.
444
- # @macro async
445
- # @macro http
456
+ # @async
446
457
  #
447
458
  # @param [String] reason The reason for pinning the message.
448
459
  #
460
+ # @return [Async::Task<void>] The task.
461
+ #
449
462
  def pin(reason: nil)
450
463
  Async do
451
464
  channel.pin_message(self, reason: reason).wait
@@ -454,11 +467,12 @@ module Discorb
454
467
 
455
468
  #
456
469
  # Unpin the message.
457
- # @macro async
458
- # @macro http
470
+ # @async
459
471
  #
460
472
  # @param [String] reason The reason for unpinning the message.
461
473
  #
474
+ # @return [Async::Task<void>] The task.
475
+ #
462
476
  def unpin(reason: nil)
463
477
  Async do
464
478
  channel.unpin_message(self, reason: reason).wait
@@ -467,10 +481,11 @@ module Discorb
467
481
 
468
482
  #
469
483
  # Start thread from the message.
484
+ # @async
470
485
  #
471
486
  # @param (see Discorb::Channel#start_thread)
472
487
  #
473
- # @return [Async::Task<<Type>>] <description>
488
+ # @return [Async::Task<Discorb::ThreadChannel>] <description>
474
489
  #
475
490
  def start_thread(*args, **kwargs)
476
491
  Async do
@@ -7,8 +7,7 @@ module Discorb
7
7
  module Messageable
8
8
  #
9
9
  # Post a message to the channel.
10
- # @macro async
11
- # @macro http
10
+ # @async
12
11
  #
13
12
  # @param [String] content The message content.
14
13
  # @param [Boolean] tts Whether the message is tts.
@@ -38,14 +37,8 @@ module Discorb
38
37
  allowed_mentions ? allowed_mentions.to_hash(@client.allowed_mentions) : @client.allowed_mentions.to_hash
39
38
  payload[:message_reference] = reference.to_reference if reference
40
39
  payload[:components] = Component.to_payload(components) if components
41
- files = [file] if file
42
- if files
43
- seperator, payload = HTTP.multipart(payload, files)
44
- headers = { "content-type" => "multipart/form-data; boundary=#{seperator}" }
45
- else
46
- headers = {}
47
- end
48
- _resp, data = @client.http.post("/channels/#{channel_id.wait}/messages", payload, headers: headers).wait
40
+ files = [file]
41
+ _resp, data = @client.http.multipart_post("/channels/#{channel_id.wait}/messages", payload, files).wait
49
42
  Message.new(@client, data.merge({ guild_id: @guild_id.to_s }))
50
43
  end
51
44
  end
@@ -54,8 +47,7 @@ module Discorb
54
47
 
55
48
  #
56
49
  # Edit a message.
57
- # @macro async
58
- # @macro http
50
+ # @async
59
51
  #
60
52
  # @param [#to_s] message_id The message id.
61
53
  # @param [String] content The message content.
@@ -65,6 +57,8 @@ module Discorb
65
57
  # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
66
58
  # @param [Boolean] supress Whether to supress embeds.
67
59
  #
60
+ # @return [Async::Task<void>] The task.
61
+ #
68
62
  def edit_message(message_id, content = nil, embed: nil, embeds: nil, allowed_mentions: nil,
69
63
  components: nil, supress: nil)
70
64
  Async do
@@ -86,12 +80,13 @@ module Discorb
86
80
 
87
81
  #
88
82
  # Delete a message.
89
- # @macro async
90
- # @macro http
83
+ # @async
91
84
  #
92
85
  # @param [#to_s] message_id The message id.
93
86
  # @param [String] reason The reason for deleting the message.
94
87
  #
88
+ # @return [Async::Task<void>] The task.
89
+ #
95
90
  def delete_message!(message_id, reason: nil)
96
91
  Async do
97
92
  @client.http.delete("/channels/#{channel_id.wait}/messages/#{message_id}", audit_log_reason: reason).wait
@@ -102,8 +97,7 @@ module Discorb
102
97
 
103
98
  #
104
99
  # Fetch a message from ID.
105
- # @macro async
106
- # @macro http
100
+ # @async
107
101
  #
108
102
  # @param [Discorb::Snowflake] id The ID of the message.
109
103
  #
@@ -119,8 +113,7 @@ module Discorb
119
113
 
120
114
  #
121
115
  # Fetch a message history.
122
- # @macro async
123
- # @macro http
116
+ # @async
124
117
  #
125
118
  # @param [Integer] limit The number of messages to fetch.
126
119
  # @param [Discorb::Snowflake] before The ID of the message to fetch before.
@@ -144,8 +137,7 @@ module Discorb
144
137
 
145
138
  #
146
139
  # Fetch the pinned messages in the channel.
147
- # @macro async
148
- # @macro http
140
+ # @async
149
141
  #
150
142
  # @return [Async::Task<Array<Discorb::Message>>] The pinned messages in the channel.
151
143
  #
@@ -158,12 +150,13 @@ module Discorb
158
150
 
159
151
  #
160
152
  # Pin a message in the channel.
161
- # @macro async
162
- # @macro http
153
+ # @async
163
154
  #
164
155
  # @param [Discorb::Message] message The message to pin.
165
156
  # @param [String] reason The reason of pinning the message.
166
157
  #
158
+ # @return [Async::Task<void>] The task.
159
+ #
167
160
  def pin_message(message, reason: nil)
168
161
  Async do
169
162
  @client.http.put("/channels/#{channel_id.wait}/pins/#{message.id}", {}, audit_log_reason: reason).wait
@@ -172,12 +165,13 @@ module Discorb
172
165
 
173
166
  #
174
167
  # Unpin a message in the channel.
175
- # @macro async
176
- # @macro http
168
+ # @async
177
169
  #
178
170
  # @param [Discorb::Message] message The message to unpin.
179
171
  # @param [String] reason The reason of unpinning the message.
180
172
  #
173
+ # @return [Async::Task<void>] The task.
174
+ #
181
175
  def unpin_message(message, reason: nil)
182
176
  Async do
183
177
  @client.http.delete("/channels/#{channel_id.wait}/pins/#{message.id}", audit_log_reason: reason).wait
@@ -186,8 +180,7 @@ module Discorb
186
180
 
187
181
  #
188
182
  # Trigger the typing indicator in the channel.
189
- # @macro async
190
- # @macro http
183
+ # @async
191
184
  #
192
185
  # If block is given, trigger typing indicator during executing block.
193
186
  # @example
@@ -164,6 +164,10 @@ module Discorb
164
164
  @deny
165
165
  end
166
166
 
167
+ def inspect
168
+ "#<#{self.class} allow=#{allow} deny=#{deny}>"
169
+ end
170
+
167
171
  #
168
172
  # Converts the permission overwrite to a hash.
169
173
  #
@@ -14,6 +14,10 @@ module Discorb
14
14
  @global = false
15
15
  end
16
16
 
17
+ def inspect
18
+ "#<#{self.class}>"
19
+ end
20
+
17
21
  #
18
22
  # Wait for the rate limit to reset.
19
23
  #
@@ -23,8 +27,8 @@ module Discorb
23
27
  def wait(method, path)
24
28
  return if path.start_with?("https://")
25
29
 
26
- if @global
27
- time = b[:reset_at] - Time.now.to_f
30
+ if @global && @global > Time.now.to_f
31
+ time = @global - Time.now.to_f
28
32
  @client.log.info("global rate limit reached, waiting #{time} seconds")
29
33
  sleep(time)
30
34
  @global = false
data/lib/discorb/role.rb CHANGED
@@ -90,12 +90,13 @@ module Discorb
90
90
 
91
91
  #
92
92
  # Moves the role to a new position.
93
- # @macro async
94
- # @macro http
93
+ # @async
95
94
  #
96
95
  # @param [Integer] position The new position.
97
96
  # @param [String] reason The reason for moving the role.
98
97
  #
98
+ # @return [Async::Task<void>] The task.
99
+ #
99
100
  def move(position, reason: nil)
100
101
  Async do
101
102
  @client.http.patch("/guilds/#{@guild.id}/roles", { id: @id, position: position }, audit_log_reason: reason).wait
@@ -104,8 +105,7 @@ module Discorb
104
105
 
105
106
  #
106
107
  # Edits the role.
107
- # @macro async
108
- # @macro http
108
+ # @async
109
109
  # @macro edit
110
110
  #
111
111
  # @param [String] name The new name of the role.
@@ -116,15 +116,17 @@ module Discorb
116
116
  # @param [Discorb::Image, Discorb::UnicodeEmoji] icon The new icon or emoji of the role.
117
117
  # @param [String] reason The reason for editing the role.
118
118
  #
119
- def edit(name: :unset, position: :unset, color: :unset, hoist: :unset, mentionable: :unset, icon: :unset, reason: nil)
119
+ # @return [Async::Task<void>] The task.
120
+ #
121
+ def edit(name: Discorb::Unset, position: Discorb::Unset, color: Discorb::Unset, hoist: Discorb::Unset, mentionable: Discorb::Unset, icon: Discorb::Unset, reason: nil)
120
122
  Async do
121
123
  payload = {}
122
- payload[:name] = name if name != :unset
123
- payload[:position] = position if position != :unset
124
- payload[:color] = color.to_i if color != :unset
125
- payload[:hoist] = hoist if hoist != :unset
126
- payload[:mentionable] = mentionable if mentionable != :unset
127
- if icon != :unset
124
+ payload[:name] = name if name != Discorb::Unset
125
+ payload[:position] = position if position != Discorb::Unset
126
+ payload[:color] = color.to_i if color != Discorb::Unset
127
+ payload[:hoist] = hoist if hoist != Discorb::Unset
128
+ payload[:mentionable] = mentionable if mentionable != Discorb::Unset
129
+ if icon != Discorb::Unset
128
130
  if icon.is_a?(Discorb::Image)
129
131
  payload[:icon] = icon.to_s
130
132
  else
@@ -142,6 +144,8 @@ module Discorb
142
144
  #
143
145
  # @param [String] reason The reason for deleting the role.
144
146
  #
147
+ # @return [Async::Task<void>] The task.
148
+ #
145
149
  def delete!(reason: nil)
146
150
  Async do
147
151
  @client.http.delete("/guilds/#{@guild.id}/roles/#{@id}", audit_log_reason: reason).wait
@@ -51,6 +51,15 @@ module Discorb
51
51
  # @!attribute [r] guild
52
52
  # @macro client_cache
53
53
  # @return [Discorb::Guild] The guild the sticker is in.
54
+ @sticker_type = {
55
+ 1 => :official,
56
+ 2 => :guild,
57
+ }.freeze
58
+ @sticker_format = {
59
+ 1 => :png,
60
+ 2 => :apng,
61
+ 3 => :lottie,
62
+ }
54
63
 
55
64
  def guild
56
65
  @client.guilds[@guild_id]
@@ -58,8 +67,7 @@ module Discorb
58
67
 
59
68
  #
60
69
  # Edits the sticker.
61
- # @macro async
62
- # @macro http
70
+ # @async
63
71
  # @macro edit
64
72
  #
65
73
  # @param [String] name The new name of the sticker.
@@ -67,12 +75,14 @@ module Discorb
67
75
  # @param [Discorb::Emoji] tag The new tags of the sticker.
68
76
  # @param [String] reason The reason for the edit.
69
77
  #
70
- def edit(name: :unset, description: :unset, tag: :unset, reason: :unset)
78
+ # @return [Async::Task<void>] The task.
79
+ #
80
+ def edit(name: Discorb::Unset, description: Discorb::Unset, tag: Discorb::Unset, reason: Discorb::Unset)
71
81
  Async do
72
82
  payload = {}
73
- payload[:name] = name unless name == :unset
74
- payload[:description] = description unless description == :unset
75
- payload[:tags] = tag.name unless tag == :unset
83
+ payload[:name] = name unless name == Discorb::Unset
84
+ payload[:description] = description unless description == Discorb::Unset
85
+ payload[:tags] = tag.name unless tag == Discorb::Unset
76
86
  @client.http.patch("/guilds/#{@guild_id}/stickers/#{@id}", payload, audit_log_reason: reason).wait
77
87
  end
78
88
  end
@@ -81,8 +91,7 @@ module Discorb
81
91
 
82
92
  #
83
93
  # Deletes the sticker.
84
- # @macro async
85
- # @macro http
94
+ # @async
86
95
  #
87
96
  # @param [String] reason The reason for the deletion.
88
97
  #
@@ -103,14 +112,10 @@ module Discorb
103
112
  attr_reader :id
104
113
  # @return [String] The name of the sticker pack.
105
114
  attr_reader :name
106
- # @return [Discorb::Snowflake] The ID of the SKU.
107
- attr_reader :sku_id
108
115
  # @return [Discorb::Snowflake] The cover sticker of the pack.
109
116
  attr_reader :cover_sticker_id
110
117
  # @return [String] The description of the pack.
111
118
  attr_reader :description
112
- # @return [Discorb::Store::SKU] The banner asset ID of the pack.
113
- attr_reader :banner_asset_id
114
119
  # @return [Array<Discorb::Sticker>] The stickers in the pack.
115
120
  attr_reader :stickers
116
121
  # @return [Discorb::Asset] The banner of the pack.
data/lib/discorb/user.rb CHANGED
@@ -58,8 +58,7 @@ module Discorb
58
58
 
59
59
  #
60
60
  # Whether the user is a owner of the client.
61
- # @macro async
62
- # @macro http
61
+ # @async
63
62
  #
64
63
  # @param [Boolean] strict Whether don't allow if the user is a member of the team.
65
64
  #
@@ -123,6 +122,7 @@ module Discorb
123
122
  verified_bot: 16,
124
123
  early_verified_bot_developer: 17,
125
124
  discord_certified_moderator: 18,
125
+ bot_http_interactions: 19,
126
126
  }.freeze
127
127
  end
128
128
 
@@ -149,18 +149,19 @@ module Discorb
149
149
  class ClientUser < User
150
150
  #
151
151
  # Edit the client user.
152
- # @macro async
153
- # @macro http
152
+ # @async
154
153
  # @macro edit
155
154
  #
156
155
  # @param [String] name The new username.
157
156
  # @param [Discorb::Image] avatar The new avatar.
158
157
  #
159
- def edit(name: :unset, avatar: :unset)
158
+ # @return [Async::Task<void>] The task.
159
+ #
160
+ def edit(name: Discorb::Unset, avatar: Discorb::Unset)
160
161
  Async do
161
162
  payload = {}
162
- payload[:username] = name unless name == :unset
163
- if avatar == :unset
163
+ payload[:username] = name unless name == Discorb::Unset
164
+ if avatar == Discorb::Unset
164
165
  # Nothing
165
166
  elsif avatar.nil?
166
167
  payload[:avatar] = nil
@@ -166,19 +166,20 @@ module Discorb
166
166
 
167
167
  #
168
168
  # Edits the stage instance.
169
- # @macro async
170
- # @macro http
169
+ # @async
171
170
  # @macro edit
172
171
  #
173
172
  # @param [String] topic The new topic of the stage instance.
174
173
  # @param [:public, :guild_only] privacy_level The new privacy level of the stage instance.
175
174
  # @param [String] reason The reason for editing the stage instance.
176
175
  #
177
- def edit(topic: :unset, privacy_level: :unset, reason: nil)
176
+ # @return [Async::Task<void>] The task.
177
+ #
178
+ def edit(topic: Discorb::Unset, privacy_level: Discorb::Unset, reason: nil)
178
179
  Async do
179
180
  payload = {}
180
- payload[:topic] = topic if topic != :unset
181
- payload[:privacy_level] = self.class.privacy_level.key(privacy_level) if privacy_level != :unset
181
+ payload[:topic] = topic if topic != Discorb::Unset
182
+ payload[:privacy_level] = self.class.privacy_level.key(privacy_level) if privacy_level != Discorb::Unset
182
183
  @client.http.edit("/stage-instances/#{@channel_id}", payload, audit_log_reason: reason).wait
183
184
  self
184
185
  end
@@ -191,6 +192,8 @@ module Discorb
191
192
  #
192
193
  # @param [String] reason The reason for deleting the stage instance.
193
194
  #
195
+ # @return [Async::Task<void>] The task.
196
+ #
194
197
  def delete!(reason: nil)
195
198
  Async do
196
199
  @client.http.delete("/stage-instances/#{@channel_id}", audit_log_reason: reason).wait