southbridgeio / tdlib-ruby

Ruby bindings and client for TDLib
MIT License
94 stars 45 forks source link

The README.md example doesn't work #63

Open yart opened 1 year ago

yart commented 1 year ago

My Gemfile:

gem 'dry-configurable', '0.15.0'
gem 'tdlib-ruby'

Trying to run the example from the current README and getting only the following:

/home/yart/work/alcom/coding/tapp/vendor/bundle/ruby/3.2.0/gems/dry-configurable-0.15.0/lib/dry/configurable/dsl.rb:28:in `initialize' [dry-configurable] passing a constructor as a block is deprecated and will be removed in the next major version
Provide a `constructor:` keyword argument instead

/home/yart/work/alcom/coding/tapp/vendor/bundle/ruby/3.2.0/gems/dry-configurable-0.15.0/lib/dry/configurable/dsl.rb:28:in `initialize' [dry-configurable] default value as positional argument to settings is deprecated and will be removed in the nex
t major version
Provide a `default:` keyword argument instead

/home/yart/work/alcom/coding/tapp/vendor/bundle/ruby/3.2.0/gems/dry-configurable-0.15.0/lib/dry/configurable/dsl.rb:28:in `initialize' [dry-configurable] default value as positional argument to settings is deprecated and will be removed in the nex
t major version
Provide a `default:` keyword argument instead

I've been tried ruby 2.7.8 and 3.2.2 — the same result.

The last warning has been repeated several times. And that's all this code does.

I've changed the dry-configurable version according to this issue: https://github.com/southbridgeio/tdlib-ruby/issues/62. I had the same error before.

Who can help me, guys?

yart commented 1 year ago

Changed this part of tdlib-ruby.rb in such a way:

  setting(:client) do
    setting(:api_id) { |val| val.to_i } # before: setting :api_id, &:to_i
    setting :api_hash
    setting :use_test_dc, default: false # before: setting :use_test_dc, false
    setting :database_directory, default: "#{Dir.home}/.tdlib-ruby/db" # before: setting :database_directory, "#{Dir.home}/.tdlib-ruby/db"
    setting :files_directory, default: "#{Dir.home}/.tdlib-ruby/data" # before: setting :files_directory, "#{Dir.home}/.tdlib-ruby/data"
    setting :use_file_database, default: true # before: setting :use_file_database, true
    setting :use_chat_info_database, default: true # before: setting :use_chat_info_database, true
    setting :use_secret_chats, default: true # before: setting :use_secret_chats, true
    setting :use_message_database, default: true # before: setting :use_message_database, true
    setting :system_language_code, default: 'en' # before: setting :system_language_code, 'en'
    setting :device_model, default: 'Ruby TD client' # before: setting :device_model, 'Ruby TD client'
    setting :system_version, default: 'Unknown' # before: setting :system_version, 'Unknown'
    setting :application_version, default: '1.0' # before: setting :application_version, '1.0'
    setting :enable_storage_optimizer, default: true # before: setting :enable_storage_optimizer, true
    setting :ignore_file_names, default: false # before: setting :ignore_file_names, false
  end

Now it's starting without errors and warnings, but the state variable from the example is receiving nothing from this block:

  state = nil

  client.on(TD::Types::Update::AuthorizationState) do |update|
    state =
      case update.authorization_state
      when TD::Types::AuthorizationState::WaitPhoneNumber
        :wait_phone_number
      when TD::Types::AuthorizationState::WaitCode
        :wait_code
      when TD::Types::AuthorizationState::WaitPassword
        :wait_password
      when TD::Types::AuthorizationState::Ready
        :ready
      end
  end

And my code is just busy. But as I got it, it should show me the prompt to put my phone and so on.

From: /home/user/coding/tapp/tel.rb:37 :

    32:   end
    33: 
    34:   client.connect
    35: 
    36:   loop do
 => 37:     binding.pry
    38: 
    39:     case state
    40:     when :wait_phone_number
    41:       puts 'Please, enter your phone number:'
    42:       phone = STDIN.gets.strip

[1] pry(main)> client
=> #<TD::Client:0x00007fe836fdd858
 @alive=true,
 @config=
  {:api_id=>"----------", # my real API ID is shown here
   :api_hash=>"----------------------------", # and the API Hash too
   :use_test_dc=>false,
   :database_directory=>"/home/user/.tdlib-ruby/db",
   :files_directory=>"/home/user/.tdlib-ruby/data",
   :use_file_database=>true,
   :use_chat_info_database=>true,
   :use_secret_chats=>true,
   :use_message_database=>true,
   :system_language_code=>"en",
   :device_model=>"Ruby TD client",
   :system_version=>"Unknown",
   :application_version=>"1.0",
   :enable_storage_optimizer=>true,
   :ignore_file_names=>false},
[2] pry(main)> state
=> nil
[3] pry(main)> !!!

Do you have any idea on how to fix it, guys?

olegzakharov1416 commented 1 year ago

@yart Write if you can solve this problem. I’m also struggling with it now, I have no ideas.

yart commented 1 year ago

@yart Write if you can solve this problem. I’m also struggling with it now, I have no ideas.

Sure. I have an assumption that the problem in one of the following places:

  1. Incorrectly built TDlib — I've been built it using g++ v.13.2.1 installed on Archlinux. I have Clang too, but it produces a strange error when I'm trying to compile the library using this one. So, I'm going to do the following to resolve this possible trouble: a. Install TDlib from AUR — it has one b. Try to compile it in a Docker container (or find a ready one) with Ubuntu or Alpine and clang
  2. TDlib was changed and needs another set of parameters, so the current one should be changed to the actual state. Will read the TDlib docs to check it.
  3. Some insignificant changes in dry-rb (like it happened with dry-configurable, but not so fatal) or/and in concurrent-ruby. Will read the sources and the change logs to check it.
KonstantinReido commented 6 months ago

@yart did you find a solution?

yart commented 6 months ago

@yart did you find a solution?

@KonstantinReido I didn't have a time for this yet. But I remember about the problem.

chhlga commented 4 months ago

Tdlib changed input params for setTdlibParameters.

https://github.com/tdlib/td/issues/2211#issuecomment-1327625869

tilvin commented 3 months ago

Let me share my experience how to work with this lib:

  1. Install TDlib from original resource https://tdlib.github.io/td/build.html?language=Ruby. Tick V Install built TDLib to /usr/local instead of placing the files to td/tdlib.

  2. Fork schema https://github.com/southbridgeio/tdlib-schema is old and dusty, you will have to fork iе. Add this PR and add some other changes.

The most important one is to change set_tdlib_parameters method to cover this changes in TDlib:

def set_tdlib_parameters(parameters:)
   broadcast(parameters.to_hash.merge('@type' => 'setTdlibParameters'))
end

Also i'm trying to inline schema with Tdlib, maybe i will create a PR soon, but at the moment you can check my fork https://github.com/tilvin/tdlib-schema.

  1. Then authorize:
TD.configure do |config|    
  config.client.api_id = 'api_id'
  config.client.api_hash = 'api_hash'
end
TD::Api.set_log_verbosity_level(1)

client = TD::Client.new

Add debugging puts:

client.on(TD::Types::Update::AuthorizationState) do |update|
   puts "----->  #{update.inspect}"
end
  1. Then connect:

client.connect

  1. Now you suppose to see the auth requirements, something like WaitPhoneNumber.

Pick method from ClientMethods accordingly.

client.set_authentication_phone_number(phone_number: '+7 phone', settings: nil).wait
—> code comes to TG

client.check_authentication_code(code: 'your code’)
  1. Check if it's alive
    client.on('updateNewMessage') do |update|
    puts "========> NEWS updateNewMessage #{update.inspect}"
    end
  2. Tips You might see notifications like: Uncaught exception in update manager: [TD::Types::ScopeNotificationSettings.new] :sound is missing in Hash input Uncaught exception in update manager: Can't find class for updateChatFolders Uncaught exception in update manager: Can't find class for updateStoryStealthMode

It comes from rescue, and means that e.g schema's class ScopeNotificationSettings attributes doesn't match with TDlib scopeNotificationSettings anymore. And Tdlib has updateChatFolders class, but your schema don't.

vladimir-vg commented 3 months ago

The most important one is to change set_tdlib_parameters method to cover this changes in TDlib:

Hm, on my machine it doesn't see .merge method for TD::Types::TdlibParameters, which is a subclass of Dry::Struct:

-----> #<TD::Types::Update::AuthorizationState authorization_state=#<TD::Types::AuthorizationState::WaitTdlibParameters>>
Uncaught exception in handler TD::UpdateHandler (TD::Types::Update::AuthorizationState): undefined method `merge' for an instance of TD::Types::TdlibParameters

