mtproto 0.0.22 → 0.0.24

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: 3d821c481442840e9ff4efd6484f531d5d51be2523ebf23c4e12f6ae1a7d397d
4
- data.tar.gz: 7c1131dfcfcafcef6e0310859d6af1f0d85ae829126288ff3084992ceafa95bf
3
+ metadata.gz: 3594ecc46ef5c1edf765f5efadbeac38fb74b4a27a127709ad5acf108d9c6299
4
+ data.tar.gz: 874e6d930464f234cf42b4030dca34d2eeb88cee2795fead2af2cf3252663877
5
5
  SHA512:
6
- metadata.gz: f8fe999e48d98c6bbb5dc6335c4bc075a9a883b130cea978c81a660145f95aa3a70d6e9a4dbe9cf546a99d1cf8306e24dcf242d633a32f9d21667cd1d14f4dbd
7
- data.tar.gz: a81fee5603238bfb9d0ff7798ffcc11f45f527b4043b32737678c58336c5637e02fe53ab3e07004b5d5e1a8054d1e406196fe7bf24d59d849401b127edca63ba
6
+ metadata.gz: 0075ae8b93b25118c8c75ac0599c37d2a3f8720d83d0f4049e548ff18eb45a218e8e90693960d76906d46b1f03e1be250b8fa046f3457f7889de554d18721015
7
+ data.tar.gz: 91d439598d87a62ee488265498c83f54ade432e0bf9f86cc835dc9d3a842a6ba28e077b0e235d4972179cbd94fd7a096ab7001d326cc03a697d4148b0416f2a9
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../tl/objects/search'
4
+ require_relative '../../tl/objects/messages'
5
+
6
+ module MTProto
7
+ class Client
8
+ class API
9
+ # Newest first — so the topmost pinned message is the returned Messages.first.
10
+ def get_pinned_messages(peer:, limit: 100)
11
+ rpc_call(
12
+ TL::Search.new(peer: peer, filter: TL::Search::INPUT_MESSAGES_FILTER_PINNED, limit: limit),
13
+ TL::Messages
14
+ ).body
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../tl/objects/update_pinned_message'
4
+ require_relative '../../tl/objects/updates'
5
+
6
+ module MTProto
7
+ class Client
8
+ class API
9
+ def pin_message(peer:, id:, silent: false, pm_oneside: false)
10
+ rpc_call(
11
+ TL::UpdatePinnedMessage.new(
12
+ peer: peer, id: id, unpin: false, silent: silent, pm_oneside: pm_oneside
13
+ ),
14
+ TL::Updates
15
+ ).body
16
+ end
17
+
18
+ def unpin_message(peer:, id:)
19
+ rpc_call(
20
+ TL::UpdatePinnedMessage.new(peer: peer, id: id, unpin: true),
21
+ TL::Updates
22
+ ).body
23
+ end
24
+ end
25
+ end
26
+ end
@@ -17,11 +17,12 @@ module MTProto
17
17
  # A `reply_to` (with optional `quote_text`/`quote_offset`) replies to a message,
18
18
  # optionally pinning the quoted fragment.
19
19
  def send_message(peer:, message: '', random_id: nil, reply_to: nil, entities: nil,
20
- parse_mode: nil, rich_markdown: nil, quote_text: nil, quote_offset: nil)
20
+ parse_mode: nil, rich_markdown: nil, quote_text: nil, quote_offset: nil, no_webpage: false)
21
21
  message, entities = Markdown.parse(message) if parse_mode && entities.nil? && rich_markdown.nil?
22
22
  rpc_call(
23
23
  TL::SendMessage.new(peer: peer, message: message, random_id: random_id, reply_to: reply_to,
24
- entities: entities, rich_markdown: rich_markdown, quote_text: quote_text, quote_offset: quote_offset),
24
+ entities: entities, rich_markdown: rich_markdown, quote_text: quote_text, quote_offset: quote_offset,
25
+ no_webpage: no_webpage),
25
26
  TL::UpdateShortSentMessage
