mtproto 0.0.17 → 0.0.20
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 +4 -4
- data/lib/mtproto/client/api/get_bot_callback_answer.rb +22 -0
- data/lib/mtproto/client/api/get_channel_difference.rb +22 -0
- data/lib/mtproto/client/api/import_bot_authorization.rb +27 -0
- data/lib/mtproto/client/api/send_message.rb +18 -3
- data/lib/mtproto/client/api.rb +21 -9
- data/lib/mtproto/client/rpc.rb +13 -1
- data/lib/mtproto/client.rb +129 -34
- data/lib/mtproto/dc.rb +31 -0
- data/lib/mtproto/markdown.rb +439 -0
- data/lib/mtproto/tl/constructors.rb +24 -0
- data/lib/mtproto/tl/message_entity.rb +154 -0
- data/lib/mtproto/tl/objects/bot_callback_answer.rb +75 -0
- data/lib/mtproto/tl/objects/channel_difference.rb +163 -0
- data/lib/mtproto/tl/objects/channels_edit_admin.rb +80 -0
- data/lib/mtproto/tl/objects/channels_edit_banned.rb +23 -6
- data/lib/mtproto/tl/objects/dialogs.rb +4 -3
- data/lib/mtproto/tl/objects/get_bot_info.rb +58 -0
- data/lib/mtproto/tl/objects/message.rb +26 -6
- data/lib/mtproto/tl/objects/messages_add_chat_user.rb +27 -0
- data/lib/mtproto/tl/objects/messages_create_chat.rb +47 -0
- data/lib/mtproto/tl/objects/reply_keyboard_markup.rb +26 -1
- data/lib/mtproto/tl/objects/send_message.rb +37 -3
- data/lib/mtproto/tl/objects/update.rb +15 -0
- data/lib/mtproto/tl/reader.rb +35 -8
- data/lib/mtproto/version.rb +1 -1
- data/lib/mtproto.rb +3 -0
- metadata +13 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'securerandom'
|
|
4
|
+
require_relative '../message_entity'
|
|
4
5
|
|
|
5
6
|
module MTProto
|
|
6
7
|
module TL
|
|
@@ -8,36 +9,69 @@ module MTProto
|
|
|
8
9
|
include Binary
|
|
9
10
|
|
|
10
11
|
INPUT_REPLY_TO_MESSAGE = 0x3bd4b7c2
|
|
12
|
+
INPUT_RICH_MESSAGE_MARKDOWN = 0x004b572c
|
|
11
13
|
|
|
12
|
-
def initialize(peer:, message
|
|
14
|
+
def initialize(peer:, message: '', random_id: nil, reply_to: nil, reply_markup: nil, silent: false,
|
|
15
|
+
entities: nil, rich_markdown: nil, quote_text: nil, quote_offset: nil)
|
|
13
16
|
@peer = peer
|
|
14
17
|
@message = message
|
|
15
18
|
@random_id = random_id || SecureRandom.random_number(2**63)
|
|
16
19
|
@reply_to = reply_to
|
|
17
20
|
@reply_markup = reply_markup
|
|
18
21
|
@silent = silent
|
|
22
|
+
@entities = entities
|
|
23
|
+
@rich_markdown = rich_markdown
|
|
24
|
+
@quote_text = quote_text
|
|
25
|
+
@quote_offset = quote_offset
|
|
19
26
|
end
|
|
20
27
|
|
|
21
28
|
def serialize
|
|
22
29
|
flags = 0
|
|
23
30
|
flags |= (1 << 0) if @reply_to
|
|
24
31
|
flags |= (1 << 2) if @reply_markup
|
|
32
|
+
flags |= (1 << 3) if entities?
|
|
25
33
|
flags |= (1 << 5) if @silent
|
|
34
|
+
flags |= (1 << 23) if @rich_markdown # rich_message
|
|
26
35
|
|
|
27
36
|
result = u32_b(Constructors::MESSAGES_SEND_MESSAGE)
|
|
28
37
|
result += u32_b(flags)
|
|
29
38
|
result += serialize_input_peer
|
|
30
39
|
result += serialize_reply_to if @reply_to
|
|
31
|
-
|
|
40
|
+
# Server-side rich markdown carries the whole message; the text field goes
|
|
41
|
+
# empty and no entities are sent (matches Telegram Desktop's sendRichMessage).
|
|
42
|
+
result += serialize_tl_string(@rich_markdown ? '' : @message)
|
|
32
43
|
result += u64_b(@random_id)
|
|
33
44
|
result += @reply_markup.serialize if @reply_markup
|
|
45
|
+
result += MessageEntities.serialize(@entities) if entities?
|
|
46
|
+
result += serialize_rich_markdown if @rich_markdown
|
|
34
47
|
result
|
|
35
48
|
end
|
|
36
49
|
|
|
37
50
|
private
|
|
38
51
|
|
|
52
|
+
def entities?
|
|
53
|
+
@entities && !@entities.empty? && !@rich_markdown
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# inputRichMessageMarkdown#004b572c flags:# rtl:flags.0?true noautolink:flags.1?true
|
|
57
|
+
# markdown:string files:flags.2?Vector<InputRichFile>. Text-only: flags=0, no files.
|
|
58
|
+
def serialize_rich_markdown
|
|
59
|
+
u32_b(INPUT_RICH_MESSAGE_MARKDOWN) + u32_b(0) + serialize_tl_string(@rich_markdown)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# inputReplyToMessage#3bd4b7c2 flags:# reply_to_msg_id:int quote_text:flags.2?string
|
|
63
|
+
# quote_offset:flags.4?int. A quote replies to @reply_to while pinning the exact
|
|
64
|
+
# fragment (@quote_text at @quote_offset in that message); Telegram validates the
|
|
65
|
+
# text against the original at the offset.
|
|
39
66
|
def serialize_reply_to
|
|
40
|
-
|
|
67
|
+
flags = 0
|
|
68
|
+
flags |= (1 << 2) if @quote_text
|
|
69
|
+
flags |= (1 << 4) unless @quote_offset.nil?
|
|
70
|
+
|
|
71
|
+
result = u32_b(INPUT_REPLY_TO_MESSAGE) + u32_b(flags) + u32_b(@reply_to)
|
|
72
|
+
result += serialize_tl_string(@quote_text) if @quote_text
|
|
73
|
+
result += u32_b(@quote_offset) unless @quote_offset.nil?
|
|
74
|
+
result
|
|
41
75
|
end
|
|
42
76
|
|
|
43
77
|
def serialize_input_peer
|
|
@@ -23,6 +23,21 @@ module MTProto
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
# Whether a top-level pushed message (as delivered to Client#on_update with
|
|
27
|
+
# its outer constructor and body) carries an updateLoginToken — the signal
|
|
28
|
+
# that a QR login token was scanned and accepted. Arrives bare or, in
|
|
29
|
+
# practice, wrapped in updateShort.
|
|
30
|
+
def self.login_token?(constructor, body)
|
|
31
|
+
case constructor
|
|
32
|
+
when Constructors::UPDATE_LOGIN_TOKEN
|
|
33
|
+
true
|
|
34
|
+
when Constructors::UPDATE_SHORT
|
|
35
|
+
UpdateShort.deserialize(body).update.type == 'login_token'
|
|
36
|
+
else
|
|
37
|
+
false
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
26
41
|
class << self
|
|
27
42
|
private
|
|
28
43
|
|
data/lib/mtproto/tl/reader.rb
CHANGED
|
@@ -41,21 +41,48 @@ module MTProto
|
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
# messageReplyHeader:
|
|
45
|
-
#
|
|
46
|
-
# flags.
|
|
47
|
-
#
|
|
44
|
+
# messageReplyHeader#1b97dd66: flags, then (in wire order) reply_to_msg_id
|
|
45
|
+
# flags.4?int, reply_to_peer_id flags.0?Peer, reply_from flags.5?MessageFwdHeader,
|
|
46
|
+
# reply_media flags.8?MessageMedia, reply_to_top_id flags.1?int, quote_text
|
|
47
|
+
# flags.6?string, quote_entities flags.7?Vector<MessageEntity>, quote_offset
|
|
48
|
+
# flags.10?int. A manual quote sets flags.9 and carries quote_text/offset — the
|
|
49
|
+
# fragment the user selected out of the replied-to message. The quote fields sit
|
|
50
|
+
# past the variable-length reply_from/reply_media, so we walk the whole header to
|
|
51
|
+
# reach them (reply_from/reply_media are sized via the schema). A plain message
|
|
52
|
+
# in a forum topic carries this header (forum_topic flags.3) but is a reply only
|
|
53
|
+
# when it targets a message in the topic (reply_to_top_id flags.1). Returns a
|
|
54
|
+
# descriptor hash, or nil for a non-messageReplyHeader (e.g. a story reply).
|
|
48
55
|
def parse_reply_to(data, offset)
|
|
49
|
-
return
|
|
56
|
+
return unless data[offset, 4].unpack1('L<') == MESSAGE_REPLY_HEADER
|
|
50
57
|
|
|
51
58
|
io = offset + 4
|
|
52
59
|
flags = data[io, 4].unpack1('L<')
|
|
53
60
|
io += 4
|
|
54
61
|
forum_topic = flags.anybits?(1 << 3)
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
|
|
63
|
+
msg_id = nil
|
|
64
|
+
if flags.anybits?(1 << 4) # reply_to_msg_id
|
|
65
|
+
msg_id = data[io, 4].unpack1('l<')
|
|
66
|
+
io += 4
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
peer_type = peer_id = nil
|
|
70
|
+
peer_type, peer_id, io = parse_peer(data, io) if flags.anybits?(1 << 0) # reply_to_peer_id
|
|
71
|
+
|
|
72
|
+
io = schema.skip(data, io) if flags.anybits?(1 << 5) # reply_from
|
|
73
|
+
io = schema.skip(data, io) if flags.anybits?(1 << 8) # reply_media
|
|
74
|
+
io += 4 if flags.anybits?(1 << 1) # reply_to_top_id
|
|
75
|
+
|
|
76
|
+
quote_text = nil
|
|
77
|
+
quote_text, io = read_tl_string(data, io) if flags.anybits?(1 << 6)
|
|
78
|
+
io = schema.skip_vector(data, io) if flags.anybits?(1 << 7) # quote_entities
|
|
79
|
+
quote_offset = flags.anybits?(1 << 10) ? data[io, 4].unpack1('l<') : nil
|
|
80
|
+
|
|
81
|
+
{ msg_id: msg_id, is_reply: forum_topic ? flags.anybits?(1 << 1) : true,
|
|
82
|
+
is_quote: flags.anybits?(1 << 9), quote_text: quote_text, quote_offset: quote_offset,
|
|
83
|
+
peer_type: peer_type, peer_id: peer_id }
|
|
57
84
|
rescue StandardError
|
|
58
|
-
|
|
85
|
+
nil
|
|
59
86
|
end
|
|
60
87
|
|
|
61
88
|
# Classify message media into :photo / :video / :audio / :document, or nil.
|
data/lib/mtproto/version.rb
CHANGED
data/lib/mtproto.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative 'mtproto/version'
|
|
4
4
|
require_relative 'mtproto/errors'
|
|
5
5
|
require_relative 'mtproto/binary'
|
|
6
|
+
require_relative 'mtproto/dc'
|
|
6
7
|
require_relative 'mtproto/delegate_methods'
|
|
7
8
|
require_relative 'mtproto/transport/errors'
|
|
8
9
|
require_relative 'mtproto/transport/packet'
|
|
@@ -13,6 +14,8 @@ require_relative 'mtproto/unencrypted_message'
|
|
|
13
14
|
require_relative 'mtproto/tl/constructors'
|
|
14
15
|
require_relative 'mtproto/tl/constructor_names'
|
|
15
16
|
require_relative 'mtproto/tl/reader'
|
|
17
|
+
require_relative 'mtproto/tl/message_entity'
|
|
18
|
+
require_relative 'mtproto/markdown'
|
|
16
19
|
require_relative 'mtproto/tl/object'
|
|
17
20
|
require_relative 'mtproto/tl/objects/update'
|
|
18
21
|
require_relative 'mtproto/tl/objects/update_short'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mtproto
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.20
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Artem Levenkov
|
|
@@ -65,6 +65,8 @@ files:
|
|
|
65
65
|
- lib/mtproto/client/api/check_password.rb
|
|
66
66
|
- lib/mtproto/client/api/export_authorization.rb
|
|
67
67
|
- lib/mtproto/client/api/export_login_token.rb
|
|
68
|
+
- lib/mtproto/client/api/get_bot_callback_answer.rb
|
|
69
|
+
- lib/mtproto/client/api/get_channel_difference.rb
|
|
68
70
|
- lib/mtproto/client/api/get_contacts.rb
|
|
69
71
|
- lib/mtproto/client/api/get_dialogs.rb
|
|
70
72
|
- lib/mtproto/client/api/get_history.rb
|
|
@@ -72,6 +74,7 @@ files:
|
|
|
72
74
|
- lib/mtproto/client/api/get_updates_state.rb
|
|
73
75
|
- lib/mtproto/client/api/get_users.rb
|
|
74
76
|
- lib/mtproto/client/api/import_authorization.rb
|
|
77
|
+
- lib/mtproto/client/api/import_bot_authorization.rb
|
|
75
78
|
- lib/mtproto/client/api/import_login_token.rb
|
|
76
79
|
- lib/mtproto/client/api/send_code.rb
|
|
77
80
|
- lib/mtproto/client/api/send_message.rb
|
|
@@ -87,21 +90,27 @@ files:
|
|
|
87
90
|
- lib/mtproto/crypto/rsa_key.rb
|
|
88
91
|
- lib/mtproto/crypto/rsa_pad.rb
|
|
89
92
|
- lib/mtproto/crypto/srp.rb
|
|
93
|
+
- lib/mtproto/dc.rb
|
|
90
94
|
- lib/mtproto/delegate_methods.rb
|
|
91
95
|
- lib/mtproto/encrypted_message.rb
|
|
92
96
|
- lib/mtproto/errors.rb
|
|
93
97
|
- lib/mtproto/file_downloader.rb
|
|
98
|
+
- lib/mtproto/markdown.rb
|
|
94
99
|
- lib/mtproto/message_id.rb
|
|
95
100
|
- lib/mtproto/session.rb
|
|
96
101
|
- lib/mtproto/tl/constructor_names.rb
|
|
97
102
|
- lib/mtproto/tl/constructors.rb
|
|
103
|
+
- lib/mtproto/tl/message_entity.rb
|
|
98
104
|
- lib/mtproto/tl/object.rb
|
|
99
105
|
- lib/mtproto/tl/objects/account_password.rb
|
|
100
106
|
- lib/mtproto/tl/objects/authorization.rb
|
|
107
|
+
- lib/mtproto/tl/objects/bot_callback_answer.rb
|
|
101
108
|
- lib/mtproto/tl/objects/bot_command_scope.rb
|
|
109
|
+
- lib/mtproto/tl/objects/channel_difference.rb
|
|
102
110
|
- lib/mtproto/tl/objects/channels_create_channel.rb
|
|
103
111
|
- lib/mtproto/tl/objects/channels_delete_messages.rb
|
|
104
112
|
- lib/mtproto/tl/objects/channels_delete_participant_history.rb
|
|
113
|
+
- lib/mtproto/tl/objects/channels_edit_admin.rb
|
|
105
114
|
- lib/mtproto/tl/objects/channels_edit_banned.rb
|
|
106
115
|
- lib/mtproto/tl/objects/channels_get_messages.rb
|
|
107
116
|
- lib/mtproto/tl/objects/channels_get_participant.rb
|
|
@@ -127,6 +136,7 @@ files:
|
|
|
127
136
|
- lib/mtproto/tl/objects/get_access_settings.rb
|
|
128
137
|
- lib/mtproto/tl/objects/get_bot_callback_answer.rb
|
|
129
138
|
- lib/mtproto/tl/objects/get_bot_commands.rb
|
|
139
|
+
- lib/mtproto/tl/objects/get_bot_info.rb
|
|
130
140
|
- lib/mtproto/tl/objects/get_channel_difference.rb
|
|
131
141
|
- lib/mtproto/tl/objects/get_config.rb
|
|
132
142
|
- lib/mtproto/tl/objects/get_contacts.rb
|
|
@@ -153,6 +163,8 @@ files:
|
|
|
153
163
|
- lib/mtproto/tl/objects/login_token.rb
|
|
154
164
|
- lib/mtproto/tl/objects/message.rb
|
|
155
165
|
- lib/mtproto/tl/objects/messages.rb
|
|
166
|
+
- lib/mtproto/tl/objects/messages_add_chat_user.rb
|
|
167
|
+
- lib/mtproto/tl/objects/messages_create_chat.rb
|
|
156
168
|
- lib/mtproto/tl/objects/messages_get_messages.rb
|
|
157
169
|
- lib/mtproto/tl/objects/msg_container.rb
|
|
158
170
|
- lib/mtproto/tl/objects/new_session_created.rb
|