Задать вопрос
  • Как добавить inline кнопку в телеграмм боте?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Включить у бота режим inline.
    Отправить inline клавиатуру с параметром switch_inline_query_current_chat равным, допустим, "Аккумуляторы"
    Добавить inline_handler, в который отлавливать query и генерировать нужные результаты

    @bot.message_handler(commands=['start'])
    def send_start(message):
        markup = InlineKeyboardMarkup()
        markup.add(InlineKeyboardButton('Аккумуляторы', switch_inline_query_current_chat='Аккумуляторы'))
        bot.send_message(message.chat.id, 'Товары', reply_markup=markup)
    
    
    @bot.inline_handler(lambda query: query.query == 'Аккумуляторы')
    def query_video(inline_query):
        r = InlineQueryResultArticle('1', 'SONY VTC6 3000 mah 30A 18650', InputTextMessageContent('Аккумулятор 1'), description='blah', url='https://buy-battery.com/goods/1', hide_url=True, thumb_url='https://via.placeholder.com/50')
        r2 = InlineQueryResultArticle('2', 'SONY VTC5A 2600 mah 35A 18650', InputTextMessageContent('Аккумулятор 2'), description='blah', url='https://buy-battery.com/goods/2', hide_url=True, thumb_url='https://via.placeholder.com/50')
        bot.answer_inline_query(inline_query.id, [r, r2])


    Справка:
    https://core.telegram.org/bots/api#inline-mode
    https://github.com/eternnoir/pyTelegramBotAPI/blob...
    Ответ написан
    Комментировать
  • Как выводить ошибку в чат?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Если используете чей-то API, то стоит глянуть доку, что возвращается в случае неудачи (ну или просто самому попробовать). Скорее всего либо 4XX/5XX статусы, либо условный {"success": "false"}. Далее уже проверяете статус код, либо что нибудь в теле ответа. Это будет правильно.

    Чтобы именно ваш код работал, удалите KeyError, вряд ли такой вид вообще вызывается при таком коде

    upd: а, нифига себе, some-random-api не заглушка, а реальный сайт)
    Как и следовало, ошибки 500.

    @commands.command()
    async def lyrics(self, ctx,*, title):
    
        url = f"https://some-random-api.ml/lyrics?title={title}"
        req = requests.get(url)
        response = req.json()
    
        if req.status_code == 200:
            lyrics = response['lyrics']
    
            if len(lyrics) > 2048:
                em = discord.Embed(title=title,description = f"Я не смог отправить текст этой песни, поскольку он превышает 2000 символов. Однако вот файл с текстами песен!",color=0xa3a3ff)
                await ctx.send(embed=em)
                
                with open('lyrics.txt', 'w', encoding='utf-8') as f:
                    f.write(lyrics)
                
                await ctx.send(file=discord.File('lyrics.txt'))
    
            else:
                em = discord.Embed(title=title,description=lyrics,color=0xa3a3ff)
                await ctx.send(embed=em)
    
        elif req.status_code == 500:
    
            error = response.get('error', '?')
    
            if error == 'Sorry I couldn\'t find that song\'s lyrics':
                em = discord.Embed(title="Вот блин!",description="Мне не удалось найти текст этой песни.",color = 0xa3a3ff)
                em.set_thumbnail(url='https://cdn.discordapp.com/attachments/830818408550629407/839555682436251698/aw_snap_large.png')
                await ctx.send(embed=em)
    
            elif error == 'Something went wrong with fetching the lyrics':
                # тут что-то отвалилось, 500 код как он есть, можно попробовать запрос еще раз отправить на сайт,
                # либо сказать пользователю что на сайте проблемы, пусть еще раз попробует
                pass
    
            else:
                em = discord.Embed(title="Вот блин!", description=f"Неизвестная ошибка: {error}",color = 0xa3a3ff)
                em.set_thumbnail(url='https://cdn.discordapp.com/attachments/830818408550629407/839555682436251698/aw_snap_large.png')
                await ctx.send(embed=em)
        else:
            # ну тут уже бог знает что случилось, сайт ни ошибкой, ни хорошим ответом не порадовал.


    x4zx, обновил ответ
    Ответ написан
  • Перенос строки в команде say discord py?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    С точки зрения передачи аргументов все выглядит логично, программа понятия не имеет, где закончился один аргумент и где начался второй, поэтому всё разделяется по пробелу. Оберните строку в кавычки, тогда будет понятно, что текст в кавычках - один аргумент. *args тоже можно убрать в таком случае

    async def say(ctx, phrase):
        embed = discord.Embed(description=phrase, color=0x8A2BE2)


    !say "Привет,
    мир"
    Ответ написан
    4 комментария
  • Возможно ли отправить уведомление на пк при входящем переводе QIWI?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Можно
    https://developer.qiwi.com/ru/qiwi-wallet-personal...

    Читаете инструкцию по ссылке, выпускаете api ключ, создаете какой нибудь обработчик запросов, как из примера ниже, регестрируете вебхук в киви и пользуетесь.

    from flask import Flask, request, Response
    
    app = Flask(__name__)
    
    @app.route('/qiwi', methods=['POST'])
    def qiwi():
        print(request.data)
        return Response(status=200)
    Ответ написан
    4 комментария
  • Как прочитать данные из json файла и записать их в тот же файл?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Сначала прочитать, добавить нужные данные в объект и записать. Код "растянется" на две строчки, зато понятно будет что происходит.

    для экстремалов

    with open('file.txt', 'r+') as f:
        data = json.load(f)
        data.append(4)
        f.seek(0)
        json.dump(data, f)

    Костыль короче красивого и правильного кода на целую 1 строку
    Ответ написан
    2 комментария
  • Как выбрать нужные аргументы команды aiogram python?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Что не получилось то?

    upd
    user, money = message.get_args().split()
    Ответ написан
    4 комментария
  • Какими еще способами можно обновлять переменные о пользователе в Telegram(telebot)?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Удалить все глобальные переменные, заменив на хотя бы самую простую БД.
    Ответ написан
  • Как правильно прописать post запрос в python?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Выглядит как google forms, но у него другой эндпоинт и немного другие имена. Без ссылки на сайт никто не угадай что там нужно
    Ответ написан
  • Как записать строку в переменную с переносом в Python?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Обернув в тройные кавычки
    string = """
          Строка
          в переменной
    """


    Либо разделив через \
    string = "Строка " \
          "в переменной"
    Ответ написан
    2 комментария
  • Мистика Python GUI (Kivy) и Multiprocessing?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    В pyinstaller (и других "компиляторах") для мультипроцессорных приложений нужно сделать mp.freeze_support() сразу после if __name__ == '__main__':.
    Но подобные действия то еще развлечение, в будущем еще что нибудь отвалится
    https://docs.python.org/3/library/multiprocessing....
    Ответ написан
    4 комментария
  • Как отправить прямой запрос с помощью requests Python?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Добавлять другие заголовки, как вариант. Но если создателю сайта захотелось бы защититься от подобных запросов, то это делается в пол строки одним из кучи способов, и тогда уже никакие заголовки не помогут. Как вариант - попробовать selenium, но не факт, что будет работать, он тоже детектится очень быстро
    Ответ написан
    Комментировать
  • Как вытащить ссылку из массива данных в Python?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    msg.reply_markup.rows[0].buttons[0].url

    re:
    import re
    
    msg = '''[Message(id=899, peer_id=PeerUser(user_id=7415649360), date=datetime.datetime(2021, 8, 10, 9, 52, 37, tzinfo=datetime.timezone.utc), message='⚠️ WARNING: The following is a third party advertisement. Do not trust anything that promises to make you money. Use the following website at your own risk.\n---------------------  \n\nFree 100 OZC, price listing $30/OZC  \n\nStart in 15/07/2021: Free 100 OZC, price listing $30/OZC  \n  \n---------------------  \nPress the "Visit website" button to earn LTC.\nYou will be redirected to a third party site.', out=False, mentioned=False, media_unread=False, silent=False, post=False, from_scheduled=False, legacy=False, edit_hide=False, pinned=False, from_id=None, fwd_from=None, via_bot_id=None, reply_to=None, media=None, reply_markup=ReplyInlineMarkup(rows=[KeyboardButtonRow(buttons=[KeyboardButtonUrl(text=' Go to website', url='https://doge.click/visit/Ka1gfo')]), KeyboardButtonRow(buttons=[KeyboardButtonCallback(text=' Report', data=b'{"name":"ReportClick","id":"click_tasks61124bf44b4413.68559229"}', requires_password=False), KeyboardButtonCallback(text='⏩ Skip', data=b'{"name":"SkipClick","id":"click_tasks61124bf44b4413.68559229"}', requires_password=False)])]), entities=[MessageEntityItalic(offset=0, length=156), MessageEntityItalic(offset=157, length=21), MessageEntityBold(offset=182, length=35), MessageEntityItalic(offset=283, length=21), MessageEntityItalic(offset=307, length=45), MessageEntityItalic(offset=353, length=45)], views=None, forwards=None, replies=None, edit_date=None, post_author=None, grouped_id=None, restriction_reason=[], ttl_period=None), total=57]'''
    
    print(re.search(r'(https://.+?)\'', msg).group(1))
    Ответ написан
  • Как считать время проведенное в голосовом канале?

    SoreMix
    @SoreMix
    yellow
    @bot.event
    async def on_voice_state_update(member, before, after):
    
        # Если пользователь зашел в голосовой канал
        if after.channel and after.channel.type == discord.ChannelType.voice:
            joined_voice_channel = time.time()
            # сохраняем в БД
    
        # если вышел из голосового
        if not after.channel and before.channel.type == discord.ChannelType.voice:
            leave_voice_channel = time.time()
            # достаем из БД joined_voice_channel и вычитаем его из leave_voice_channel
    
            print('Время в голосовом канале:', leave_voice_channel-joined_voice_channel, 'секунд')


    https://discordpy.readthedocs.io/en/stable/api.htm...
    Ответ написан
  • Как сделать, чтобы бот оставил реакцию на сообщение пользователя?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    await ctx.message.add_reaction('✅')
    Ответ написан
    Комментировать
  • Почему бот не отдает фразу обратно?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Ошибки из консоли и подсвека из IDE? Переменная bot не определена.
    Ответ написан
    Комментировать
  • Использую библиотеку telebot, можно ли вставить стикеры в сообщение?

    SoreMix
    @SoreMix
    yellow
    Мне надо что бы я смог изменить шрифт текста, который я вывожу в телеграмме, а именно жирний шрифт и подчёркнутый текст.


    Используйте соответствующий Markdown:
    https://core.telegram.org/bots/api#formatting-options

    При отправке сообщения пишите ваш текст, и в send_message передайте аргумент parse_mode, вам подойдет обычный "Markdown"
    bot.send_message(chat_id, 'Обычный текст\n*Жирный*\n__подчерктнутый__', parse_mode='Markdown')


    Так же мне надо в одно сообщение вставить стикеры

    Стикеры нельзя вставить в какое-то сообщение, стикер и есть отдельное сообщение. Если имеется в виду просто отправка стикеров -
    # sendSticker
    sti = open('/tmp/sti.webp', 'rb')
    tb.send_sticker(chat_id, sti)
    tb.send_sticker(chat_id, "FILEID")

    Можете отправить любой с ПК, если он в формате webp, либо передать fileid.
    Сомневаюсь, что можно как нибудь достать все ID через bot API, скорее всего только через клиентский, но fileid можно узнавать хотя бы как-то так:
    @bot.message_handler(content_types=['sticker'])
    def send_sticker_id(message):
        bot.send_message(message.chat.id, f'This sticker id: {message.sticker.file_id}')

    ну и уже затем делать bot.send_sticker(chat_id, sticker_id), где sticker_id - id, который получили из кода выше
    Ответ написан
    Комментировать
  • Как обработать двухфакторную аутентификацию Google?

    SoreMix
    @SoreMix
    yellow
    2fa гугла (да и не только) по сути является просто секретной строкой, на основе которой генерируются коды. Установите библиотеку pyotp, достаньте вашу секретную строку (обычно либо сайт ее даёт в чистом виде, для использования в других приложениях, либо даёт хотя бы возможность сгенерировать QR код, который можно прочитать камерой и из него достать строку; альтернативный вариант - открыть логи запросов в браузере и сгенерировать новый 2fa код, он где нибудь отразиться в истории), далее просто делаете
    import pyotp
    code = pyotp.TOTP(secret_line).now()

    И отправляете этот код через requests, точно так же как и отправляет обычный браузер
    Ответ написан
    1 комментарий
  • Сайт возвращает 404 при отправке запроса requests?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Заголовок с юзерагентом добавьте

    response = requests.get(url, headers={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.2 Safari/605.1.15'})
    Ответ написан
    Комментировать
  • Как оптимизировать elif'ы?

    SoreMix
    @SoreMix Куратор тега Python
    yellow
    Самое банальное, что можно сделать - вынести одинаковые функции за ифы, а именно
    os.rename(file, new_path)

    А вообще -
    suffixes = {'Audio': ['.mp3', '.wav'], 'Photos': ['.jpg', '.png'], etc, etc}
    
    suffix = Path(file).suffix
    
    for folder_name, extensions in suffixes.items():
        if suffix in extensions:
            new_path = f'{folder_track}/{folder_name}/{filename}'
            break
    else:
        new_path = f'{folder_track}/Other/{filename}'
    
    os.rename(file, new_path)
    Ответ написан
    1 комментарий