26
27
  ).body
27
28
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../tl/objects/unpin_all_messages'
4
+ require_relative '../../tl/objects/affected_history'
5
+
6
+ module MTProto
7
+ class Client
8
+ class API
9
+ def unpin_all_messages(peer:, top_msg_id: nil)
10
+ rpc_call(
11
+ TL::UnpinAllMessages.new(peer: peer, top_msg_id: top_msg_id),
12
+ TL::AffectedHistory
13
+ ).body
14
+ end
15
+ end
16
+ end
17
+ end
@@ -18,6 +18,9 @@ require_relative 'api/get_bot_callback_answer'
18
18
  require_relative 'api/send_message'
19
19
  require_relative 'api/set_typing'
20
20
  require_relative 'api/get_contacts'
21
+ require_relative 'api/pin_message'
22
+ require_relative 'api/unpin_all_messages'
23
+ require_relative 'api/get_pinned_messages'
21
24
 
22
25
  module MTProto
23
26
  class Client
@@ -354,6 +354,11 @@ module MTProto
354
354
  constructor = response_body[0, 4].unpack1('L<')
355
355
 
356
356
  case constructor
357
+ when TL::Constructors::GZIP_PACKED
358
+ # The server gzips larger payloads (notably busy channels' update
359
+ # containers) at the top level too, not only inside rpc_result. Inflate
360
+ # and re-route the inner message, or these updates are silently dropped.
361
+ process_message(TL::GzipPacked.unpack(response_body), server_msg_id)
357
362
  when TL::Constructors::MSG_CONTAINER
358
363
  handle_container(response_body)
359
364
  when TL::Constructors::RPC_RESULT
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MTProto
4
+ module TL
5
+ # messages.affectedHistory — reply to bulk history operations (unpinAllMessages,
6
+ # deleteHistory, readHistory…). pts/pts_count advance the update state; a nonzero
7
+ # offset means the server processed only part of the range and the caller must
8
+ # repeat the request with the same arguments until offset reaches 0.
9
+ class AffectedHistory
10
+ CONSTRUCTOR = 0xb45c69d1
11
+
12
+ attr_reader :pts, :pts_count, :offset
13
+
14
+ def initialize(pts:, pts_count:, offset:)
15
+ @pts = pts
16
+ @pts_count = pts_count
17
+ @offset = offset
18
+ end
19
+
20
+ def self.deserialize(data)
21
+ constructor = data[0, 4].unpack1('L<')
22
+ raise UnexpectedConstructorError, constructor unless constructor == CONSTRUCTOR
23
+
24
+ pts = data[4, 4].unpack1('l<')
25
+ pts_count = data[8, 4].unpack1('l<')
26
+ offset = data[12, 4].unpack1('l<')
27
+ new(pts: pts, pts_count: pts_count, offset: offset)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -443,7 +443,8 @@ module MTProto
443
443
  offset += 8 if flags2.anybits?(1 << 14) # bot_verification_icon
444
444
  offset += 8 if flags2.anybits?(1 << 15) # send_paid_messages_stars
445
445
 
446
- [{ id: id, first_name: first_name, last_name: last_name, username: username, access_hash: access_hash }, offset]
446
+ [{ id: id, first_name: first_name, last_name: last_name, username: username,
447
+ is_bot: flags.anybits?(1 << 14), access_hash: access_hash }, offset]
447
448
  end
448
449
 
449
450
  # --- TL string ---
@@ -2,11 +2,13 @@
2
2
 
3
3
  require_relative '../schema'
4
4
  require_relative 'message'
5
+ require_relative 'dialogs'
5
6
 
6
7
  module MTProto
7
8
  module TL
8
9
  # A messages.messages / messagesSlice / channelMessages container (e.g. the
9
- # messages.getHistory reply). Its messages are TL::Message instances.
10
+ # messages.getHistory / messages.getMessages reply). Its messages are
11
+ # TL::Message instances.
10
12
  class Messages
11
13
  MESSAGES_MESSAGES = 0x1d73e7ea
