Class: TD::Client

Inherits:
Object
  • Object
show all
Includes:
Concurrent
Defined in:
lib/tdlib/client.rb

Overview

Simple client for TDLib.

Examples:

TD.configure do |config|
  config.lib_path = 'path_to_tdlibjson'
  config.encryption_key = 'your_encryption_key'

  config.client.api_id = your_api_id
  config.client.api_hash = 'your_api_hash'
end

client = TD::Client.new

begin
  state = nil

  client.on('updateAuthorizationState') do |update|
    next unless update.dig('authorization_state', '@type') == 'authorizationStateWaitPhoneNumber'
    state = :wait_phone
  end

  client.on('updateAuthorizationState') do |update|
    next unless update.dig('authorization_state', '@type') == 'authorizationStateWaitCode'
    state = :wait_code
  end

  client.on('updateAuthorizationState') do |update|
    next unless update.dig('authorization_state', '@type') == 'authorizationStateReady'
    state = :ready
  end

  loop do
    case state
    when :wait_phone
      p 'Please, enter your phone number:'
      phone = STDIN.gets.strip
      params = {
        '@type' => 'setAuthenticationPhoneNumber',
        'phone_number' => phone
      }
      client.broadcast_and_receive(params)
    when :wait_code
      p 'Please, enter code from SMS:'
      code = STDIN.gets.strip
      params = {
        '@type' => 'checkAuthenticationCode',
        'code' => code
      }
      client.broadcast_and_receive(params)
    when :ready
      @me = client.broadcast_and_receive('@type' => 'getMe')
      break
    end
  end

ensure
  client.close
end

p @me

Constant Summary collapse

TIMEOUT =
20

Instance Method Summary collapse

Constructor Details

#initialize(td_client = TD::Api.client_create, update_manager = TD::UpdateManager.new(td_client), proxy: { '@type' => 'proxyEmpty' }, **extra_config) ⇒ Client

Returns a new instance of Client.


65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/tdlib/client.rb', line 65

def initialize(td_client = TD::Api.client_create,
               update_manager = TD::UpdateManager.new(td_client),
               proxy: { '@type' => 'proxyEmpty' },
               **extra_config)
  @td_client = td_client
  @update_manager = update_manager
  @config = TD.config.client.to_h.merge(extra_config)
  @proxy = proxy
  @ready_condition_mutex = Mutex.new
  @ready_condition = ConditionVariable.new
  authorize
  @update_manager.run
end

Instance Method Details

#authorization_stateHash

Returns current authorization state (it's offline request)

Returns:

  • (Hash)

129
130
131
# File 'lib/tdlib/client.rb', line 129

def authorization_state
  broadcast_and_receive('@type' => 'getAuthorizationState')
end

#broadcast(query, timeout: TIMEOUT) ⇒ Concurrent::Promise

Sends asynchronous request to the TDLib client and returns Promise object

Examples:

client.broadcast(some_query).then { |result| puts result }.rescue

Parameters:

  • query (Hash)
  • timeout (Numeric) (defaults to: TIMEOUT)

Returns:

  • (Concurrent::Promise)

See Also:


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/tdlib/client.rb', line 86

def broadcast(query, timeout: TIMEOUT)
  Promise.execute do
    condition = ConditionVariable.new
    extra = TD::Utils.generate_extra(query)
    result = nil
    mutex = Mutex.new
    handler = ->(update) do
      return unless update['@extra'] == extra
      mutex.synchronize do
        result = update
        @update_manager.remove_handler(handler)
        condition.signal
      end
    end
    @update_manager.add_handler(handler)
    query['@extra'] = extra
    mutex.synchronize do
      TD::Api.client_send(@td_client, query)
      condition.wait(mutex, timeout)
      raise TD::TimeoutError if result.nil?
      result
    end
  end
end

#closeObject

Stops update manager and destroys TDLib client


152
153
154
155
# File 'lib/tdlib/client.rb', line 152

def close
  @update_manager.stop
  TD::Api.client_destroy(@td_client)
end

#execute(query) ⇒ Object

Synchronously executes TDLib request Only a few requests can be executed synchronously

Parameters:

  • query (Hash)

123
124
125
# File 'lib/tdlib/client.rb', line 123

def execute(query)
  TD::Api.client_execute(@td_client, query)
end

#fetch(query, timeout: TIMEOUT) ⇒ Hash Also known as: broadcast_and_receive

Sends asynchronous request to the TDLib client and returns received update synchronously

Parameters:

  • query (Hash)

Returns:

  • (Hash)

114
115
116
# File 'lib/tdlib/client.rb', line 114

def fetch(query, timeout: TIMEOUT)
  broadcast(query, timeout: timeout).value
end

#on(update_type) {|update| ... } ⇒ Object

Binds passed block as a handler for updates with type of update_type

Parameters:

  • update_type (String)

Yields:

  • (update)

    yields update to the block as soon as it's received


136
137
138
139
140
141
142
# File 'lib/tdlib/client.rb', line 136

def on(update_type, &_)
  handler = ->(update) do
    return unless update['@type'] == update_type
    yield update
  end
  @update_manager.add_handler(handler)
end

#on_ready(timeout: TIMEOUT, &_) ⇒ Object


144
145
146
147
148
149
# File 'lib/tdlib/client.rb', line 144

def on_ready(timeout: TIMEOUT, &_)
  @ready_condition_mutex.synchronize do
    return(yield self) if @ready || (@ready_condition.wait(@ready_condition_mutex, timeout) && @ready)
    raise TD::TimeoutError
  end
end