Esempio n. 1
0
    async def handle(self, message: types.Message, user: UserRepository,
                     _: dict):
        await message.bot.send_chat_action(message.from_user.id,
                                           ChatActions.TYPING)
        async with IntercomClient(INTERCOM_TOKEN) as intercom:

            intercom_user = await get_intercom_contact(message.from_user)

            conversations = await intercom.find_conversations_for_user(
                intercom_user["id"])

            keyboard_markup = types.InlineKeyboardMarkup(row_width=1)

            if conversations["total_count"] > 0:
                for conv in conversations["conversations"][
                    (1 - 1) * PER_PAGE_CONVERSATIONS:1 *
                        PER_PAGE_CONVERSATIONS]:
                    keyboard_markup.add(
                        types.InlineKeyboardButton(
                            f'#{conv["id"]} - ' +
                            (_["feedback_opened"]
                             if conv["open"] else _["feedback_closed"]),
                            callback_data=conv_cb.new(id=conv["id"],
                                                      action="open"),
                        ))

                buttons = []

                buttons.append(
                    types.InlineKeyboardButton(
                        _['new_feedback_button'],
                        callback_data=conv_cb.new(id="_", action="new"),
                    ))

                if (len(conversations["conversations"]) >
                        1 * PER_PAGE_CONVERSATIONS):
                    buttons.append(
                        types.InlineKeyboardButton(
                            _["next_button"],
                            callback_data=conv_cb.new(
                                id=2,
                                action="page",
                            ),
                        ), )

                keyboard_markup.row(*buttons)

                await message.answer(
                    _["feedback_menu_has_items"].format(
                        open=sum((1 for i in conversations["conversations"]
                                  if i["open"]), 0),
                        closed=sum((1 for i in conversations["conversations"]
                                    if not i["open"]), 0)),
                    reply_markup=keyboard_markup,
                )
                return

            keyboard_markup.row(
                types.InlineKeyboardButton(
                    _['new_feedback_button'],
                    callback_data=conv_cb.new(id="_", action="new"),
                ))

            await message.answer(
                _["feedback_menu_no_items"],
                reply_markup=keyboard_markup,
            )
Esempio n. 2
0
    async def job(self, con: Connection, item: NotificationQueue,
                  notifier: TelegramNotifier, locales: Dict):
        if (self.is_throttled):
            logger.warning(
                f'already throttled by telegram, skipping loaded items')
            return

        user_repo = UserRepository(con)
        notification_repo = NotificationRepository(con)

        reply_markup = None
        if (item.type_id == NotifyType.Conversation.value):
            conv_repo = ConversationRepository(con)
            reply_markup = types.InlineKeyboardMarkup(row_width=1)
            conv_id = await conv_repo.find_conversation_id_by_notification_id(
                item.notification_id)

            if (not conv_id):
                logger.warning(
                    f'conversation not found for {item.user_id} and {item.notification_id}'
                )
                item.status_id = NotifyStatus.Failed.value
                return await notification_repo.update(item)

            user = await user_repo.get_user(item.user_id)
            if (user):
                c_user_locale_code = Lang(user.lang_id).name

                reply_markup.row(
                    types.InlineKeyboardButton(
                        locales[c_user_locale_code]['feedback_reply_button'],
                        callback_data=conv_cb.new(
                            id=conv_id,
                            action="reply",
                        ),
                    ), )

        result = await notifier.notify(item.content,
                                       con,
                                       item.user_id,
                                       reply_markup=reply_markup)

        item.result = result.result.value

        if (result.result not in [TelegramSendResult.RetryAfter]):
            await asyncio.sleep(result.wait_time)

            if (result.result in [TelegramSendResult.Ok]):
                item.status_id = NotifyStatus.Sent.value

                if (item.type_id == NotifyType.Conversation.value):
                    conv_repo = ConversationRepository(con)
                    conv_id = await conv_repo.find_conversation_id_by_notification_id(
                        item.notification_id)
                    await conv_repo.update_conversation_message(
                        conv_id,
                        result.message_id,
                    )

            elif (result.result in [
                    TelegramSendResult.Blocked,
                    TelegramSendResult.Deactivated,
                    TelegramSendResult.ChatNotFound,
            ]):
                logger.warning(
                    f'{item.user_id} blocked bot or deactivated they telegram account, disabling notifications'
                )
                item.status_id = NotifyStatus.Failed.value
                if (item.type_id == NotifyType.Payout):
                    await user_repo.update_notification_payouts_setting(
                        item.user_id, False)
                elif (item.type_id == NotifyType.Worker):
                    await user_repo.update_notification_setting(
                        item.user_id, False)

            elif (result.result
                  in [TelegramSendResult.ApiError, TelegramSendResult.Error]):
                logger.warning(f'{item.user_id} api error.')
                item.status_id = NotifyStatus.Failed.value

        else:
            self.is_throttled = True
            item.status_id = NotifyStatus.New.value
            await notification_repo.create_throttled_record(
                item.channel_id, result.wait_time)

        await notification_repo.update(item)
