2024-01-31 19:37:01 +10:00
|
|
|
from loguru import logger
|
|
|
|
|
|
|
|
from opentele.tl import TelegramClient
|
|
|
|
from opentele.api import API
|
|
|
|
|
|
|
|
from telethon.tl.functions.channels import InviteToChannelRequest, JoinChannelRequest
|
|
|
|
from telethon.tl.functions.messages import AddChatUserRequest
|
2024-04-12 16:55:27 +10:00
|
|
|
from telethon.tl.functions.users import GetFullUserRequest
|
2024-01-31 19:37:01 +10:00
|
|
|
|
|
|
|
# Types
|
|
|
|
from telethon.hints import (Entity, EntityLike, MessageLike)
|
|
|
|
from telethon.types import Channel, Chat, User
|
|
|
|
from telethon.sessions.abstract import Session
|
|
|
|
|
|
|
|
from paper.errors import *
|
|
|
|
from telethon.errors.rpcerrorlist import (
|
|
|
|
ChatAdminRequiredError,
|
|
|
|
UserPrivacyRestrictedError,
|
|
|
|
UserNotMutualContactError,
|
|
|
|
ChannelPrivateError,
|
|
|
|
ChatWriteForbiddenError,
|
|
|
|
PeerFloodError,
|
|
|
|
FloodWaitError,
|
|
|
|
UsersTooMuchError,
|
|
|
|
UserChannelsTooMuchError,
|
|
|
|
UserIsBlockedError,
|
2024-02-08 17:59:42 +10:00
|
|
|
YouBlockedUserError,
|
|
|
|
UsernameInvalidError,
|
2024-03-12 19:49:06 +10:00
|
|
|
UserKickedError
|
2024-01-31 19:37:01 +10:00
|
|
|
)
|
|
|
|
|
|
|
|
class PaperClient(TelegramClient):
|
|
|
|
def __init__(self, session: str | Session) -> None:
|
2024-03-13 18:14:46 +10:00
|
|
|
api = API.TelegramAndroid.Generate(session)
|
2024-02-18 23:00:40 +10:00
|
|
|
super().__init__(f"sessions/{session}.session", api, flood_sleep_threshold=120)
|
2024-01-31 19:37:01 +10:00
|
|
|
|
|
|
|
async def invite_self(self, group: Entity | EntityLike):
|
|
|
|
group = await self.__cast_to_entity(group)
|
|
|
|
|
|
|
|
if isinstance(group, Channel):
|
|
|
|
await self(JoinChannelRequest(group))
|
|
|
|
logger.info(f"Added self to a channel {group.title}")
|
|
|
|
|
|
|
|
@logger.catch(reraise=True)
|
|
|
|
async def invite_user(self, user: Entity | EntityLike, group: Entity | EntityLike):
|
|
|
|
user, group = await self.__cast_to_entity(user), await self.__cast_to_entity(group)
|
|
|
|
|
|
|
|
try:
|
|
|
|
if isinstance(group, Channel) and isinstance(user, User):
|
|
|
|
await self(InviteToChannelRequest(group, [user])) # type: ignore
|
|
|
|
logger.info(f"User {user} was added to channel {group.title}")
|
|
|
|
|
|
|
|
elif isinstance(group, Chat) and isinstance(user, User):
|
|
|
|
await self(AddChatUserRequest(group, user, 30)) # type: ignore
|
|
|
|
logger.info(f"User {user} was added to chat {group.title}")
|
|
|
|
|
|
|
|
else:
|
|
|
|
logger.warning(f"Can't determine group type for {group}. Skipping...")
|
|
|
|
|
|
|
|
except (UserPrivacyRestrictedError, UserNotMutualContactError) as e:
|
|
|
|
raise UserPrivacyException(e)
|
|
|
|
|
|
|
|
except (ChatWriteForbiddenError, ChannelPrivateError, ChatAdminRequiredError) as e:
|
|
|
|
raise AdminPrivilegesExceptions(e)
|
|
|
|
|
|
|
|
except (PeerFloodError, FloodWaitError) as e:
|
|
|
|
raise FloodException(e)
|
|
|
|
|
2024-04-12 20:19:39 +10:00
|
|
|
except (UserChannelsTooMuchError, UsersTooMuchError, UserIsBlockedError, YouBlockedUserError, ValueError, UserKickedError, UsernameInvalidError) as e:
|
2024-01-31 19:37:01 +10:00
|
|
|
raise IgnoreException(e)
|
|
|
|
|
|
|
|
@logger.catch(reraise=True)
|
|
|
|
async def send_message(self, entity: Entity | EntityLike, message: str, file: str | None):
|
|
|
|
entity = await self.__cast_to_entity(entity)
|
|
|
|
|
|
|
|
try:
|
|
|
|
return await super().send_message(entity, message=message, file=file) #type: ignore
|
|
|
|
|
|
|
|
except (UserPrivacyRestrictedError, UserNotMutualContactError) as e:
|
|
|
|
raise UserPrivacyException(e)
|
|
|
|
|
|
|
|
except (ChatWriteForbiddenError, ChannelPrivateError, ChatAdminRequiredError) as e:
|
|
|
|
raise AdminPrivilegesExceptions(e)
|
|
|
|
|
|
|
|
except (PeerFloodError, FloodWaitError) as e:
|
|
|
|
raise FloodException(e)
|
|
|
|
|
|
|
|
except (UserChannelsTooMuchError, UsersTooMuchError, UserIsBlockedError, YouBlockedUserError) as e:
|
|
|
|
raise IgnoreException(e)
|
|
|
|
|
|
|
|
|
|
|
|
@logger.catch(reraise=True)
|
|
|
|
async def get_participants(self, group: Entity | EntityLike, *args, **kwargs):
|
|
|
|
group = await self.__cast_to_entity(group)
|
|
|
|
|
|
|
|
return await super().get_participants(group, *args, **kwargs)
|
|
|
|
|
|
|
|
async def __cast_to_entity(self, entity: Entity | EntityLike) -> Entity:
|
2024-02-08 17:59:42 +10:00
|
|
|
try:
|
|
|
|
if not isinstance(entity, Entity):
|
|
|
|
if hasattr(entity, "username"):
|
|
|
|
entity = await self.get_entity(entity.username)
|
|
|
|
else:
|
|
|
|
entity = await self.get_entity(entity)
|
2024-01-31 19:37:01 +10:00
|
|
|
|
2024-02-08 17:59:42 +10:00
|
|
|
return entity # type: ignore
|
|
|
|
except UsernameInvalidError as e:
|
|
|
|
raise IgnoreException(e)
|
2024-04-12 16:55:27 +10:00
|
|
|
|
|
|
|
async def get_full_info(self, user):
|
|
|
|
return await self(GetFullUserRequest(user))
|