Beispiel #1
0
    async def handler(self, event: events.ChatAction,
                      request_context: RequestContext):
        session_id = self.generate_session_id()

        request_context.add_default_fields(session_id=session_id)
        request_context.statbox(action='show', mode='submit')

        if event.document.mime_type != 'application/pdf':
            request_context.statbox(action='unknown_file_format')
            request_context.error_log(
                UnknownFileFormatError(format=event.document.mime_type))
            return await asyncio.gather(
                event.reply(
                    t('UNKNOWN_FILE_FORMAT_ERROR',
                      language=request_context.chat.language),
                    buttons=[close_button()],
                ),
                event.delete(),
            )

        return await asyncio.gather(
            self.application.hub_client.submit(
                telegram_document=bytes(event.document),
                telegram_file_id=event.file.id,
                chat=request_context.chat,
                request_id=request_context.request_id,
                session_id=session_id,
            ),
            event.delete(),
        )
Beispiel #2
0
    async def handler(self, event: events.ChatAction, request_context: RequestContext):
        raw_query = event.pattern_match.group(1)
        query = None

        request_context.statbox(action='start', mode='start')

        try:
            query = decode_deep_query(raw_query)
        except DecodeDeepQueryError as e:
            request_context.error_log(e, mode='start', raw_query=raw_query)

        if query:
            request_context.statbox(action='query', mode='start', query=query)
            request_message = await self.application.telegram_client.send_message(event.chat, query)
            prefetch_message = await request_message.reply(
                t("SEARCHING", language=request_context.chat.language),
            )
            self.application.user_manager.last_widget[request_context.chat.chat_id] = prefetch_message.id
            await asyncio.gather(
                event.delete(),
                self.do_search(event, request_context, prefetch_message, query=query,
                               is_shortpath_enabled=True),
            )
        else:
            request_context.statbox(action='show', mode='start')
            await event.reply(t('HELP', language=request_context.chat.language))
Beispiel #3
0
    async def handler(self, event: events.ChatAction,
                      request_context: RequestContext):
        schema, session_id, document_id, vote, vote_value = self.parse_pattern(
            event)

        request_context.add_default_fields(mode='vote', session_id=session_id)
        request_context.statbox(
            action='vote',
            document_id=document_id,
            query=vote,
            schema=schema,
        )

        document_operation_pb = DocumentOperationPb(vote=VotePb(
            document_id=document_id,
            value=vote_value,
            voter_id=request_context.chat.chat_id,
        ), )
        logging.getLogger('operation').info(
            msg=MessageToDict(document_operation_pb), )

        message = await event.get_message()

        # ToDo: Generalize nexus.views.telegram.common.remove_button and use it here
        return await asyncio.gather(
            self.application.telegram_client.edit_message(
                request_context.chat.chat_id,
                message.id,
                message.text,
                buttons=None,
            ),
            event.answer(t('TANKS_BRUH')),
        )
Beispiel #4
0
    async def handler(self, event: events.ChatAction,
                      request_context: RequestContext):
        session_id = self.generate_session_id()
        request_context.add_default_fields(mode='roll', session_id=session_id)
        request_context.statbox(action='show')

        roll_response_pb = await self.application.meta_api_client.roll(
            language=request_context.chat.language,
            session_id=session_id,
            request_id=request_context.request_id,
            user_id=str(request_context.chat.chat_id),
        )
        scitech_view = await self.resolve_scitech(
            document_id=roll_response_pb.document_id,
            position=0,
            request_context=request_context,
            session_id=session_id,
        )
        view, buttons = scitech_view.get_view(
            language=request_context.chat.language,
            session_id=session_id,
            bot_external_name=self.application.config['telegram']
            ['bot_external_name'],
        )
        actions = [
            self.application.telegram_client.send_message(
                request_context.chat.chat_id,
                view,
                buttons=buttons,
            ),
            event.delete(),
        ]
        return await asyncio.gather(*actions)
