Class: MTProto::TL::Message

Inherits:
Object
  • Object
show all
Defined in:
lib/mtproto/tl/objects/message.rb

Overview

The high-level chat-message TL structure ‘message#7600b9d3` (text/media/ fwd_from/reply/sender/…). Owns the field walk for that one constructor; the low-level TL reads it needs (peer/string/bytes/media/document, plus the shared schema) live in Reader and are reused here.

Reading is decoupled from alignment: ‘.deserialize` only READS the fields we surface and returns a Message (or nil for a non-`message` constructor — e.g. messageService/messageEmpty). Advancing past the whole object is the caller’s job via ‘Schema#skip`, so any unmodelled tail never drops the message. This is the single parser for all three inbound paths (live `Updates` push, `updates.getDifference`, and `messages.getHistory`).

Constant Summary collapse

MESSAGE =
Constructors::MESSAGE
MESSAGE_FWD_HEADER =
0x4e4df4bb
FIELDS =
%i[id date message peer_type peer_id from_type from_id out media
document photo is_reply reply_to_msg_id fwd_from_type fwd_from_id].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attrs) ⇒ Message

Returns a new instance of Message.



30
31
32
# File 'lib/mtproto/tl/objects/message.rb', line 30

def initialize(attrs)
  FIELDS.each { |f| instance_variable_set("@#{f}", attrs[f]) }
end

Class Method Details

.deserialize(data, offset, constructor) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/mtproto/tl/objects/message.rb', line 40

def deserialize(data, offset, constructor)
  return unless constructor == MESSAGE

  offset += 4 # constructor
  flags = data[offset, 4].unpack1('L<')
  offset += 4
  flags2 = data[offset, 4].unpack1('L<')
  offset += 4
  id = data[offset, 4].unpack1('l<')
  offset += 4

  from_type = from_id = nil
  from_type, from_id, offset = x.parse_peer(data, offset) if flags.anybits?(1 << 8) # from_id (Peer)
  offset += 4 if flags.anybits?(1 << 29) # from_boosts_applied
  _, offset = x.read_tl_string(data, offset) if flags2.anybits?(1 << 12) # from_rank (layer 227)
  peer_type, peer_id, offset = x.parse_peer(data, offset)
  offset = x.schema.skip(data, offset) if flags.anybits?(1 << 28) # saved_peer_id
  fwd_from_type = fwd_from_id = nil
  if flags.anybits?(1 << 2) # fwd_from
    fwd_from_type, fwd_from_id = parse_fwd_origin(data, offset)
    offset = x.schema.skip(data, offset)
  end
  offset += 8 if flags.anybits?(1 << 11) # via_bot_id
  offset += 8 if flags2.anybits?(1 << 0) # via_business_bot_id
  offset = x.schema.skip(data, offset) if flags2.anybits?(1 << 19) # guestchat_via_from (layer 227, Peer)

  is_reply = false
  reply_to_msg_id = nil
  if flags.anybits?(1 << 3) # reply_to
    reply_to_msg_id, is_reply = x.parse_reply_to(data, offset)
    offset = x.schema.skip(data, offset)
  end

  date = data[offset, 4].unpack1('L<')
  offset += 4
  message_text, offset = x.read_tl_string(data, offset)
  has_media = flags.anybits?(1 << 9)
  media = has_media ? x.parse_media(data, offset) : nil
  document = has_media ? x.parse_document(data, offset) : nil
  photo = has_media ? x.parse_photo(data, offset) : nil

  new(id: id, date: date, message: message_text, peer_type: peer_type, peer_id: peer_id,
    from_type: from_type, from_id: from_id, out: flags.anybits?(1 << 1),
    media: media, document: document, photo: photo, is_reply: is_reply,
    reply_to_msg_id: reply_to_msg_id, fwd_from_type: fwd_from_type, fwd_from_id: fwd_from_id)
end

Instance Method Details

#to_hObject

The legacy hash shape the Updates / UpdatesDifference consumers expect.



35
36
37
# File 'lib/mtproto/tl/objects/message.rb', line 35

def to_h
  FIELDS.each_with_object({}) { |f, h| h[f] = public_send(f) }
end