2019-04-06 06:12:54 +00:00
|
|
|
require 'tdlib-ruby'
|
|
|
|
|
2019-04-06 07:29:48 +00:00
|
|
|
|
2019-04-06 06:12:54 +00:00
|
|
|
class TelegramClient
|
|
|
|
|
|
|
|
# tdlib configuration, shared within all instances #
|
|
|
|
def self.configure(params)
|
|
|
|
TD.configure do |config|
|
|
|
|
config.lib_path = params[:lib_path] || 'lib/'
|
2019-04-06 07:29:48 +00:00
|
|
|
config.client.api_id = params[:api_id] || '17349' # desktop telegram app
|
|
|
|
config.client.api_hash = params[:api_hash] || '344583e45741c457fe1862106095a5eb' # desktop telegram app
|
2019-04-06 06:12:54 +00:00
|
|
|
end
|
2019-04-06 07:29:48 +00:00
|
|
|
TD::Api.set_log_verbosity_level(params[:verbosity] || 1)
|
2019-04-06 06:12:54 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# instance initialization #
|
|
|
|
def initialize(xmpp, login)
|
|
|
|
|
2019-04-06 08:23:14 +00:00
|
|
|
@logger = Logger.new(STDOUT); @logger.progname = '[TelegramClient: %s/%s]' % [xmpp.user_jid, login] # create logger
|
|
|
|
@xmpp = xmpp # our XMPP user session. we will send messages back to Jabber through this instance.
|
|
|
|
@login = login # store tg login
|
2019-04-06 06:12:54 +00:00
|
|
|
|
2019-04-06 08:23:14 +00:00
|
|
|
# spawn telegram client and specify callback handlers
|
2019-04-06 07:29:48 +00:00
|
|
|
@logger.info 'Spawning Telegram client instance..'
|
2019-04-06 06:12:54 +00:00
|
|
|
@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::NewMessage) do |update| self.message_handler(update) end # register new message update handler
|
|
|
|
@client.connect #
|
|
|
|
|
2019-04-06 08:23:14 +00:00
|
|
|
# we will check for outgoing messages in a queue and/or auth data from XMPP thread while XMPP indicates that service is online #
|
2019-04-06 07:29:48 +00:00
|
|
|
begin
|
2019-04-06 07:46:29 +00:00
|
|
|
while not @xmpp.online? === false do
|
2019-04-06 06:12:54 +00:00
|
|
|
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(:password, @xmpp.tg_auth_data[:password]) unless @xmpp.tg_auth_data[:password].nil? # found 2fa password in auth queue
|
|
|
|
sleep 0.5
|
|
|
|
end
|
2019-04-06 07:29:48 +00:00
|
|
|
ensure
|
|
|
|
@logger.info 'Exitting gracefully...'
|
|
|
|
@client.dispose
|
|
|
|
end
|
2019-04-06 06:12:54 +00:00
|
|
|
end
|
2019-04-06 07:29:48 +00:00
|
|
|
|
|
|
|
###########################################
|
|
|
|
## Callback handlers #####################
|
|
|
|
###########################################
|
2019-04-06 06:12:54 +00:00
|
|
|
|
|
|
|
# authorization handler #
|
|
|
|
def auth_handler(update)
|
2019-04-06 07:29:48 +00:00
|
|
|
@logger.debug 'Authorization state changed: %s' % update.authorization_state
|
2019-04-06 06:12:54 +00:00
|
|
|
|
2019-04-06 07:29:48 +00:00
|
|
|
case update.authorization_state
|
2019-04-06 06:12:54 +00:00
|
|
|
# auth stage 0: specify login #
|
|
|
|
when TD::Types::AuthorizationState::WaitPhoneNumber
|
2019-04-06 07:29:48 +00:00
|
|
|
@logger.info 'Logging in..'
|
2019-04-06 06:12:54 +00:00
|
|
|
@client.set_authentication_phone_number(@login)
|
|
|
|
# auth stage 1: wait for authorization code #
|
|
|
|
when TD::Types::AuthorizationState::WaitCode
|
2019-04-06 07:29:48 +00:00
|
|
|
@logger.info 'Waiting for authorization code..'
|
2019-04-06 06:12:54 +00:00
|
|
|
@xmpp.send_message(nil, 'Please, enter authorization code via /code 12345')
|
|
|
|
# auth stage 2: wait for 2fa passphrase #
|
|
|
|
when TD::Types::AuthorizationState::WaitPassword
|
2019-04-06 07:29:48 +00:00
|
|
|
@logger.info 'Waiting for 2FA password..'
|
2019-04-06 06:12:54 +00:00
|
|
|
@xmpp.send_message(nil, 'Please, enter 2FA passphrase via /password 12345')
|
|
|
|
# authorizatio successful #
|
|
|
|
when TD::Types::AuthorizationState::Ready
|
2019-04-06 07:29:48 +00:00
|
|
|
@logger.info 'Authorization successful!'
|
2019-04-06 06:12:54 +00:00
|
|
|
@xmpp.send_message(nil, 'Authorization successful.')
|
2019-04-06 07:46:29 +00:00
|
|
|
@xmpp.online!
|
2019-04-06 06:12:54 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# message from telegram network handler #
|
|
|
|
def message_handler(update)
|
2019-04-06 07:29:48 +00:00
|
|
|
@logger.info 'Got NewMessage update'
|
2019-04-06 08:23:14 +00:00
|
|
|
from = update.message.chat_id.to_s
|
|
|
|
text = update.message.content.text.text.to_s
|
2019-04-06 06:12:54 +00:00
|
|
|
@xmpp.send_message(from, text) if not update.message.is_outgoing
|
|
|
|
end
|
|
|
|
|
2019-04-06 07:29:48 +00:00
|
|
|
###########################################
|
|
|
|
## LooP handlers #########################
|
|
|
|
###########################################
|
2019-04-06 06:12:54 +00:00
|
|
|
|
|
|
|
# processing authorization #
|
|
|
|
def process_auth(typ, data)
|
2019-04-06 07:29:48 +00:00
|
|
|
@logger.info 'Check authorization :%s..' % typ.to_s
|
2019-04-06 06:12:54 +00:00
|
|
|
@client.check_authentication_code(data) if typ == :code
|
|
|
|
@client.check_authentication_password(data) if typ == :password
|
|
|
|
@xmpp.tg_auth = {} # unset it to prevent extracting 2fa password from memory
|
|
|
|
end
|
|
|
|
|
|
|
|
# processing outgoing message from queue #
|
|
|
|
def process_outgoing_msg(msg)
|
2019-04-06 07:29:48 +00:00
|
|
|
@logger.info 'Sending message to user/chat <%s> within Telegram network..' % msg[:to]
|
2019-04-06 06:12:54 +00:00
|
|
|
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)
|
|
|
|
end
|
2019-04-06 07:29:48 +00:00
|
|
|
|
2019-04-06 06:12:54 +00:00
|
|
|
end
|