Beispiel #5
0
    async def handler(self, event: events.ChatAction, request_context: RequestContext):
        schema, session_id, old_message_id, document_id, position, page = self.parse_pattern(event)

        request_context.add_default_fields(mode='view', session_id=session_id)
        request_context.statbox(action='view', document_id=document_id, position=position, schema=schema)

        has_found_old_widget = old_message_id == self.application.user_manager.last_widget.get(request_context.chat.chat_id)

        try:
            message_id, link_preview = await self.process_widgeting(
                has_found_old_widget=has_found_old_widget,
                old_message_id=old_message_id,
                request_context=request_context
            )

            document_view = await self.resolve_document(
                schema,
                document_id,
                position,
                session_id,
                request_context,
            )
            try:
                back_command = await self.compose_back_command(
                    session_id=session_id,
                    message_id=message_id,
                    page=page,
                )
            except MessageHasBeenDeletedError:
                return await event.respond(
                    t('REPLY_MESSAGE_HAS_BEEN_DELETED', language=request_context.chat.language),
                )

            view, buttons = document_view.get_view(
                language=request_context.chat.language,
                session_id=session_id,
                bot_external_name=self.application.config['telegram']['bot_external_name'],
                position=position,
                back_command=back_command,
            )
            actions = [
                self.application.telegram_client.edit_message(
                    request_context.chat.chat_id,
                    message_id,
                    view,
                    buttons=buttons,
                    link_preview=link_preview,
                ),
                event.delete(),
            ]
            if not has_found_old_widget:
                actions.append(
                    self.application.telegram_client.delete_messages(
                        request_context.chat.chat_id,
                        [old_message_id],
                    )
                )
            return await asyncio.gather(*actions)
        except MessageIdInvalidError:
            await event.reply(t("VIEWS_CANNOT_BE_SHARED", language=request_context.chat.language))
    async def __init(self, configuration, loop):
        await self.__client.get_dialogs()
        # await self.__client.get_entity(89616296) # свея
        self.__client.on(
            ChatAction(configuration.group_id,
                       func=lambda __event: __event.user_joined or __event.
                       user_added))(self.__on_new_user_in_group, )

        print("User bot configured")
Beispiel #7
0
        def decorator(function):
            async def func_callback(event):
                try:
                    await function(event)
                except Exception as e:
                    self.log.error(
                        f"Function '{function.__name__}' stopped due to an unhandled exception",
                        exc_info=True if self.traceback else False)

            tgclient.add_event_handler(func_callback, ChatAction(**args))
            return func_callback
Beispiel #8
0
    async def handler(self, event: events.ChatAction,
                      request_context: RequestContext):
        session_id, message_id, page = self.parse_pattern(event)

        request_context.add_default_fields(mode='search_paging',
                                           session_id=session_id)
        start_time = time.time()

        message = await event.get_message()
        if not message:
            return await event.answer()

        reply_message = await message.get_reply_message()
        try:
            if not reply_message:
                raise MessageHasBeenDeletedError()
            query = self.preprocess_query(reply_message.raw_text)
            search_widget = await SearchWidget.create(
                application=self.application,
                chat=request_context.chat,
                session_id=session_id,
                message_id=message_id,
                request_id=request_context.request_id,
                query=query,
                page=page,
            )
        except MessageHasBeenDeletedError:
            return await event.respond(
                t('REPLY_MESSAGE_HAS_BEEN_DELETED',
                  language=request_context.chat.language), )
        except AioRpcError as e:
            if e.code() == StatusCode.INVALID_ARGUMENT or e.code(
            ) == StatusCode.CANCELLED:
                request_context.error_log(e)
                return await event.answer(
                    t('MAINTENANCE_WO_PIC',
                      language=request_context.chat.language), )
            raise e

        action = 'documents_found'
        if len(search_widget.scored_documents) == 0:
            action = 'documents_not_found'

        request_context.statbox(
            action=action,
            duration=time.time() - start_time,
            query=f'page:{page} query:{query}',
        )
        serp, buttons = await search_widget.render()
        return await asyncio.gather(
            event.answer(),
            message.edit(serp, buttons=buttons, link_preview=False))
Beispiel #9
0
        def decorator(function):
            async def func_callback(event):
                try:
                    await function(event)
                except Exception as e:
                    self.log.error(
                        f"Function '{function.__name__}' stopped due to an unhandled exception",
                        exc_info=True if self.traceback else False)

            try:
                tgclient.add_event_handler(func_callback,
                                           ChatAction(*args, **kwargs))
            except Exception as e:
                self.log.error(f"Failed to add a chat action feature to client "\
                               f"(in function '{function.__name__}')",
                               exc_info=True if self.traceback else False)
                return None
            return func_callback
