discorb 0.14.0 → 0.15.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 810e9b14c77e49e9fca7afc4fe6b98389b26cb17dc1617213f38d7655b990a49
4
- data.tar.gz: bbaa999265ac212f90ab60d57ec772fe7ade0e47f264a136130c679b85a46952
3
+ metadata.gz: 497fc76081f6183ccd3ec7c14768e80d81a172c092afa67f26bcec625f7b204f
4
+ data.tar.gz: 5d0d4070c729b2b63d6a746fa559900b2205d51f737105d8c8653c59eec01e97
5
5
  SHA512:
6
- metadata.gz: 120828736edcf7eef9d78410914651edeb41ae85eadef012050b105b03c80f07f835d812105d3cfe954c7237e344b3bbc540af8840a7dde1a69f590b008a759e
7
- data.tar.gz: f29b0399c65f180b05bf6c0c3d5f253689ff08c734f60ee7681b57c060d99e36dd85fc275f9652354933478b8139aa76c8ad854f6963fd1c074a8a260ffb6bde
6
+ metadata.gz: bf93daa59116cbd29d408e361b0cebf0e4b681c21eb2e07466f2ea2659f7bec959a58c4bf168c8b5058bb4221bb26352770c94e6bc61a9713a82d72bf98316e8
7
+ data.tar.gz: aa07fe600a6397f69584a33d4b79dfd2d64952c4c1fff83a08a84418e0547a78c9b2261fce7e96a46bf19d4dab9ff0972ebe09b2ddf59371d5d74a761282c45e
@@ -33,7 +33,7 @@ jobs:
33
33
  git clone git@github.com:discorb-lib/discorb-lib.github.io /tmp/pages
34
34
  - name: Install dependencies
35
35
  run: |
36
- bundle config --local with 'docs development'
36
+ bundle config --local with 'docs development lint'
37
37
  bundle install
38
38
  gem update uri
39
39
  - name: Generate document
@@ -1,6 +1,8 @@
1
1
  name: Lint with RuboCop
2
2
  on:
3
- - push
3
+ push:
4
+ branches:
5
+ - main
4
6
  jobs:
5
7
  rubocop:
6
8
  runs-on: ubuntu-latest
@@ -15,4 +17,4 @@ jobs:
15
17
  gem install rubocop
16
18
  - name: Run rubocop
17
19
  run: |
18
- rubocop lib
20
+ rubocop lib
data/Changelog.md CHANGED
@@ -4,6 +4,15 @@
4
4
 
5
5
  # Changelog
6
6
 
7
+ ## v0.15
8
+
9
+ ### v0.15.0
10
+
11
+ - Add: Migrate to API v10
12
+ - Add: Add `TextChannel#threads`
13
+ - Add: Support editing attachments
14
+ - Delete!: Delete File class - Use Attachment class instead
15
+
7
16
  ## v0.14
8
17
 
9
18
  ### v0.14.0
data/docs/faq.md CHANGED
@@ -62,19 +62,19 @@ client.on :ready do
62
62
  end
63
63
  ```
64
64
 
65
- ### How can I send files?
65
+ ### How can I send attachments?
66
66
 
67
- Use {Discorb::File} class.
67
+ Use {Discorb::Attachment} class.
68
68
 
69
69
  ```ruby
70
- # Send a file
71
- message.channel.post file: Discorb::File.new(File.open("./README.md"))
70
+ # Send an attachment
71
+ message.channel.post attachment: Discorb::Attachment.new(File.open("./README.md"))
72
72
 
73
- # Send some files with text
74
- message.channel.post "File!", files: [Discorb::File.new(File.open("./README.md")), Discorb::File.new(File.open("./License.txt"))]
73
+ # Send some attachment with text
74
+ message.channel.post "File!", attachments: [Discorb::Attachment.new("./README.md"), Discorb::Attachment.new(File.open("./License.txt"))]
75
75
 