Esempio n. 3
0
async def conversation_pages(
    query: types.CallbackQuery,
    callback_data: typing.Dict[str, str],
    user: UserRepository,
    _: LangHolder,
):
    page = int(callback_data['id'])

    async with IntercomClient(INTERCOM_TOKEN) as intercom:

        intercom_user = await get_intercom_contact(query.from_user)

        conversations = await intercom.find_conversations_for_user(
            intercom_user["id"])

        keyboard_markup = types.InlineKeyboardMarkup(row_width=1)

        if conversations["total_count"] > 0:
            current_conv_page = conversations["conversations"][
                (page - 1) * PER_PAGE_CONVERSATIONS:page *
                PER_PAGE_CONVERSATIONS]

            for conv in current_conv_page:
                keyboard_markup.add(
                    types.InlineKeyboardButton(
                        f'#{conv["id"]} - ' +
                        (_["feedback_opened"]
                         if conv["open"] else _["feedback_closed"]),
                        callback_data=conv_cb.new(id=conv["id"],
                                                  action="open"),
                    ))

            buttons = []

            if (page > 1):
                buttons.append(
                    types.InlineKeyboardButton(
                        _["prev_button"],
                        callback_data=conv_cb.new(
                            id=page - 1,
                            action="page",
                        ),
                    ), )

            buttons.append(
                types.InlineKeyboardButton(
                    _['new_feedback'],
                    callback_data=conv_cb.new(id="_", action="new"),
                ))

            if (len(current_conv_page) >= 1 * PER_PAGE_CONVERSATIONS):
                buttons.append(
                    types.InlineKeyboardButton(
                        _["next_button"],
                        callback_data=conv_cb.new(
                            id=page + 1,
                            action="page",
                        ),
                    ), )

            keyboard_markup.row(*buttons)

            await query.message.edit_text(
                _["feedback_menu_has_items"].format(
                    open=sum(
                        (1
                         for i in conversations["conversations"] if i["open"]),
                        0),
                    closed=sum((1 for i in conversations["conversations"]
                                if not i["open"]), 0)),
                reply_markup=keyboard_markup,
            )
            await query.answer()
            return

        keyboard_markup.row(
            types.InlineKeyboardButton(
                _['new_feedback_button'],
                callback_data=conv_cb.new(id="_", action="new"),
            ))

        await query.message.edit_text(
            _["feedback_menu_no_items"],
            reply_markup=keyboard_markup,
        )

        await query.answer()
Esempio n. 4
0
async def flow_page(
    query: types.CallbackQuery,
    callback_data: typing.Dict[str, str],
    user: UserRepository,
    _: LangHolder,
):
    conversation_id = int(callback_data['conv_id'])
    page = int(callback_data['id'])

    async with IntercomClient(INTERCOM_TOKEN) as intercom:
        intercom_conversation = await intercom.retrieve_conversation(
            conversation_id)

        comments = [intercom_conversation['source']] + [
            i for i in intercom_conversation['conversation_parts']
            ['conversation_parts'] if i['part_type'] in (
                'comment',
                'assignment',
            )
        ]
        last_message = sorted(comments,
                              key=lambda x: x.get('created_at', 0),
                              reverse=True)[page]

        keyboard_markup = types.InlineKeyboardMarkup(row_width=3)
        keyboard_markup.row(
            types.InlineKeyboardButton(
                _['feedback_reply_button'],
                callback_data=conv_cb.new(
                    id=conversation_id,
                    action="reply",
                ),
            ), )
        buttons = []

        if (last_message['type'] != 'conversation'):
            buttons.append(
                types.InlineKeyboardButton(
                    _["prev_button"],
                    callback_data=flow_cb.new(
                        id=page + 1,
                        action="page",
                        conv_id=conversation_id,
                    ),
                ))

        buttons.append(
            types.InlineKeyboardButton(
                f"{len(comments) - page}/{len(comments)}",
                callback_data="do_nothing"))

        if (page >= 1):
            buttons.append(
                types.InlineKeyboardButton(
                    _["next_button"],
                    callback_data=flow_cb.new(
                        id=page - 1,
                        action="page",
                        conv_id=conversation_id,
                    ),
                ))

        keyboard_markup.row(*buttons)

        attachments_text = ''
        if (last_message['attachments']):
            attachments_text = '\n'.join([
                _['conversation_description_attachments'].format(
                    link=f"<a href=\"{i['url']}\">{i['name']}</a>")
                for i in last_message['attachments']
            ])

        await query.message.edit_text(
            _['conversation_description'].format(
                from_who=_['support'] if last_message['author']['type']
                == 'admin' else _['not_support'],
                text=last_message['body'],
                time=datetime.fromtimestamp(
                    last_message.get(
                        'updated_at',
                        intercom_conversation['created_at'])).strftime(
                            "%d/%m/%Y %H:%M:%S"),
                attachments=attachments_text,
            ),
            reply_markup=keyboard_markup,
            disable_web_page_preview=True,
        )

        await query.answer()