Beispiel #10
0
    async def handler(self, event: events.ChatAction,
                      request_context: RequestContext):
        try:
            self.check_search_ban_timeout(
                user_id=str(request_context.chat.chat_id))
        except BannedUserError as e:
            request_context.error_log(e)
            return await event.reply(
                t('BANNED_FOR_SECONDS',
                  language=request_context.chat.language).format(
                      seconds=e.ban_timeout,
                      reason=t('BAN_MESSAGE_TOO_MANY_REQUESTS',
                               language=request_context.chat.language),
                  ))
        search_prefix, query, is_group_mode = self.parse_pattern(event)

        if is_group_mode and not search_prefix:
            return
        if not is_group_mode and search_prefix:
            query = event.raw_text

        prefetch_message = await event.reply(
            t("SEARCHING", language=request_context.chat.language), )
        self.application.user_manager.last_widget[
            request_context.chat.chat_id] = prefetch_message.id
        try:
            await self.do_search(
                event=event,
                request_context=request_context,
                prefetch_message=prefetch_message,
                query=query,
                is_group_mode=is_group_mode,
                is_shortpath_enabled=True,
            )
        except (AioRpcError, asyncio.CancelledError) as e:
            await asyncio.gather(
                event.delete(),
                prefetch_message.delete(),
            )
            raise e
Beispiel #11
0
        def decorator(function):
            caller_name = basename(
                getouterframes(currentframe(), 2)[1].filename)[:-3]

            async def func_callback(event):
                try:
                    await function(event)
                except Exception:
                    self.log.error(
                        f"Function '{function.__name__}' stopped "
                        "due to an unhandled exception",
                        exc_info=True if self.traceback else False)

            try:
                _tgclient.add_event_handler(func_callback,
                                            ChatAction(*args, **kwargs))
                update_handlers(caller_name, func_callback)
            except Exception:
                self.log.error(
                    f"Failed to add a chat action feature to "
                    f"client (in function '{function.__name__}')",
                    exc_info=True if self.traceback else False)
                return None
            return func_callback
Beispiel #12
0
from requests import get
from telethon.errors import ChatAdminRequiredError
from telethon.events import ChatAction
from telethon.tl.types import ChannelParticipantsAdmins
from telethon.utils import get_display_name

from ..Config import Config
from ..sql_helper.gban_sql_helper import get_gbanuser, is_gbanned
from ..utils import is_admin
from . import BOTLOG, BOTLOG_CHATID, catub, edit_or_reply, logging, spamwatch

LOGS = logging.getLogger(__name__)
plugin_category = "admin"
if Config.ANTISPAMBOT_BAN:

    @catub.on(ChatAction())
    async def anti_spambot(event):  # sourcery no-metrics
        if not event.user_joined and not event.user_added:
            return
        user = await event.get_user()
        catadmin = await is_admin(event.client, event.chat_id,
                                  event.client.uid)
        if not catadmin:
            return
        catbanned = None
        adder = None
        ignore = None
        if event.user_added:
            try:
                adder = event.action_message.sender_id
            except AttributeError:
Beispiel #13
0
    def __init__(self,
                 session: str,
                 api_id: int,
                 api_hash: str,
                 loop: asyncio.AbstractEventLoop,
                 bot_id: int,
                 chats: Iterable[int] = tuple()):
        """
        Need to create a client with API key, hash, and a session file
        Need a list of whitelisted chat IDs

        Create a queue for incoming messages.

        Args:
            session: Session authorization string
            api_id: API ID of Telegram client
            api_hash: API Hash of Telegram client
            loop: Event loop to run the client on, (can be provided by ``pytest-asyncio``)
        """

        # Build proxy parameters
        # Currently only support SOCKS5 proxy in ALL_PROXY environment variable
        proxy_env = os.environ.get('all_proxy') or os.environ.get('ALL_PROXY')
        if proxy_env and proxy_env.startswith('socks5://'):
            from socks import SOCKS5
            hostname, port, username, password = parse_socks5_link(proxy_env)
            proxy: Optional[Tuple] = (SOCKS5, hostname, port, True, username,
                                      password)
        else:
            proxy = None

        # Telethon client to use
        self.client: TelegramClient = TelegramClient(StringSession(session),
                                                     api_id,
                                                     api_hash,
                                                     proxy=proxy,
                                                     loop=loop,
                                                     sequential_updates=True)

        # Queue for incoming messages
        self.queue: "asyncio.queues.Queue[EventCommon]" = asyncio.queues.Queue(
        )

        # Collect mappings from message ID to its chat (as Telegram API is not sending them)
        self.message_chat_map: Dict[int, TypeInputPeer] = dict()

        self.chats = list(map(abs, chats))
        self.client.parse_mode = "html"
        self.client.add_event_handler(
            self.new_message_handler,
            NewMessage(chats=self.chats, incoming=True, from_users=[bot_id]))
        # self.client.add_event_handler(self.new_message_handler,
        #                               NewMessage(incoming=True))
        self.client.add_event_handler(self.deleted_message_handler,
                                      MessageDeleted())
        self.client.add_event_handler(self.update_handler,
                                      UserUpdate(chats=self.chats))
        self.client.add_event_handler(self.update_handler,
                                      MessageEdited(chats=self.chats))
        self.client.add_event_handler(self.update_handler,
                                      ChatAction(chats=self.chats))

        self.logger = logging.getLogger(__name__)