I've used gem 'dry-configurable', '0.15.0', otherwise it just refuses to load tdlib-ruby with no receiver given message.

Tried to replace .merge with .new, with no luck for now.

tilvin commented 3 months ago

The most important one is to change set_tdlib_parameters method to cover this changes in TDlib:

Hm, on my machine it doesn't see .merge method for TD::Types::TdlibParameters, which is a subclass of Dry::Struct:

-----> #<TD::Types::Update::AuthorizationState authorization_state=#<TD::Types::AuthorizationState::WaitTdlibParameters>>
Uncaught exception in handler TD::UpdateHandler (TD::Types::Update::AuthorizationState): undefined method `merge' for an instance of TD::Types::TdlibParameters

I've used gem 'dry-configurable', '0.15.0', otherwise it just refuses to load tdlib-ruby with no receiver given message.

Tried to replace .merge with .new, with no luck for now.

Thanks, i forgot this part: a small update set_tdlib_parameters(parameters: TD::Types::TdlibParameters.new(**@config).to_hash) here

Or

def set_tdlib_parameters(parameters:)
   broadcast(parameters.to_hash.merge('@type' => 'setTdlibParameters'))
end

to change only one gem instead of two.

vladimir-vg commented 3 months ago

Thanks, i forgot this part: a small update

Thanks! Indeed, this fix made that error disappear