patch fae93b3a3f74e5858d8bf4f090f8ed245894e4c9
Author: E. Bosch <presidev@AT@gmail.com>
Date: Sun Jul 19 22:35:25 CEST 2026
* telegram: Add support for 2nd factor authentication (2FA) password for Telegram accounts that have it enabled.
This will work consistenly with "ask_code" option whether True or False.
Refactored authentication code to not produce too many login code requests
to avoid bans. Improve error logging.
Remove the use of aioconsole, use to_thread with standard functions instead.
hunk ./README.md 58
+- Login code and 2FA password support for Telegram
hunk ./README.md 67
-- [aioconsole] (tested with v0.6.1)
hunk ./irgramd 81
- tornado.options.define('ask_code', default=False, help='Ask authentication code (sent by Telegram) in console instead of "code" service command in IRC')
+ tornado.options.define('ask_code', default=False, help='Ask authentication code (sent by Telegram) and 2FA password (if enabled) in console instead of "code" service command in IRC')
hunk ./service.py 11
+from telethon.errors.rpcerrorlist import SessionPasswordNeededError
hunk ./service.py 17
- 'code': (self.handle_command_code, 1, 1, -1),
+ 'code': (self.handle_command_code, 1, 2, -1),
hunk ./service.py 45
- 'use /msg {} code <code>'.format(self.irc.service_user.irc_nick),
- 'e.g. /msg {} code 12345'.format(self.irc.service_user.irc_nick)
+ 'use /msg or equivalent in your IRC client',
+ 'e.g. /msg {} code 12345'.format(self.irc.service_user.irc_nick),
+ 'If 2nd authentication factor (2FA) password is enabled in',
+ 'your account, you must provide it as well',
+ 'e.g. /msg {} code 12345 password'.format(self.irc.service_user.irc_nick),
hunk ./service.py 52
- async def handle_command_code(self, code=None, help=None):
+ async def handle_command_code(self, code=None, passw=None, help=None):
hunk ./service.py 57
+ valid_auth = True
hunk ./service.py 60
+ except SessionPasswordNeededError:
+ try:
+ await self.tg.telegram_client.sign_in(password=passw)
+ except:
+ reply = ('Invalid 2FA password',)
+ valid_auth = False
hunk ./service.py 68
- else:
- reply = ('Valid code', 'Telegram account authorized')
+ valid_auth = False
+ if valid_auth:
+ reply = ('Valid authentication', 'Telegram account authorized')
hunk ./service.py 76
- reply = (' code Enter authorization code',)
+ reply = (' code Enter authorization code and 2FA password',)
hunk ./service.py 80
- ' code <code>',
+ ' code <code> [<password>]',
hunk ./service.py 82
- 'another client connected.',
- 'This authorization code usually is only needed the first time',
+ 'another client connected. If 2nd factor authentication (2FA) password',
+ 'is enabled in your account, must be provided too.',
+ 'This authentication usually is only needed the first time',
hunk ./telegram.py 13
-import aioconsole
hunk ./telegram.py 16
+from getpass import getpass
hunk ./telegram.py 20
+from telethon.errors.rpcerrorlist import SessionPasswordNeededError
hunk ./telegram.py 127
- while not await self.telegram_client.is_user_authorized():
+ if not await self.telegram_client.is_user_authorized():
hunk ./telegram.py 133
- self.logger.info('You must provide the Login code that Telegram will '
- 'sent you via SMS or another connected client')
- code = await aioconsole.ainput('Login code: ')
+ attempts_msg = ('After 3 failed authentication attempts, aborted. '
+ 'Please restart irgramd to try again')
+ count = 1
+ while not await self.telegram_client.is_user_authorized():
+ if count > 3:
+ self.logger.error(attempts_msg)
+ return
+ await asyncio.to_thread(print, 'You must provide the Login code that Telegram will '
+ 'sent you via SMS or another connected client')
+ code = await asyncio.to_thread(input, 'Login code: ')
hunk ./telegram.py 145
- except:
- pass
+ except SessionPasswordNeededError:
+ count = 1
+ while not await self.telegram_client.is_user_authorized():
+ if count > 3:
+ self.logger.error(attempts_msg)
+ return
+ await asyncio.to_thread(print, '2nd factor authentication (2FA) password is enabled '
+ 'in your account, you must provide it')
+ passw = await asyncio.to_thread(getpass, 'Password (not shown): ')
+ try:
+ await self.telegram_client.sign_in(password=passw)
+ except BaseException as err:
+ self.logger.error(repr(err))
+ count += 1
+ except BaseException as err:
+ self.logger.error(repr(err))
+ count += 1