@ -1,15 +1,16 @@
require 'tdlib-ruby'
require 'tdlib-ruby'
class TelegramClient
class TelegramClient
# tdlib configuration, shared within all instances #
# tdlib configuration, shared within all instances #
def self . configure ( params )
def self . configure ( params )
TD . configure do | config |
TD . configure do | config |
config . lib_path = params [ :lib_path ] || 'lib/'
config . lib_path = params [ :lib_path ] || 'lib/'
config . client . api_id = params [ :api_id ] || 430850
config . client . api_id = params [ :api_id ] || '17349' # desktop telegram app
config . client . api_hash = params [ :api_hash ] || '3 d3cfcbd30d0805f757c5fc521004861'
config . client . api_hash = params [ :api_hash ] || '3 44583e45741c457fe1862106095a5eb' # desktop telegram app
end
end
TD :: Api . set_log_verbosity_level ( params [ :verbos e ] || 1 )
TD :: Api . set_log_verbosity_level ( params [ :verbos ity ] || 1 )
end
end
# instance initialization #
# instance initialization #
@ -17,65 +18,71 @@ class TelegramClient
@xmpp = xmpp
@xmpp = xmpp
@login = login
@login = login
@logger = Logger . new ( STDOUT ) ; @logger . progname = '[TelegramClient: %s/%s]' % [ @xmpp . user_jid , @login ]
Logging . log . info '[TelegramClient] [%s] Initializing..' % @login
@logger . info 'Spawning Telegram client instance..'
@client = TD :: Client . new ( database_directory : 'sessions/' + @login , files_directory : 'sessions/' + @login + '/files/' ) # create telegram client instance
@client = TD :: Client . new ( database_directory : 'sessions/' + @login , files_directory : 'sessions/' + @login + '/files/' ) # create telegram client instance
@client . on ( TD :: Types :: Update :: AuthorizationState ) do | update | self . auth_handler ( update ) end # register auth update handler
@client . on ( TD :: Types :: Update :: AuthorizationState ) do | update | self . auth_handler ( update ) end # register auth update handler
@client . on ( TD :: Types :: Update :: NewMessage ) do | update | self . message_handler ( update ) end # register new message update handler
@client . on ( TD :: Types :: Update :: NewMessage ) do | update | self . message_handler ( update ) end # register new message update handler
@client . connect #
@client . connect #
# we will check new messages in queue and auth data in forever loop #
# we will check new messages in queue and auth data in forever loop #
# begin
begin
loop do
loop do
self . process_outgoing_msg ( @xmpp . message_queue . pop ) unless @xmpp . message_queue . empty? # found something in message queue
self . process_outgoing_msg ( @xmpp . message_queue . pop ) unless @xmpp . message_queue . empty? # found something in message queue
self . process_auth ( :code , @xmpp . tg_auth_data [ :code ] ) unless @xmpp . tg_auth_data [ :code ] . nil? # found code in auth queue
self . process_auth ( :code , @xmpp . tg_auth_data [ :code ] ) unless @xmpp . tg_auth_data [ :code ] . nil? # found code in auth queue
self . process_auth ( :password , @xmpp . tg_auth_data [ :password ] ) unless @xmpp . tg_auth_data [ :password ] . nil? # found 2fa password in auth queue
self . process_auth ( :password , @xmpp . tg_auth_data [ :password ] ) unless @xmpp . tg_auth_data [ :password ] . nil? # found 2fa password in auth queue
sleep 0 . 5
sleep 0 . 5
end
end
# ensure
ensure
#Logging.log.info '[TelegramClient] Exitting gracefully...'
@logger . info ' Exitting gracefully...'
#@client. dispose
@client . dispose
# end
end
end
end
###########################################
## Callback handlers #####################
###########################################
# authorization handler #
# authorization handler #
def auth_handler ( update )
def auth_handler ( update )
Logging . log . debug '[TelegramClient] [%s] Authorization state changed: %s' % [ @login , update . authorization_state ]
@logger . debug 'Authorization state changed: %s' % update . authorization_state
case update . authorization_state
case update . authorization_state
# auth stage 0: specify login #
# auth stage 0: specify login #
when TD :: Types :: AuthorizationState :: WaitPhoneNumber
when TD :: Types :: AuthorizationState :: WaitPhoneNumber
Logging . log . debug '[TelegramClient] [%s] Logging in..' % @login
@logger . info 'Logging in..'
@client . set_authentication_phone_number ( @login )
@client . set_authentication_phone_number ( @login )
# auth stage 1: wait for authorization code #
# auth stage 1: wait for authorization code #
when TD :: Types :: AuthorizationState :: WaitCode
when TD :: Types :: AuthorizationState :: WaitCode
@logger . info 'Waiting for authorization code..'
@xmpp . send_message ( nil , 'Please, enter authorization code via /code 12345' )
@xmpp . send_message ( nil , 'Please, enter authorization code via /code 12345' )
Logging . log . debug '[TelegramClient] [%s] Waiting for Authorization code..' % @login
# auth stage 2: wait for 2fa passphrase #
# auth stage 2: wait for 2fa passphrase #
when TD :: Types :: AuthorizationState :: WaitPassword
when TD :: Types :: AuthorizationState :: WaitPassword
@logger . info 'Waiting for 2FA password..'
@xmpp . send_message ( nil , 'Please, enter 2FA passphrase via /password 12345' )
@xmpp . send_message ( nil , 'Please, enter 2FA passphrase via /password 12345' )
Logging . log . debug '[TelegramClient] [%s] Waiting for 2FA password..' % @login
# authorizatio successful #
# authorizatio successful #
when TD :: Types :: AuthorizationState :: Ready
when TD :: Types :: AuthorizationState :: Ready
@logger . info 'Authorization successful!'
@xmpp . send_message ( nil , 'Authorization successful.' )
@xmpp . send_message ( nil , 'Authorization successful.' )
Logging . log . debug '[TelegramClient] [%s] Authorization successful.' % @login
end
end
end
end
# message from telegram network handler #
# message from telegram network handler #
def message_handler ( update )
def message_handler ( update )
Logging . log . debug '[TelegramClient] [%s] Got NewMessage update <%s>' % [ @login , update . message ]
@logger . info 'Got NewMessage update'
from = update . message . chat_id
from = update . message . chat_id
text = update . message . content . text . text
text = update . message . content . text . text
@xmpp . send_message ( from , text ) if not update . message . is_outgoing
@xmpp . send_message ( from , text ) if not update . message . is_outgoing
end
end
##################################################
###########################################
## LooP handlers #########################
###########################################
# processing authorization #
# processing authorization #
def process_auth ( typ , data )
def process_auth ( typ , data )
Logging . log . debug '[TelegramClient] [%s] Authorizing with <%s> in Telegram...' % [ @login , typ . to_s ]
@logger . info 'Check authorization :%s..' % typ . to_s
@client . check_authentication_code ( data ) if typ == :code
@client . check_authentication_code ( data ) if typ == :code
@client . check_authentication_password ( data ) if typ == :password
@client . check_authentication_password ( data ) if typ == :password
@xmpp . tg_auth = { } # unset it to prevent extracting 2fa password from memory
@xmpp . tg_auth = { } # unset it to prevent extracting 2fa password from memory
@ -83,8 +90,9 @@ class TelegramClient
# processing outgoing message from queue #
# processing outgoing message from queue #
def process_outgoing_msg ( msg )
def process_outgoing_msg ( msg )
Logging . log . debug '[TelegramClient] [%s] Sending message to user/chat <%s> within Telegram network..' % [ @login , msg [ :to ] ]
@logger . info ' Sending message to user/chat <%s> within Telegram network..' % msg [ :to ]
message = TD :: Types :: InputMessageContent :: Text . new ( :text = > { :text = > msg [ :text ] , :entities = > [ ] } , :disable_web_page_preview = > false , :clear_draft = > false )
message = TD :: Types :: InputMessageContent :: Text . new ( :text = > { :text = > msg [ :text ] , :entities = > [ ] } , :disable_web_page_preview = > false , :clear_draft = > false )
@client . send_message ( msg [ :to ] . to_i , message )
@client . send_message ( msg [ :to ] . to_i , message )
end
end
end
end