12
14
  MESSAGES_SLICE = 0x5f206716
@@ -14,11 +16,13 @@ module MTProto
14
16
 
15
17
  VALID_CONSTRUCTORS = [MESSAGES_MESSAGES, MESSAGES_SLICE, MESSAGES_CHANNEL].freeze
16
18
 
17
- attr_reader :messages, :count
19
+ attr_reader :messages, :count, :users, :chats
18
20
 
19
- def initialize(messages:, count: nil)
21
+ def initialize(messages:, count: nil, users: [], chats: [])
20
22
  @messages = messages
21
23
  @count = count
24
+ @users = users
25
+ @chats = chats
22
26
  end
23
27
 
24
28
  def slice?
@@ -64,12 +68,13 @@ module MTProto
64
68
 
65
69
  messages, offset = parse_messages_vector(data, offset)
66
70
 
67
- # skip topics vector for channelMessages
68
- schema.skip_vector(data, offset) { |d, o| schema.skip(d, o) } if constructor == MESSAGES_CHANNEL
71
+ # topics:Vector<ForumTopic> precedes chats/users in all three constructors
72
+ offset = schema.skip_vector(data, offset) { |d, o| schema.skip(d, o) }
69
73
 
70
- # skip chats and users (we don't need them here)
74
+ chats, offset = Dialogs.chats_at(data, offset)
75
+ users, = Dialogs.users_at(data, offset)
71
76
 
72
- new(messages: messages, count: count)
77
+ new(messages: messages, count: count, users: users, chats: chats)
73
78
  end
74
79
 
75
80
  class << self
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MTProto
4
+ module TL
5
+ # messages.search. None of the optional (flag-driven) fields are sent, so flags
6
+ # is always 0. Returns messages.Messages.
7
+ class Search
8
+ include Binary
9
+
10
+ CONSTRUCTOR = 0x29ee847a
11
+ INPUT_MESSAGES_FILTER_PINNED = 0x1bb00451
12
+
13
+ def initialize(peer:, filter: INPUT_MESSAGES_FILTER_PINNED, q: '', limit: 100,
14
+ offset_id: 0, add_offset: 0, max_id: 0, min_id: 0, min_date: 0, max_date: 0)
15
+ @peer = peer
16
+ @filter = filter
17
+ @q = q
18
+ @limit = limit
19
+ @offset_id = offset_id
20
+ @add_offset = add_offset
21
+ @max_id = max_id
22
+ @min_id = min_id
23
+ @min_date = min_date
24
+ @max_date = max_date
25
+ end
26
+
27
+ def serialize
28
+ result = u32_b(CONSTRUCTOR)
29
+ result += u32_b(0) # flags
30
+ result += serialize_input_peer
31
+ result += serialize_tl_string(@q)
32
+ result += u32_b(@filter)
33
+ result += u32_b(@min_date)
34
+ result += u32_b(@max_date)
35
+ result += u32_b(@offset_id)
36
+ result += u32_b(@add_offset)
37
+ result += u32_b(@limit)
38
+ result += u32_b(@max_id)
39
+ result += u32_b(@min_id)
40
+ result += u64_b(0) # hash
41
+ result
42
+ end
43
+
44
+ private
45
+
46
+ def serialize_input_peer
47
+ case @peer[:type]
48
+ when :user
49
+ u32_b(Constructors::INPUT_PEER_USER) + u64_b(@peer[:id]) + u64_b(@peer[:access_hash] || 0)
50
+ when :chat
51
+ u32_b(Constructors::INPUT_PEER_CHAT) + u64_b(@peer[:id])
52
+ when :channel
53
+ u32_b(Constructors::INPUT_PEER_CHANNEL) + u64_b(@peer[:id]) + u64_b(@peer[:access_hash] || 0)
54
+ else
55
+ raise "Unknown peer type: #{@peer[:type]}"
56
+ end
57
+ end
58
+
59
+ def serialize_tl_string(str)
60
+ bytes = str.encode('UTF-8').bytes
61
+ length = bytes.length
62
+
63
+ if length <= 253
64
+ [length] + bytes + padding(length + 1)
65
+ else
66
+ [254] + u32_b(length)[0, 3] + bytes + padding(length + 4)
67
+ end
68
+ end
69
+
70
+ def padding(current_length)
71
+ pad_length = (4 - (current_length % 4)) % 4
72
+ [0] * pad_length
73
+ end
74
+ end
75
+ end
76
+ end
@@ -12,13 +12,14 @@ module MTProto
12
12
  INPUT_RICH_MESSAGE_MARKDOWN = 0x004b572c