Beispiel #14
0
    async def do_search(
        self,
        event: events.ChatAction,
        request_context: RequestContext,
        prefetch_message,
        query: str,
        is_group_mode: bool = False,
        is_shortpath_enabled: bool = False,
    ):
        session_id = self.generate_session_id()
        message_id = prefetch_message.id
        request_context.add_default_fields(is_group_mode=is_group_mode,
                                           mode='search',
                                           session_id=session_id)
        start_time = time.time()

        try:
            search_widget = await SearchWidget.create(
                application=self.application,
                chat=request_context.chat,
                session_id=session_id,
                message_id=message_id,
                request_id=request_context.request_id,
                query=query,
                is_group_mode=is_group_mode,
            )
        except AioRpcError as e:
            actions = [
                self.application.telegram_client.delete_messages(
                    request_context.chat.chat_id,
                    [message_id],
                )
            ]
            if e.code() == StatusCode.INVALID_ARGUMENT:
                too_difficult_picture_url = self.application.config[
                    'application'].get('too_difficult_picture_url', '')
                if e.details() == 'url_query_error':
                    actions.append(
                        event.reply(
                            t('INVALID_QUERY_ERROR',
                              language=request_context.chat.language).format(
                                  too_difficult_picture_url=
                                  too_difficult_picture_url, ),
                            buttons=[close_button()],
                        ))
                elif e.details() == 'invalid_query_error':
                    actions.append(
                        event.reply(
                            t('INVALID_SYNTAX_ERROR',
                              language=request_context.chat.language).format(
                                  too_difficult_picture_url=
                                  too_difficult_picture_url, ),
                            buttons=[close_button()],
                        ))
                return await asyncio.gather(*actions)
            elif e.code() == StatusCode.CANCELLED:
                maintenance_picture_url = self.application.config[
                    'application'].get('maintenance_picture_url', '')
                request_context.error_log(e)
                actions.append(
                    event.reply(
                        t('MAINTENANCE',
                          language=request_context.chat.language).format(
                              maintenance_picture_url=maintenance_picture_url,
                          ),
                        buttons=[close_button()],
                    ))
                return await asyncio.gather(*actions)
            await asyncio.gather(*actions)
            raise e

        action = 'documents_found'
        if len(search_widget.scored_documents) == 0:
            action = 'documents_not_found'

        request_context.statbox(
            action=action,
            duration=time.time() - start_time,
            query=f'page:0 query:{query}',
        )

        if len(search_widget.scored_documents) == 1 and is_shortpath_enabled:
            scored_document = search_widget.scored_documents[0]
            document_view = parse_typed_document_to_view(
                scored_document.typed_document)
            # Second (re-)fetching is required to retrieve duplicates
            document_view = await self.resolve_document(
                schema=scored_document.typed_document.WhichOneof('document'),
                document_id=document_view.id,
                position=0,
                session_id=session_id,
                request_context=request_context,
            )
            view, buttons = document_view.get_view(
                language=request_context.chat.language,
                session_id=session_id,
                bot_external_name=self.application.config['telegram']
                ['bot_external_name'],
                with_buttons=not is_group_mode,
            )
            return await asyncio.gather(
                self.application.telegram_client.edit_message(
                    request_context.chat.chat_id,
                    message_id,
                    view,
                    buttons=buttons,
                ), )

        serp, buttons = await search_widget.render()
        return await self.application.telegram_client.edit_message(
            request_context.chat.chat_id,
            message_id,
            serp,
            buttons=buttons,
            link_preview=False,
        )