Class: MTProto::Client
- Inherits:
-
Object
- Object
- MTProto::Client
- Extended by:
- DelegateMethods
- Defined in:
- lib/mtproto/client.rb,
lib/mtproto/client/api.rb,
lib/mtproto/client/rpc.rb,
lib/mtproto/client/api/sign_in.rb,
lib/mtproto/client/rpc/response.rb,
lib/mtproto/client/api/get_users.rb,
lib/mtproto/client/api/send_code.rb,
lib/mtproto/client/api/get_dialogs.rb,
lib/mtproto/client/api/get_history.rb,
lib/mtproto/client/api/get_contacts.rb,
lib/mtproto/client/api/send_message.rb,
lib/mtproto/client/api/check_password.rb,
lib/mtproto/client/api/get_updates_state.rb,
lib/mtproto/client/api/export_login_token.rb,
lib/mtproto/client/api/import_login_token.rb,
lib/mtproto/client/api/get_updates_difference.rb
Defined Under Namespace
Constant Summary collapse
- API_LAYER =
214
Instance Attribute Summary collapse
-
#access_hash ⇒ Object
readonly
Returns the value of attribute access_hash.
-
#api_hash ⇒ Object
Returns the value of attribute api_hash.
-
#api_id ⇒ Object
Returns the value of attribute api_id.
-
#app_version ⇒ Object
Returns the value of attribute app_version.
-
#auth_key ⇒ Object
readonly
Returns the value of attribute auth_key.
-
#connection ⇒ Object
readonly
Returns the value of attribute connection.
-
#dc_number ⇒ Object
readonly
Returns the value of attribute dc_number.
-
#device_model ⇒ Object
Returns the value of attribute device_model.
-
#lang_code ⇒ Object
Returns the value of attribute lang_code.
-
#lang_pack ⇒ Object
Returns the value of attribute lang_pack.
-
#server_key ⇒ Object
readonly
Returns the value of attribute server_key.
-
#server_salt ⇒ Object
readonly
Returns the value of attribute server_salt.
-
#session ⇒ Object
readonly
Returns the value of attribute session.
-
#system_lang_code ⇒ Object
Returns the value of attribute system_lang_code.
-
#system_version ⇒ Object
Returns the value of attribute system_version.
-
#time_offset ⇒ Object
readonly
Returns the value of attribute time_offset.
-
#timeout ⇒ Object
readonly
Returns the value of attribute timeout.
-
#user_id ⇒ Object
readonly
Returns the value of attribute user_id.
Instance Method Summary collapse
- #api ⇒ Object
- #auth_key? ⇒ Boolean
- #disconnect! ⇒ Object
- #exchange_keys! ⇒ Object
- #init_connection! ⇒ Object
-
#initialize(host:, api_id:, api_hash:, port: 443, public_key: nil, dc_number: nil, test_mode: false, timeout: 10) ⇒ Client
constructor
A new instance of Client.
- #load_auth_data(auth_data) ⇒ Object
- #mainloop_running? ⇒ Boolean
- #on_update(&block) ⇒ Object
- #rpc ⇒ Object
- #run_mainloop ⇒ Object
- #save_auth_data ⇒ Object
-
#start_receiving! ⇒ Object
Start the receiver task without taking over the current Async reactor.
- #update_server_salt(new_salt) ⇒ Object
- #update_user(user_id:, access_hash: nil) ⇒ Object
Methods included from DelegateMethods
Constructor Details
#initialize(host:, api_id:, api_hash:, port: 443, public_key: nil, dc_number: nil, test_mode: false, timeout: 10) ⇒ Client
Returns a new instance of Client.
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 |
# File 'lib/mtproto/client.rb', line 40 def initialize( host:, api_id:, api_hash:, port: 443, public_key: nil, dc_number: nil, test_mode: false, timeout: 10 ) raise ArgumentError, 'host is required' if host.nil? || host.empty? raise ArgumentError, 'dc_number must be positive. Use test_mode: true for test DCs' if dc_number && dc_number < 0 @api_id = api_id @api_hash = api_hash transport = Transport::TCPConnection.new(host, port) @connection = Transport::Connection.new(transport) @public_key = public_key @dc_number = dc_number @test_mode = test_mode @timeout = timeout @server_key = nil @auth_key = nil @server_salt = nil @time_offset = 0 @session = nil @connection_initialized = false @user_id = nil @access_hash = nil @device_model = 'Ruby MTProto' @system_version = RUBY_DESCRIPTION @app_version = '0.1.0' @system_lang_code = 'en' @lang_pack = '' @lang_code = 'en' @receiver_task = nil @running = false @on_update_callbacks = [] end |
Instance Attribute Details
#access_hash ⇒ Object (readonly)
Returns the value of attribute access_hash.
25 26 27 |
# File 'lib/mtproto/client.rb', line 25 def access_hash @access_hash end |
#api_hash ⇒ Object
Returns the value of attribute api_hash.
27 28 29 |
# File 'lib/mtproto/client.rb', line 27 def api_hash @api_hash end |
#api_id ⇒ Object
Returns the value of attribute api_id.
27 28 29 |
# File 'lib/mtproto/client.rb', line 27 def api_id @api_id end |
#app_version ⇒ Object
Returns the value of attribute app_version.
27 28 29 |
# File 'lib/mtproto/client.rb', line 27 def app_version @app_version end |
#auth_key ⇒ Object (readonly)
Returns the value of attribute auth_key.
25 26 27 |
# File 'lib/mtproto/client.rb', line 25 def auth_key @auth_key end |
#connection ⇒ Object (readonly)
Returns the value of attribute connection.
25 26 27 |
# File 'lib/mtproto/client.rb', line 25 def connection @connection end |
#dc_number ⇒ Object (readonly)
Returns the value of attribute dc_number.
25 26 27 |
# File 'lib/mtproto/client.rb', line 25 def dc_number @dc_number end |
#device_model ⇒ Object
Returns the value of attribute device_model.
27 28 29 |
# File 'lib/mtproto/client.rb', line 27 def device_model @device_model end |
#lang_code ⇒ Object
Returns the value of attribute lang_code.
27 28 29 |
# File 'lib/mtproto/client.rb', line 27 def lang_code @lang_code end |
#lang_pack ⇒ Object
Returns the value of attribute lang_pack.
27 28 29 |
# File 'lib/mtproto/client.rb', line 27 def lang_pack @lang_pack end |
#server_key ⇒ Object (readonly)
Returns the value of attribute server_key.
25 26 27 |
# File 'lib/mtproto/client.rb', line 25 def server_key @server_key end |
#server_salt ⇒ Object (readonly)
Returns the value of attribute server_salt.
25 26 27 |
# File 'lib/mtproto/client.rb', line 25 def server_salt @server_salt end |
#session ⇒ Object (readonly)
Returns the value of attribute session.
25 26 27 |
# File 'lib/mtproto/client.rb', line 25 def session @session end |
#system_lang_code ⇒ Object
Returns the value of attribute system_lang_code.
27 28 29 |
# File 'lib/mtproto/client.rb', line 27 def system_lang_code @system_lang_code end |
#system_version ⇒ Object
Returns the value of attribute system_version.
27 28 29 |
# File 'lib/mtproto/client.rb', line 27 def system_version @system_version end |
#time_offset ⇒ Object (readonly)
Returns the value of attribute time_offset.
25 26 27 |
# File 'lib/mtproto/client.rb', line 25 def time_offset @time_offset end |
#timeout ⇒ Object (readonly)
Returns the value of attribute timeout.
25 26 27 |
# File 'lib/mtproto/client.rb', line 25 def timeout @timeout end |
#user_id ⇒ Object (readonly)
Returns the value of attribute user_id.
25 26 27 |
# File 'lib/mtproto/client.rb', line 25 def user_id @user_id end |
Instance Method Details
#api ⇒ Object
166 167 168 |
# File 'lib/mtproto/client.rb', line 166 def api @api ||= API.new(self) end |
#auth_key? ⇒ Boolean
32 33 34 |
# File 'lib/mtproto/client.rb', line 32 def auth_key? !@auth_key.nil? end |
#disconnect! ⇒ Object
132 133 134 135 136 137 138 139 140 |
# File 'lib/mtproto/client.rb', line 132 def disconnect! @running = false @receiver_task&.stop @receiver_task = nil rpc.signal_all_error(Transport::ConnectionError.new('Client shutting down')) @connection.disconnect! if @connection&.connected? end |
#exchange_keys! ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/mtproto/client.rb', line 142 def exchange_keys! raise ArgumentError, 'public_key is required for auth key generation' if @public_key.nil? || @public_key.empty? generator = AuthKeyGenerator.new( @connection, @public_key, @dc_number, test_mode: @test_mode, timeout: @timeout ) result = generator.generate @auth_key = generator.auth_key @server_salt = generator.server_salt @time_offset = generator.time_offset @session = Session.new result end |
#init_connection! ⇒ Object
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/mtproto/client.rb', line 170 def init_connection! return if @connection_initialized query = TL::InvokeWithLayer.new( layer: API_LAYER, query: TL::InitConnection.new( api_id: api_id, device_model: device_model, system_version: system_version, app_version: app_version, system_lang_code: system_lang_code, lang_pack: lang_pack, lang_code: lang_code, query: TL::GetConfig.new ) ) response = rpc.call(query, TL::HelpConfig) response.wait!(timeout) @connection_initialized = true response.body end |
#load_auth_data(auth_data) ⇒ Object
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/mtproto/client.rb', line 208 def load_auth_data(auth_data) raise ArgumentError, 'auth_data must be a Hash' unless auth_data.is_a?(Hash) raise ArgumentError, 'auth_key is required' unless auth_data[:auth_key] raise ArgumentError, 'server_salt is required' unless auth_data[:server_salt] @auth_key = Base64.strict_decode64(auth_data[:auth_key]) @server_salt = auth_data[:server_salt] @time_offset = auth_data[:time_offset] || 0 @user_id = auth_data[:user_id] @access_hash = auth_data[:access_hash] @session = Session.new true end |
#mainloop_running? ⇒ Boolean
36 37 38 |
# File 'lib/mtproto/client.rb', line 36 def mainloop_running? @running end |
#on_update(&block) ⇒ Object
84 85 86 |
# File 'lib/mtproto/client.rb', line 84 def on_update(&block) @on_update_callbacks << block end |
#rpc ⇒ Object
162 163 164 |
# File 'lib/mtproto/client.rb', line 162 def rpc @rpc ||= RPC.new(self) end |
#run_mainloop ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/mtproto/client.rb', line 88 def run_mainloop raise 'Auth key not set' unless auth_key? raise 'Mainloop already running' if @running raise ArgumentError, 'Block is required' unless block_given? begin Async do start_receiving! yield self ensure disconnect! end rescue Interrupt # Ctrl+C end end |
#save_auth_data ⇒ Object
195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/mtproto/client.rb', line 195 def save_auth_data raise 'Cannot save auth_data: auth_key not set' unless @auth_key { auth_key: Base64.strict_encode64(@auth_key), server_salt: @server_salt, user_id: @user_id, access_hash: @access_hash, dc_number: @dc_number, time_offset: @time_offset } end |
#start_receiving! ⇒ Object
Start the receiver task without taking over the current Async reactor. Use when orchestrating multiple clients in a shared Async block — call from inside an Async do … end. The caller is responsible for disconnect! at the end.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/mtproto/client.rb', line 109 def start_receiving! raise 'Auth key not set' unless auth_key? raise 'Mainloop already running' if @running @running = true @receiver_task = Async do @connection.receive do |packet, error| if error warn "[MTProto] Packet read error: #{error.}" next end decrypted = EncryptedMessage.decrypt( auth_key: @auth_key, encrypted_message_data: packet.data.pack('C*'), sender: :server ) (decrypted[:body]) end end end |
#update_server_salt(new_salt) ⇒ Object
229 230 231 |
# File 'lib/mtproto/client.rb', line 229 def update_server_salt(new_salt) @server_salt = new_salt end |
#update_user(user_id:, access_hash: nil) ⇒ Object
224 225 226 227 |
# File 'lib/mtproto/client.rb', line 224 def update_user(user_id:, access_hash: nil) @user_id = user_id @access_hash = access_hash end |