13
13
 
14
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)
15
+ no_webpage: false, entities: nil, rich_markdown: nil, quote_text: nil, quote_offset: nil)
16
16
  @peer = peer
17
17
  @message = message
18
18
  @random_id = random_id || SecureRandom.random_number(2**63)
19
19
  @reply_to = reply_to
20
20
  @reply_markup = reply_markup
21
21
  @silent = silent
22
+ @no_webpage = no_webpage
22
23
  @entities = entities
23
24
  @rich_markdown = rich_markdown
24
25
  @quote_text = quote_text
@@ -28,6 +29,7 @@ module MTProto
28
29
  def serialize
29
30
  flags = 0
30
31
  flags |= (1 << 0) if @reply_to
32
+ flags |= (1 << 1) if @no_webpage
31
33
  flags |= (1 << 2) if @reply_markup
32
34
  flags |= (1 << 3) if entities?
33
35
  flags |= (1 << 5) if @silent
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MTProto
4
+ module TL
5
+ # messages.unpinAllMessages. Returns messages.AffectedHistory.
6
+ class UnpinAllMessages
7
+ include Binary
8
+
9
+ CONSTRUCTOR = 0x062dd747
10
+
11
+ def initialize(peer:, top_msg_id: nil)
12
+ @peer = peer
13
+ @top_msg_id = top_msg_id
14
+ end
15
+
16
+ def serialize
17
+ flags = 0
18
+ flags |= (1 << 0) unless @top_msg_id.nil?
19
+
20
+ result = u32_b(CONSTRUCTOR)
21
+ result += u32_b(flags)
22
+ result += serialize_input_peer
23
+ result += u32_b(@top_msg_id) unless @top_msg_id.nil?
24
+ result
25
+ end
26
+
27
+ private
28
+
29
+ def serialize_input_peer
30
+ case @peer[:type]
31
+ when :user
32
+ u32_b(Constructors::INPUT_PEER_USER) + u64_b(@peer[:id]) + u64_b(@peer[:access_hash] || 0)
33
+ when :chat
34
+ u32_b(Constructors::INPUT_PEER_CHAT) + u64_b(@peer[:id])
35
+ when :channel
36
+ u32_b(Constructors::INPUT_PEER_CHANNEL) + u64_b(@peer[:id]) + u64_b(@peer[:access_hash] || 0)
37
+ else
38
+ raise "Unknown peer type: #{@peer[:type]}"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MTProto
4
+ module TL
5
+ # messages.updatePinnedMessage. silent suppresses the pin service notification;
6
+ # pm_oneside pins only on the caller's side in a private chat. Returns Updates.
7
+ class UpdatePinnedMessage
8
+ include Binary
9
+
10
+ CONSTRUCTOR = 0xd2aaf7ec
11
+
12
+ def initialize(peer:, id:, unpin: false, silent: false, pm_oneside: false)
13
+ @peer = peer
14
+ @id = id
15
+ @unpin = unpin
16
+ @silent = silent
17
+ @pm_oneside = pm_oneside
18
+ end
19
+
20
+ def serialize
21
+ flags = 0
22
+ flags |= (1 << 0) if @silent
23
+ flags |= (1 << 1) if @unpin
24
+ flags |= (1 << 2) if @pm_oneside
25
+
26
+ result = u32_b(CONSTRUCTOR)
27
+ result += u32_b(flags)
28
+ result += serialize_input_peer
29
+ result += u32_b(@id)
30
+ result
31
+ end
32
+
33
+ private
34
+
35
+ def serialize_input_peer
36
+ case @peer[:type]
37
+ when :user
38
+ u32_b(Constructors::INPUT_PEER_USER) + u64_b(@peer[:id]) + u64_b(@peer[:access_hash] || 0)
39
+ when :chat
40
+ u32_b(Constructors::INPUT_PEER_CHAT) + u64_b(@peer[:id])
41
+ when :channel
42
+ u32_b(Constructors::INPUT_PEER_CHANNEL) + u64_b(@peer[:id]) + u64_b(@peer[:access_hash] || 0)
43
+ else
44
+ raise "Unknown peer type: #{@peer[:type]}"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MTProto
4
- VERSION = '0.0.22'
4
+ VERSION = '0.0.24'
5
5
  end
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.22
4
+ version: 0.0.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artem Levenkov
@@ -71,16 +71,19 @@ files:
71
71
  - lib/mtproto/client/api/get_contacts.rb
