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 reply_to_peer_type reply_to_peer_id
is_quote quote_text quote_offset entities 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.



32
33
34
# File 'lib/mtproto/tl/objects/message.rb', line 32

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

Class Method Details

.deserialize(data, offset, constructor) ⇒ Object



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
86
87
88
89
90
91
# File 'lib/mtproto/tl/objects/message.rb', line 42

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)

  reply = nil
  if flags.anybits?(1 << 3) # reply_to
    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
  entities = parse_entities(data, offset, flags, has_media)

  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: reply ? reply[:is_reply] : false, reply_to_msg_id: reply && reply[:msg_id],
    reply_to_peer_type: reply && reply[:peer_type], reply_to_peer_id: reply && reply[:peer_id],
    is_quote: reply ? reply[:is_quote] : false, quote_text: reply && reply[:quote_text],
    quote_offset: reply && reply[:quote_offset], entities: entities,
    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.



37
38
39
# File 'lib/mtproto/tl/objects/message.rb', line 37

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