76
- # Send a string as a file
77
- message.channel.post file: Discorb::File.from_string("Hello world!", "hello.txt")
76
+ # Send a string as an attachment
77
+ message.channel.post attachments: Discorb::Attachment.from_string("Hello world!", "hello.txt")
78
78
  ```
79
79
 
80
80
  ### How can I add reactions?
@@ -7,15 +7,17 @@ module Discorb
7
7
  #
8
8
  # Represents a attachment file.
9
9
  #
10
- class Attachment < DiscordModel
10
+ class Attachment
11
11
  # @return [#read] The file content.
12
12
  attr_reader :io
13
- # @return [Discorb::Snowflake] The attachment id.
14
- attr_reader :id
15
13
  # @return [String] The attachment filename.
16
14
  attr_reader :filename
17
15
  # @return [String] The attachment content type.
18
16
  attr_reader :content_type
17
+ # @return [String] The attachment description.
18
+ attr_reader :description
19
+ # @return [Discorb::Snowflake] The attachment id.
20
+ attr_reader :id
19
21
  # @return [Integer] The attachment size in bytes.
20
22
  attr_reader :size
21
23
  # @return [String] The attachment url.
@@ -28,12 +30,40 @@ module Discorb
28
30
  # @return [Integer] The image width.
29
31
  # @return [nil] If the attachment is not an image.
30
32
  attr_reader :width
33
+ # @return [:client, :discord] The attachment was created by.
34
+ attr_reader :created_by
35
+ # @private
36
+ attr_reader :will_close
31
37
 
32
38
  # @!attribute [r] image?
33
39
  # @return [Boolean] whether the file is an image.
34
40
 
41
+ #
42
+ # Creates a new attachment.
43
+ #
44
+ # @param [#read, String] source The Source of the attachment.
45
+ # @param [String] filename The filename of the attachment. If not set, path or object_id of the IO is used.
46
+ # @param [String] description The description of the attachment.
47
+ # @param [String] content_type The content type of the attachment. If not set, it is guessed from the filename.
48
+ # If failed to guess, it is set to `application/octet-stream`.
49
+ # @param [Boolean] will_close Whether the IO will be closed after the attachment is sent.
50
+ #
51
+ def initialize(source, filename = nil, description: nil, content_type: nil, will_close: true)
52
+ @io = if source.respond_to?(:read)
53
+ source
54
+ else
55
+ File.open(source, "rb")
56
+ end
57
+ @filename = filename || (@io.respond_to?(:path) ? @io.path : @io.object_id)
58
+ @description = description
59
+ @content_type = content_type || MIME::Types.type_for(@filename.to_s)[0].to_s
60
+ @content_type = "application/octet-stream" if @content_type == ""
61
+ @will_close = will_close
62
+ @created_by = :client
63
+ end
64
+
35
65
  # @private
36
- def initialize(data)
66
+ def initialize_hash(data)
37
67
  @id = Snowflake.new(data[:id])
38
68
  @filename = data[:filename]
39
69
  @content_type = data[:content_type]
@@ -42,37 +72,18 @@ module Discorb
42
72
  @proxy_url = data[:proxy_url]
43
73
  @height = data[:height]
44
74
  @width = data[:width]
75
+ @created_by = :discord
45
76
  end
46
77
 
47
78
  def image?
48
79
  @content_type.start_with? "image/"
49
80
  end
50
- end
51
81
 
52
- #
53
- # Represents a file to send as an attachment.
54
- #
55
- class File
56
- # @return [#read] The IO of the file.
57
- attr_accessor :io
58
- # @return [String] The filename of the file. If not set, path or object_id of the IO is used.
59
- attr_accessor :filename
60
- # @return [String] The content type of the file. If not set, it is guessed from the filename.
61
- attr_accessor :content_type
62
-
63
- #
64
- # Creates a new file from IO.
65
- #
66
- # @param [#read] io The IO of the file.
67
- # @param [String] filename The filename of the file. If not set, path or object_id of the IO is used.
68
- # @param [String] content_type The content type of the file. If not set, it is guessed from the filename.
69
- # If failed to guess, it is set to `application/octet-stream`.
70
- #
71
- def initialize(io, filename = nil, content_type: nil)
72
- @io = io
73
- @filename = filename || (io.respond_to?(:path) ? io.path : io.object_id)
74
- @content_type = content_type || MIME::Types.type_for(@filename.to_s)[0].to_s
75
- @content_type = "application/octet-stream" if @content_type == ""
82
+ # @private
83
+ def self.from_hash(data)
84
+ inst = allocate
85
+ inst.initialize_hash(data)
86
+ inst
76
87
  end
77
88
 
78
89
  #
@@ -84,14 +95,10 @@ module Discorb
84
95
  #
85
96
  # @return [File] The new file.
86
97
  #
87
- def self.from_string(string, filename: nil, content_type: nil)
98
+ def self.from_string(string, filename = nil, content_type: nil, description: nil)
88
99
  io = StringIO.new(string)
89
100
  filename ||= string.object_id.to_s + ".txt"
90
- new(io, filename, content_type: content_type)
91
- end
92
-
93
- def inspect
94
- "#<#{self.class} filename=#{@filename} content_type=#{@content_type}>"
101
+ new(io, filename, content_type: content_type, description: description, will_close: true)
95
102
  end
96
103
  end
97
104
  end
@@ -239,17 +239,15 @@ module Discorb
239
239
  # @return [Time] The time when the last pinned message was pinned.
240
240
  attr_reader :last_pin_timestamp
241
241
  alias last_pinned_at last_pin_timestamp
242
- # @return [Array<Discorb::ThreadChannel>] The threads in the channel.
243
- attr_reader :threads
244
242
 
245
243
  include Messageable
246
244
 
247
245
  @channel_type = 0
248
246
 
249
- # @private
250
- def initialize(client, data, no_cache: false)
251
- super
252
- @threads = Dictionary.new
247
+ # @!attribute [r] threads
248
+ # @return [Array<Discorb::ThreadChannel>] The threads in the channel.
249
+ def threads
250
+ guild.threads.select { |thread| thread.parent == self }
253
251
  end
254
252
 
255
253
  #
@@ -829,8 +827,6 @@ module Discorb
829
827
  def initialize(client, data, no_cache: false)
830
828
  @members = Dictionary.new
831
829
  super
832
- @client.channels[@parent_id].threads[@id] = self
833
-
834
830
  @client.channels[@id] = self unless no_cache
835
831
  end
836
832
 
@@ -2,9 +2,9 @@
2
2
 
3
3
  module Discorb
4
4
  # @return [String] The API base URL.
5
- API_BASE_URL = "https://discord.com/api/v9"
5
+ API_BASE_URL = "https://discord.com/api/v10"
6
6
  # @return [String] The version of discorb.
7
- VERSION = "0.14.0"
7
+ VERSION = "0.15.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}".freeze
10
10
 
data/lib/discorb/embed.rb CHANGED
@@ -45,37 +45,38 @@ module Discorb
45
45
  # @param [Discorb::Embed::Thumbnail, String] thumbnail The thumbnail of embed.
46
46
  #
47
47
  def initialize(title = nil, description = nil, color: nil, url: nil, timestamp: nil, author: nil,
48
- fields: nil, footer: nil, image: nil, thumbnail: nil, data: nil)
49
- if data.nil?
50
- @title = title
51
- @description = description
52
- @url = url
53
- @timestamp = timestamp
54
- @color = color
55
- @author = author
56
- @fields = fields || []
57
- @footer = footer
58
- @image = image && (image.is_a?(String) ? Image.new(image) : image)
59
- @thumbnail = thumbnail && (thumbnail.is_a?(String) ? Thumbnail.new(thumbnail) : thumbnail)
60
- @type = "rich"
61
- else
62
- @title = data[:title]
63
- @description = data[:description]
64
- @url = data[:url]
65
- @timestamp = data[:timestamp] && Time.iso8601(data[:timestamp])
66
- @type = data[:type]
67
- @color = data[:color] && Color.new(data[:color])
68
- @footer = data[:footer] && Footer.new(data[:footer][:text], icon: data[:footer][:icon_url])
69
- @author = if data[:author]
70
- Author.new(data[:author][:name], icon: data[:author][:icon_url],
71
- url: data[:author][:url])
72
- end
73
- @thumbnail = data[:thumbnail] && Thumbnail.new(data[:thumbnail])
74
- @image = data[:image] && Image.new(data[:image])
75
- @video = data[:video] && Video.new(data[:video])
76
- @provider = data[:provider] && Provider.new(data[:provider])
77
- @fields = data[:fields] ? data[:fields].map { |f| Field.new(f[:name], f[:value], inline: f[:inline]) } : []
78
- end
48
+ fields: nil, footer: nil, image: nil, thumbnail: nil)
49
+ @title = title
50
+ @description = description
51
+ @url = url
52
+ @timestamp = timestamp
53
+ @color = color
54
+ @author = author
55
+ @fields = fields || []
56
+ @footer = footer
57
+ @image = image && (image.is_a?(String) ? Image.new(image) : image)
58
+ @thumbnail = thumbnail && (thumbnail.is_a?(String) ? Thumbnail.new(thumbnail) : thumbnail)
59
+ @type = "rich"
60
+ end
61
+
62
+ # @private
63
+ def initialize_hash(data)
64
+ @title = data[:title]
65
+ @description = data[:description]
66
+ @url = data[:url]
67
+ @timestamp = data[:timestamp] && Time.iso8601(data[:timestamp])
68
+ @type = data[:type]
69
+ @color = data[:color] && Color.new(data[:color])
70
+ @footer = data[:footer] && Footer.new(data[:footer][:text], icon: data[:footer][:icon_url])
71
+ @author = if data[:author]
72
+ Author.new(data[:author][:name], icon: data[:author][:icon_url],
73
+ url: data[:author][:url])
74
+ end
75
+ @thumbnail = data[:thumbnail] && Thumbnail.new(data[:thumbnail])
76
+ @image = data[:image] && Image.new(data[:image])
77
+ @video = data[:video] && Video.new(data[:video])
78
+ @provider = data[:provider] && Provider.new(data[:provider])
79
+ @fields = data[:fields] ? data[:fields].map { |f| Field.new(f[:name], f[:value], inline: f[:inline]) } : []
79
80
  end
80
81
 
81
82
  def image=(value)
@@ -111,6 +112,12 @@ module Discorb
111
112
  ret
112
113
  end
113
114
 
115
+ def self.from_hash(data)
116
+ inst = allocate
117
+ inst.initialize_hash(data)
118
+ inst
119
+ end
120
+
114
121
  #
115
122
  # Represents an author of embed.
116
123
  #
@@ -305,8 +305,8 @@ module Discorb
305
305
  @timestamp = Time.iso8601(data[:edited_timestamp])
306
306
  @mention_everyone = data[:mention_everyone]
307
307
  @mention_roles = data[:mention_roles].map { |r| guild.roles[r] } if data.key?(:mention_roles)
308
- @attachments = data[:attachments].map { |a| Attachment.new(a) } if data.key?(:attachments)
309
- @embeds = data[:embeds] ? data[:embeds].map { |e| Embed.new(data: e) } : [] if data.key?(:embeds)
308
+ @attachments = data[:attachments].map { |a| Attachment.from_hash(a) } if data.key?(:attachments)
309
+ @embeds = data[:embeds] ? data[:embeds].map { |e| Embed.from_hash(e) } : [] if data.key?(:embeds)
310
310
  end
311
311
 
312
312
  def channel
@@ -545,7 +545,13 @@ module Discorb
545
545
  @http = HTTP.new(self)
546
546
  _, gateway_response = @http.request(Route.new("/gateway", "//gateway", :get)).wait
547
547
  gateway_url = gateway_response[:url]
548
- endpoint = Async::HTTP::Endpoint.parse("#{gateway_url}?v=9&encoding=json&compress=zlib-stream",
548
+ gateway_version = if @intents.to_h[:message_content].nil?
549
+ warn "message_content intent not set, using gateway version 9. You should specify `message_content` intent for preventing unexpected changes in the future."
550
+ 9
551
+ else
552
+ 10
553
+ end
554
+ endpoint = Async::HTTP::Endpoint.parse("#{gateway_url}?v=#{gateway_version}&encoding=json&compress=zlib-stream",
549
555
  alpn_protocols: Async::HTTP::Protocol::HTTP11.names)
550
556
  begin
551
557
  @connection = Async::WebSocket::Client.connect(endpoint, headers: [["User-Agent", Discorb::USER_AGENT]], handler: RawConnection)
data/lib/discorb/http.rb CHANGED
@@ -70,12 +70,23 @@ module Discorb
70
70
  ]
71
71
  files&.each_with_index do |file, i|
72
72
  next if file.nil?
73
- data << ["files[#{i}]", file.io, { filename: file.filename, content_type: file.content_type }]
73
+ if file.created_by == :discord
74
+ request_io = StringIO.new(
75
+ cdn_http.get(URI.parse(file.url).path, {
76
+ "Content-Type" => nil,
77
+ "User-Agent" => Discorb::USER_AGENT,
78
+ }).body
79
+ )
80
+ data << ["files[#{i}]", request_io, { filename: file.filename, content_type: file.content_type }]
81
+ else
82
+ data << ["files[#{i}]", file.io, { filename: file.filename, content_type: file.content_type }]
83
+ end
74
84
  end
75
85
  req.set_form(data, "multipart/form-data")
76
86
  session = Net::HTTP.new("discord.com", 443)
77
87
  session.use_ssl = true
78
88
  resp = session.request(req)
89
+ files&.then { _1.filter(&:will_close).each { |f| f.io.close } }
79
90
  data = get_response_data(resp)
80
91
  @ratelimit_handler.save(path, resp)
81
92
  handle_response(resp, data, path, body, headers, audit_log_reason, kwargs)
@@ -159,6 +170,12 @@ module Discorb
159
170
  https
160
171
  end
161
172
 
173
+ def cdn_http
174
+ https = Net::HTTP.new("cdn.discordapp.com", 443)
175
+ https.use_ssl = true
176
+ https
177
+ end
178
+
162
179
  def recr_utf8(data)
163
180
  case data
164
181
  when Hash
@@ -19,6 +19,7 @@ module Discorb
19
19
  dm_messages: 1 << 12,
20
20
  dm_reactions: 1 << 13,
21
21
  dm_typing: 1 << 14,
22
+ message_content: 1 << 15,
22
23
  scheduled_events: 1 << 16,
23
24
  }.freeze
24
25
 
@@ -39,9 +40,13 @@ module Discorb
39
40
  # @param dm_messages [Boolean] Whether dm messages related events are enabled.
40
41
  # @param dm_reactions [Boolean] Whether dm reactions related events are enabled.
41
42
  # @param dm_typing [Boolean] Whether dm typing related events are enabled.
43
+ # @param message_content [Boolean] Whether message content will be sent with events.
42
44
  # @param scheduled_events [Boolean] Whether events related scheduled events are enabled.
43
45
  #
44
46
  # @note You must enable privileged intents to use `members` and/or `presences` intents.
47
+ # @note Message Content Intent is not required to use `message_content` intents for now,
48
+ # this will be required in April 30, 2022. [Learn More](https://support-dev.discord.com/hc/en-us/articles/4404772028055).
49
+ # You should specify `message_content` intent for preventing unexpected changes in the future.
45
50
  #
46
51
  def initialize(guilds: true,
47
52
  members: false,
@@ -58,6 +63,7 @@ module Discorb
58
63
  dm_messages: true,
59
64
  dm_reactions: true,
60
65
  dm_typing: true,
66
+ message_content: nil,
61
67
  scheduled_events: true)
62
68
  @raw_value = {
63
69
  guilds: guilds,
@@ -75,6 +81,7 @@ module Discorb
75
81
  dm_messages: dm_messages,
76
82
  dm_reactions: dm_reactions,
77
83
  dm_typing: dm_typing,
84
+ message_content: message_content,
78
85
  scheduled_events: scheduled_events,
79
86
  }
80
87
  end
@@ -129,9 +136,7 @@ module Discorb
129
136
 
130
137
  # Create new intent object with default values.
131
138
  # This will return intents without members and presence.
132
- def default
133
- from_value(@intent_bits.values.reduce(:+) - @intent_bits[:members] - @intent_bits[:presences])
134
- end
139
+ alias default new
135
140
 
136
141
  # Create new intent object with all intents.
137
142
  def all
@@ -244,16 +244,17 @@ module Discorb
244
244
  # @param [Discorb::Embed] embed The embed to send.
245
245
  # @param [Array<Discorb::Embed>] embeds The embeds to send.
246
246
  # @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions.
247
+ # @param [Array<Discorb::Attachment>] attachments The new attachments.
247
248
  # @param [Array<Discorb::Component>, Array<Array<Discorb::Component>>] components The components to send.
248
249
  # @param [Boolean] supress Whether to supress embeds.
249
250
  #
250
251
  # @return [Async::Task<void>] The task.
251
252
  #
252
- def edit(content = nil, embed: nil, embeds: nil, allowed_mentions: nil,
253
- components: nil, supress: nil)
253
+ def edit(content = Discorb::Unset, embed: Discorb::Unset, embeds: Discorb::Unset, allowed_mentions: Discorb::Unset,
254
+ attachments: Discorb::Unset, components: Discorb::Unset, supress: Discorb::Unset)
254
255
  Async do
255
256
  channel.edit_message(@id, content, embed: embed, embeds: embeds, allowed_mentions: allowed_mentions,
256
- components: components, supress: supress).wait
257
+ attachments: attachments, components: components, supress: supress).wait
257
258
  end
258
259
  end
259
260
 
@@ -445,6 +446,53 @@ module Discorb
445
446
  "#<#{self.class} #{@content.inspect} id=#{@id}>"
446
447
  end
447
448
 
449
+ # @private
450
+ def _set_data(data)
451
+ @id = Snowflake.new(data[:id])
452
+ @channel_id = data[:channel_id]
453
+
454
+ if data[:guild_id]
455
+ @guild_id = data[:guild_id]
456
+ @dm = nil
457
+ else
458
+ @dm = Discorb::DMChannel.new(@client, data[:channel_id])
459
+ @guild_id = nil
460
+ end
461
+
462
+ if data[:member].nil? && data[:webhook_id]
463
+ @webhook_id = Snowflake.new(data[:webhook_id])
464
+ @author = Webhook::Message::Author.new(data[:author])
465
+ elsif data[:guild_id].nil? || data[:guild_id].empty? || data[:member].nil?
466
+ @author = @client.users[data[:author][:id]] || User.new(@client, data[:author])
467
+ else
468
+ @author = guild&.members&.get(data[:author][:id]) || Member.new(@client,
469
+ @guild_id, data[:author], data[:member])
470
+ end
471
+ @content = data[:content]
472
+ @created_at = Time.iso8601(data[:timestamp])
473
+ @updated_at = data[:edited_timestamp].nil? ? nil : Time.iso8601(data[:edited_timestamp])
474
+
475
+ @tts = data[:tts]
476
+ @mention_everyone = data[:mention_everyone]
477
+ @mention_roles = data[:mention_roles].map { |r| guild.roles[r] }
478
+ @attachments = data[:attachments].map { |a| Attachment.from_hash(a) }
479
+ @embeds = data[:embeds] ? data[:embeds].map { |e| Embed.from_hash(e) } : []
480
+ @reactions = data[:reactions] ? data[:reactions].map { |r| Reaction.new(self, r) } : []
481
+ @pinned = data[:pinned]
482
+ @type = self.class.message_type[data[:type]]
483
+ @activity = data[:activity] && Activity.new(data[:activity])
484
+ @application_id = data[:application_id]
485
+ @message_reference = data[:message_reference] && Reference.from_hash(data[:message_reference])
486
+ @flag = Flag.new(0b111 - data[:flags])
487
+ @sticker_items = data[:sticker_items] ? data[:sticker_items].map { |s| Message::Sticker.new(s) } : []
488
+ # @referenced_message = data[:referenced_message] && Message.new(@client, data[:referenced_message])
489
+ @interaction = data[:interaction] && Message::Interaction.new(@client, data[:interaction])
490
+ @thread = data[:thread] && Channel.make_channel(@client, data[:thread])
491
+ @components = data[:components].map { |c| c[:components].map { |co| Component.from_hash(co) } }
492
+ @data.update(data)
493
+ @deleted = false
494
+ end
495
+
448
496
  class << self
449
497
  # @private
450
498
  attr_reader :message_type
@@ -103,54 +103,6 @@ module Discorb
103
103
  end
104
104
  end
105
105
 
106
- private
107
-
108
- def _set_data(data)
109
- @id = Snowflake.new(data[:id])
110
- @channel_id = data[:channel_id]
111
-
112
- if data[:guild_id]
113
- @guild_id = data[:guild_id]
114
- @dm = nil
115
- else
116
- @dm = Discorb::DMChannel.new(@client, data[:channel_id])
117
- @guild_id = nil
118
- end
119
-
120
- if data[:member].nil? && data[:webhook_id]
121
- @webhook_id = Snowflake.new(data[:webhook_id])
122
- @author = Webhook::Message::Author.new(data[:author])
123
- elsif data[:guild_id].nil? || data[:guild_id].empty? || data[:member].nil?
124
- @author = @client.users[data[:author][:id]] || User.new(@client, data[:author])
125
- else
126
- @author = guild&.members&.get(data[:author][:id]) || Member.new(@client,
127
- @guild_id, data[:author], data[:member])
128
- end
129
- @content = data[:content]
130
- @created_at = Time.iso8601(data[:timestamp])
131
- @updated_at = data[:edited_timestamp].nil? ? nil : Time.iso8601(data[:edited_timestamp])
132
-
133
- @tts = data[:tts]
134
- @mention_everyone = data[:mention_everyone]
135
- @mention_roles = data[:mention_roles].map { |r| guild.roles[r] }
136
- @attachments = data[:attachments].map { |a| Attachment.new(a) }
137
- @embeds = data[:embeds] ? data[:embeds].map { |e| Embed.new(data: e) } : []
138
- @reactions = data[:reactions] ? data[:reactions].map { |r| Reaction.new(self, r) } : []
139
- @pinned = data[:pinned]
140
- @type = self.class.message_type[data[:type]]
141
- @activity = data[:activity] && Activity.new(data[:activity])
142
- @application_id = data[:application_id]
143
- @message_reference = data[:message_reference] && Reference.from_hash(data[:message_reference])
144
- @flag = Flag.new(0b111 - data[:flags])
145
- @sticker_items = data[:sticker_items] ? data[:sticker_items].map { |s| Message::Sticker.new(s) } : []
146
- # @referenced_message = data[:referenced_message] && Message.new(@client, data[:referenced_message])
147
- @interaction = data[:interaction] && Message::Interaction.new(@client, data[:interaction])
148
- @thread = data[:thread] && Channel.make_channel(@client, data[:thread])
149
- @components = data[:components].map { |c| c[:components].map { |co| Component.from_hash(co) } }
150
- @data.update(data)
151
- @deleted = false
152
- end
153
-
154
106
  #
155
107
  # Represents a interaction of message.
156
108
  #