72
72
  - lib/mtproto/client/api/get_dialogs.rb
73
73
  - lib/mtproto/client/api/get_history.rb
74
+ - lib/mtproto/client/api/get_pinned_messages.rb
74
75
  - lib/mtproto/client/api/get_updates_difference.rb
75
76
  - lib/mtproto/client/api/get_updates_state.rb
76
77
  - lib/mtproto/client/api/get_users.rb
77
78
  - lib/mtproto/client/api/import_authorization.rb
78
79
  - lib/mtproto/client/api/import_bot_authorization.rb
79
80
  - lib/mtproto/client/api/import_login_token.rb
81
+ - lib/mtproto/client/api/pin_message.rb
80
82
  - lib/mtproto/client/api/send_code.rb
81
83
  - lib/mtproto/client/api/send_message.rb
82
84
  - lib/mtproto/client/api/set_typing.rb
83
85
  - lib/mtproto/client/api/sign_in.rb
86
+ - lib/mtproto/client/api/unpin_all_messages.rb
84
87
  - lib/mtproto/client/rpc.rb
85
88
  - lib/mtproto/client/rpc/response.rb
86
89
  - lib/mtproto/crypto/aes_ige.rb
@@ -105,6 +108,7 @@ files:
105
108
  - lib/mtproto/tl/message_entity.rb
106
109
  - lib/mtproto/tl/object.rb
107
110
  - lib/mtproto/tl/objects/account_password.rb
111
+ - lib/mtproto/tl/objects/affected_history.rb
108
112
  - lib/mtproto/tl/objects/authorization.rb
109
113
  - lib/mtproto/tl/objects/bot_callback_answer.rb
110
114
  - lib/mtproto/tl/objects/bot_command_scope.rb
@@ -182,6 +186,7 @@ files:
182
186
  - lib/mtproto/tl/objects/resolve_username.rb
183
187
  - lib/mtproto/tl/objects/rpc_error.rb
184
188
  - lib/mtproto/tl/objects/save_file_part.rb
189
+ - lib/mtproto/tl/objects/search.rb
185
190
  - lib/mtproto/tl/objects/send_bot_requested_peer.rb
186
191
  - lib/mtproto/tl/objects/send_code.rb
187
192
  - lib/mtproto/tl/objects/send_media.rb
@@ -198,7 +203,9 @@ files:
198
203
  - lib/mtproto/tl/objects/set_client_dh_params.rb
199
204
  - lib/mtproto/tl/objects/set_typing.rb
200
205
  - lib/mtproto/tl/objects/sign_in.rb
206
+ - lib/mtproto/tl/objects/unpin_all_messages.rb
201
207
  - lib/mtproto/tl/objects/update.rb
208
+ - lib/mtproto/tl/objects/update_pinned_message.rb
202
209
  - lib/mtproto/tl/objects/update_short.rb
203
210
  - lib/mtproto/tl/objects/update_short_message.rb
204
211
  - lib/mtproto/tl/objects/update_short_sent_message.rb