Client
In short, to create a client you can use:
from grammers import Client
client = Client(name, api_id, api_hash)
async def main():
async client:
# Now you can use all client methods listed below, like for example...
await client.send_message('me', 'Hello to myself!')
client.run(main())
See Client Reference for a short summary.
- class grammers.client.Client(session, api_id, api_hash, *, phone=None, code=None, password=None, bot_token=None, app_version=None, device_model=None, system_version=None, lang_code='en', system_lang_code='en', use_ipv6=False)
Bases:
Client- Parameters:
session (str | Session)
api_id (int | str)
api_hash (str)
phone (str | Callable[[], str | Awaitable[str]] | None)
code (Callable[[], str | int | Awaitable[str | int]] | None)
password (str | PasswordCallback | None)
bot_token (str | None)
app_version (str | None)
device_model (str | None)
system_version (str | None)
lang_code (str | None)
system_lang_code (str | None)
use_ipv6 (bool)
- run(coroutine=None)
Shortcut run method, which automatically invoke Client.start() and Client.stop().
If no parameter is provided, it runs Client.idle() within the async with block.
If an Awaitable (e.g., a coroutine) is provided, it awaits that coroutine instead of Client.idle(),
- Parameters:
coroutine (Awaitable | None)
- class grammers._rs.client.Client(session, api_id, api_hash, *, phone, code, password, bot_token=None, device_model=None, system_version=None, app_version=None, lang_code=None, system_lang_code=None, use_ipv6=False)
Bases:
object- accept_invite_link(invite_link)
Import a chat invite and join a private chat/supergroup/channel.
Only users can use this method.
- add_handler(event, handler)
- api_hash
- api_id
- app_version
- authorize()
Terminal interactive login.
- Pseudo-code
async def authorize(self) -> types.User: bot_token = self.bot_token if bot_token: return await self.bot_sign_in(bot_token) # check if session is logined session = self.session dc_id = await session.home_dc_id() dc_option = await session.dc_option(dc_id) if dc_option and dc_option.auth_key: if x := await self.get_password_information(): return await self.auto_check_password(x) phone = utils.maybe_call(self.phone) phone = await utils.maybe_await(phone) if not isinstance(phone, str): return ValueError(f"phone excepted str, got '{type(phone).__qualname__}'") login_token = await self.request_login_code(phone, self.api_hash) code = self.code() code = str(await utils.maybe_await(code)) try: return await self.sign_in(login_token, code) except PasswordRequiredError: return await self.auto_check_password()
- auto_check_password(password_info=None)
Check password used by Client.authorize()
- Pseudo-code
async def auto_check_password(self, password_info: types.account.Password | None = None) -> types.User: if password_info is None: password_info = await self.get_password_information() hint = password_info.hint password = self.password password = utils.maybe_call(password, [hint]) password = await utils.maybe_await(password) if not isinstance(password, str): raise ValueError(f"password excepted str, got '{type(password).__qualname__}'") return await sekf.check_password(password_info, password)
- bot_sign_in(bot_token=None)
Signs in to the bot account associated with this token.
This is the method you need to call to use the client under a bot account.
It is recommended to save the session on successful login. Some session storages will do this automatically. If saving fails, it is recommended to Client.sign_out(). If the session is never saved post-login, then the authorization will be “lost” in the list of logged-in clients, since it is unaccessible.
- Example
# Note: these values are obviously fake. # Obtain your own with the developer's phone at https://my.telegram.org. API_HASH: str = "514727c32270b9eb8cc16daf17e21e57" # Obtain your own by talking to @BotFather via a Telegram app. BOT_TOKEN: str = "776609994:AAFXAy5-PawQlnYywUlZ_b_GOXgarR3ah_yq" client = Client('bot', API_ID, API_HASH, bot_token=BOT_TOKEN) async def main(): user = await client.bot_sign_in() print('Signed in as {user.first_name}')
- bot_token
- check_invite_link(invite_link)
Check the validity of a chat invite link and get basic info about it.
Only users can use this method.
- check_password(password_info, password)
Sign in using two-factor authentication (user password).
password_token can be obtained from PasswordRequiredError error after the Client.sign_in() method fails.
- Example
# API_HASH: str = '' # PHONE: str = '' def get_user_password(hint: str) -> String: return getpass.getpass(f'Please input password: (hint: {hint})') # token = await client.request_login_code(PHONE, API_HASH) # code = '' # ... enter phone number, request login code ... try: let user = await client.sign_in(token, code) except errors.PasswordRequiredError as e: password_token = e.password_token password = get_user_password(password_token.hint) try: user = await client.check_password(password_token, password) except errors.RpcError as e: print('Sign in required') except errors.RpcError as e: print('Failed to sign in as a user:', traceback.format_exc(e))
- code
- complete_login(auth)
Complete login, will cache peer and save update state.
- Pseudo-code
async def complete_login(self, auth: types.auth.Authorization) -> types.User: user = auth.user user_id = user.id bot = getattr(user, 'bot', None) session = self.session auth = None if not getattr(user, 'min', False): auth = user.access_hash else: peer = await session.peer(user_id) if peer: auth = peer.auth await session.cache_peer(PeerInfo.User( user_id, auth, bot, True, )) try: state = await self.client(functions.updates.GetState()) except errors.RpcError: pass else: await session.set_update_state(UpdateState.All( state.pts, state.qts, state.date, state.seq, [], )) return user
- device_model
- disconnect()
Signals all clients sharing the same sender pool to disconnect.
- get_me()
Fetch information about the currently logged-in user.
Although this method is cheap to call, you might want to use the Client.me attribute which automatically cached by Client.start() method.
Both users and bots can use this method.
- Example
await client.get_me()
- get_messages_by_id(peer, message_ids)
Get messages by id
Both users and bots can use this method.
- Example
messages = await client.get_messages_by_id(peer, [123])
- get_password_information()
Extract information needed for the two-factor authentication It’s called automatically when we get SESSION_PASSWORD_NEEDED error during sign in.
- idle()
Block until the event pool finishes or a termination signal is received (SIGINT / SIGTERM).
- invoke(request)
Invoke a raw API call. This directly sends the request to Telegram’s servers.
Using function definitions corresponding to a different layer is likely to cause the responses to the request to not be understood.
Warning
This method is not part of the stability guarantees of semantic versioning. It may break during minor version changes (but not on patch version changes). Use with care.
- Example
await client.invoke(functions.Ping(ping_id=0))
- invoke_in_dc(dc_id, request)
- invoke_raw(request_body)
low-level api, send data to telegram directly.
- invoke_raw_in_dc(dc_id, request_body)
- is_authorized()
Returns true if the current account is authorized. Otherwise, logging in will be required before being able to invoke requests.
This will likely be the first method you want to call on a connected Client. After you determine if the account is authorized or not, you will likely want to use either Client.bot_sign_in() or Client.request_login_code().
- Example
if await client.is_authorized(): print('Client already authorized and ready to use!') else: print('Client is not authorized, you will need to sign_in!')
- iter_history_messages(peer, limit=None, *, offset_id=0, offset_date=0, add_offset=0, page_limit=0, max_id=0, min_id=0)
Returns the conversation history with one interlocutor / within a chat
Only users can use this method
- Example
# Get the latest message of Telegram. async for m in client.iter_history_messages(777000, limit=1) print(m.date) print(m.message) # Or without using async for iterator = client.iter_history_messages( 777000, limit=None, ) # Determines how many messages there are in total. print(await iterator.total()) # Get the next `Message`. print(await iterator.next()) # or await anext(iterator)
- lang_code
- me
- on(event)
- static parse_invite_link(invite_link)
- password
- phone
- request_login_code(phone, api_hash)
Requests the login code for the account associated to the given phone number via another Telegram application or SMS.
This is the method you need to call before being able to sign in to a user account. After you obtain the code and it’s inside your program (e.g. ask the user to enter it via the console’s standard input), you will need to Client.sign_in() to complete the process.
- Example
# Note: these values are obviously fake. # Obtain your own with the developer's phone at https://my.telegram.org. API_HASH: str = "514727c32270b9eb8cc16daf17e21e57" # The phone used here does NOT need to be the same as the one used by the developer # to obtain the API ID and hash. PHONE: str = "+1 415 555 0132" if not await client.is_authorized(): # We're not logged in, so request the login code. token = await client.request_login_code(PHONE, API_HASH)
- resolve_input_peer(peer)
Resolves a InputPeer into a Peer.
Both users and bots can use this method.
- resolve_peer(peer)
Resolves any InputPeerLike to a Peer.
Both users and bots can use this method.
- resolve_peer_ref(peer)
Resolves any InputPeerLike to a PeerRef, with using cached access_hash.
Both users and bots can use this method.
- resolve_phone(phone)
Resolves a phone to a User.
Both users and bots can use this method
- resolve_username(username)
Resolves a username (not prefix with ‘@’) into the peer that owns it, if any.
Note that this method is expensive to call, and can quickly cause long flood waits.
Both users and bots can use this method.
- Example
if peer := await client.resolve_username("username"): print("Found peer!: {:?}", peer.name)
- session
- sign_in(token, code)
Signs in to the user account.
You must call Client.request_login_code before using this method in order to obtain necessary login token, and also have asked the user for the login code.
It is recommended to save the session on successful login. Some session storages will do this automatically. If saving fails, it is recommended to Client.sign_out(). If the session is never saved post-login, then the authorization will be “lost” in the list of logged-in clients, since it is unaccessible.
- Example
# API_HASH: str = '' # PHONE: str = '' def ask_code_to_user() -> str: return input('Please input code you received:') token = await client.request_login_code(PHONE, API_HASH) code = ask_code_to_user() try: user = await client.sign_in(token, code) except errors.PasswordRequiredError as e: token = e.token print('Please provide a password') except errors.SignUpRequiredError: print('Sign up required') except errors.RPCError as e: print('Failed to sign in as a user:\n', traceback.format_exc(e)) if user.first_name: print(f"Signed in as {user.first_name}!") else: print("Signed in!")
- sign_out()
Signs out of the account authorized by this client’s session.
If the client was not logged in, this method raise RpcError.
The client is not disconnected after signing out.
Note that after using this method you will have to sign in again. If all you want to do is disconnect, simply call await client.stop().
- Example
from grammers import errors try: await client.sign_out() except errors.RpcError: print("No user was signed in, so nothing has changed..."); else: print("Signed out successfully!");
- start()
Start login in to telegram
- stop()
Stop client Calling clent’s methods after stopping will raise ClientStoppedError.
- system_lang_code
- system_version
- trigger_event(event)
- use_ipv6