mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-10 19:46:36 +03:00
Added .start() convenience method to quickly connect/authorize (#528)
This commit is contained in:
parent
eaef392a9b
commit
80f81fe69a
|
@ -39,11 +39,7 @@ Creating a client
|
||||||
phone = '+34600000000'
|
phone = '+34600000000'
|
||||||
|
|
||||||
client = TelegramClient('session_name', api_id, api_hash)
|
client = TelegramClient('session_name', api_id, api_hash)
|
||||||
client.connect()
|
client.start()
|
||||||
|
|
||||||
# If you already have a previous 'session_name.session' file, skip this.
|
|
||||||
client.sign_in(phone=phone)
|
|
||||||
me = client.sign_in(code=77777) # Put whatever code you received here.
|
|
||||||
|
|
||||||
|
|
||||||
Doing stuff
|
Doing stuff
|
||||||
|
|
|
@ -76,6 +76,22 @@ As a full example:
|
||||||
me = client.sign_in(phone_number, input('Enter code: '))
|
me = client.sign_in(phone_number, input('Enter code: '))
|
||||||
|
|
||||||
|
|
||||||
|
All of this, however, can be done through a call to ``.start()``:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
client = TelegramClient('anon', api_id, api_hash)
|
||||||
|
client.start()
|
||||||
|
|
||||||
|
|
||||||
|
The code shown is just what ``.start()`` will be doing behind the scenes
|
||||||
|
(with a few extra checks), so that you know how to sign in case you want
|
||||||
|
to avoid using ``input()`` (the default) for whatever reason.
|
||||||
|
|
||||||
|
You can use either, as both will work. Determining which
|
||||||
|
is just a matter of taste, and how much control you need.
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
If you want to use a **proxy**, you have to `install PySocks`__
|
If you want to use a **proxy**, you have to `install PySocks`__
|
||||||
(via pip or manual) and then set the appropriated parameters:
|
(via pip or manual) and then set the appropriated parameters:
|
||||||
|
@ -113,6 +129,9 @@ account, calling :meth:`telethon.TelegramClient.sign_in` will raise a
|
||||||
client.sign_in(password=getpass.getpass())
|
client.sign_in(password=getpass.getpass())
|
||||||
|
|
||||||
|
|
||||||
|
The mentioned ``.start()`` method will handle this for you as well, but
|
||||||
|
you must set the ``password=`` parameter beforehand (it won't be asked).
|
||||||
|
|
||||||
If you don't have 2FA enabled, but you would like to do so through the library,
|
If you don't have 2FA enabled, but you would like to do so through the library,
|
||||||
take as example the following code snippet:
|
take as example the following code snippet:
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import itertools
|
import itertools
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import time
|
import time
|
||||||
from collections import OrderedDict, UserList
|
from collections import OrderedDict, UserList
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
@ -14,8 +15,8 @@ from . import TelegramBareClient
|
||||||
from . import helpers, utils
|
from . import helpers, utils
|
||||||
from .errors import (
|
from .errors import (
|
||||||
RPCError, UnauthorizedError, PhoneCodeEmptyError, PhoneCodeExpiredError,
|
RPCError, UnauthorizedError, PhoneCodeEmptyError, PhoneCodeExpiredError,
|
||||||
PhoneCodeHashEmptyError, PhoneCodeInvalidError, LocationInvalidError
|
PhoneCodeHashEmptyError, PhoneCodeInvalidError, LocationInvalidError,
|
||||||
)
|
SessionPasswordNeededError)
|
||||||
from .network import ConnectionMode
|
from .network import ConnectionMode
|
||||||
from .tl import TLObject
|
from .tl import TLObject
|
||||||
from .tl.custom import Draft, Dialog
|
from .tl.custom import Draft, Dialog
|
||||||
|
@ -184,6 +185,104 @@ class TelegramClient(TelegramBareClient):
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def start(self, phone=None, password=None, bot_token=None,
|
||||||
|
force_sms=False, code_callback=None):
|
||||||
|
"""
|
||||||
|
Convenience method to interactively connect and sign in if required,
|
||||||
|
also taking into consideration that 2FA may be enabled in the account.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
>>> client = TelegramClient(session, api_id, api_hash).start(phone)
|
||||||
|
Please enter the code you received: 12345
|
||||||
|
Please enter your password: *******
|
||||||
|
(You are now logged in)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
phone (:obj:`str` | :obj:`int`):
|
||||||
|
The phone to which the code will be sent.
|
||||||
|
|
||||||
|
password (:obj:`callable`, optional):
|
||||||
|
The password for 2 Factor Authentication (2FA).
|
||||||
|
This is only required if it is enabled in your account.
|
||||||
|
|
||||||
|
bot_token (:obj:`str`):
|
||||||
|
Bot Token obtained by @BotFather to log in as a bot.
|
||||||
|
Cannot be specified with `phone` (only one of either allowed).
|
||||||
|
|
||||||
|
force_sms (:obj:`bool`, optional):
|
||||||
|
Whether to force sending the code request as SMS.
|
||||||
|
This only makes sense when signing in with a `phone`.
|
||||||
|
|
||||||
|
code_callback (:obj:`callable`, optional):
|
||||||
|
A callable that will be used to retrieve the Telegram
|
||||||
|
login code. Defaults to `input()`.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
:obj:`TelegramClient`:
|
||||||
|
This client, so initialization can be chained with `.start()`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if code_callback is None:
|
||||||
|
def code_callback():
|
||||||
|
return input('Please enter the code you received: ')
|
||||||
|
elif not callable(code_callback):
|
||||||
|
raise ValueError(
|
||||||
|
'The code_callback parameter needs to be a callable '
|
||||||
|
'function that returns the code you received by Telegram.'
|
||||||
|
)
|
||||||
|
|
||||||
|
if (phone and bot_token) or (not phone and not bot_token):
|
||||||
|
raise ValueError(
|
||||||
|
'You must provide either a phone number or a bot token, '
|
||||||
|
'not both (or neither).'
|
||||||
|
)
|
||||||
|
|
||||||
|
if not self.is_connected():
|
||||||
|
self.connect()
|
||||||
|
|
||||||
|
if self.is_user_authorized():
|
||||||
|
return self
|
||||||
|
|
||||||
|
if bot_token:
|
||||||
|
self.sign_in(bot_token=bot_token)
|
||||||
|
return self
|
||||||
|
|
||||||
|
me = None
|
||||||
|
attempts = 0
|
||||||
|
max_attempts = 3
|
||||||
|
two_step_detected = False
|
||||||
|
|
||||||
|
self.send_code_request(phone, force_sms=force_sms)
|
||||||
|
while attempts < max_attempts:
|
||||||
|
try:
|
||||||
|
# Raises SessionPasswordNeededError if 2FA enabled
|
||||||
|
me = self.sign_in(phone, code_callback())
|
||||||
|
break
|
||||||
|
except SessionPasswordNeededError:
|
||||||
|
two_step_detected = True
|
||||||
|
break
|
||||||
|
except (PhoneCodeEmptyError, PhoneCodeExpiredError,
|
||||||
|
PhoneCodeHashEmptyError, PhoneCodeInvalidError):
|
||||||
|
print('Invalid code. Please try again.', file=sys.stderr)
|
||||||
|
attempts += 1
|
||||||
|
else:
|
||||||
|
raise RuntimeError(
|
||||||
|
'{} consecutive sign-in attempts failed. Aborting'
|
||||||
|
.format(max_attempts)
|
||||||
|
)
|
||||||
|
|
||||||
|
if two_step_detected:
|
||||||
|
if not password:
|
||||||
|
raise ValueError(
|
||||||
|
"Two-step verification is enabled for this account. "
|
||||||
|
"Please provide the 'password' argument to 'start()'."
|
||||||
|
)
|
||||||
|
me = self.sign_in(phone=phone, password=password)
|
||||||
|
|
||||||
|
# We won't reach here if any step failed (exit by exception)
|
||||||
|
print('Signed in successfully as', utils.get_display_name(me))
|
||||||
|
return self
|
||||||
|
|
||||||
def sign_in(self, phone=None, code=None,
|
def sign_in(self, phone=None, code=None,
|
||||||
password=None, bot_token=None, phone_code_hash=None):
|
password=None, bot_token=None, phone_code_hash=None):
|
||||||
"""
|
"""
|
||||||
|
@ -216,7 +315,7 @@ class TelegramClient(TelegramBareClient):
|
||||||
:meth:`.send_code_request()`.
|
:meth:`.send_code_request()`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if phone and not code:
|
if phone and not code and not password:
|
||||||
return self.send_code_request(phone)
|
return self.send_code_request(phone)
|
||||||
elif code:
|
elif code:
|
||||||
phone = utils.parse_phone(phone) or self._phone
|
phone = utils.parse_phone(phone) or self._phone
|
||||||
|
@ -230,15 +329,9 @@ class TelegramClient(TelegramBareClient):
|
||||||
if not phone_code_hash:
|
if not phone_code_hash:
|
||||||
raise ValueError('You also need to provide a phone_code_hash.')
|
raise ValueError('You also need to provide a phone_code_hash.')
|
||||||
|
|
||||||
try:
|
# May raise PhoneCodeEmptyError, PhoneCodeExpiredError,
|
||||||
if isinstance(code, int):
|
# PhoneCodeHashEmptyError or PhoneCodeInvalidError.
|
||||||
code = str(code)
|
result = self(SignInRequest(phone, phone_code_hash, str(code)))
|
||||||
|
|
||||||
result = self(SignInRequest(phone, phone_code_hash, code))
|
|
||||||
|
|
||||||
except (PhoneCodeEmptyError, PhoneCodeExpiredError,
|
|
||||||
PhoneCodeHashEmptyError, PhoneCodeInvalidError):
|
|
||||||
return None
|
|
||||||
elif password:
|
elif password:
|
||||||
salt = self(GetPasswordRequest()).current_salt
|
salt = self(GetPasswordRequest()).current_salt
|
||||||
result = self(CheckPasswordRequest(
|
result = self(CheckPasswordRequest(
|
||||||
|
@ -310,7 +403,7 @@ class TelegramClient(TelegramBareClient):
|
||||||
or None if the request fails (hence, not authenticated).
|
or None if the request fails (hence, not authenticated).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Your own user.
|
:obj:`User`: Your own user.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return self(GetUsersRequest([InputUserSelf()]))[0]
|
return self(GetUsersRequest([InputUserSelf()]))[0]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user