Задать вопрос
  • Как реализовать в Телеграме общий чат для менеджеров?

    @Medovochka
    Наша компания использует этот сервис https://www.chatwoot.com/ для таких же целей как и у вас. У нас так же Саппорты общаются и отвечают через ТГ Бота, а это все отображается в том сервисе + много других классных полезностей
    Есть и фильтрация и ассайн саппортов под каждый тикет или каждого клиента

    Нам очень помогает в связке с ТГ
    Ответ написан
    Комментировать
  • Как сделать экспорт контента в Instagrma stories?

    @Medovochka
    Скопировать текст и фото, и затем вставить в публикацию / Историю Инстаграмма чем не вариант?

    Еще как вариант - можете сделать скриншот страницы сайта, а затем уже залить его в Публикацию / Историю Инстаграмма
    Ответ написан
    Комментировать
  • Какие устройства выбрать для тестирования?

    @Medovochka Автор вопроса
    Был такой ответ из другого источника:

    Если рассуждать об этой задаче, как о задачке на граничные значения, то логичным будет примерно следующее:
    - минимальное количество ОЗУ, на которой запустится игра в принципе (в задаче этой цифры нет, но логика подсказывает, что она есть)
    - максимальное количество памяти для low
    - минимальное количество памяти для middle
    - максимальное количество памяти для middle
    - минимальное количество памяти для high
    По желанию - докинуть ещё девайсов для середины (или другого значения в пределах диапазона) для каждого КЭ

    + добавить что все упирается в количество девайсов, которые мы можем взять (т.е. ресурсы) и частотность использования разных девайсов.
    И ещё про то, что помимо ОЗУ есть и другие параметры, которые тоже надо учитывать.
    Ответ написан
    Комментировать
  • При запуске flutter doctor выдаёт предупреждение. Как исправить?

    @Medovochka
    Прям в официальной документации есть ответ на ваш вопрос https://docs.flutter.dev/get-started/install/windo... . Просто пошагово прочитайте
    Ответ написан
    Комментировать
  • Можно ли нарушать safe area зоны в приложениях?

    @Medovochka Автор вопроса
    Нашла на просторах такую фразу, которая по сути отвечает на мой вопрос: "Помните, что это называется "Human Interface Guidelines", а не "Human Interface Rules". Guidelines - это предложение, которое поможет сделать ваше приложение удобным и последовательным."
    Ответ написан
    Комментировать
  • Как в virtual device manager изменить геолокацию?

    @Medovochka Автор вопроса
    Нашла решение: Да, не очень хорошее, но как есть - на ПК включить ВПН для нужной страны, и Андроид Студио автоматически подхватит IP-шку в приложениях
    Ответ написан
    Комментировать
  • На что опираться при выборе изучения RN и Flutter?

    @Medovochka
    Кстати, сейчас C# с его .NET Multi-platform App UI сильно топит ( на замену Xamarin), но это на Западе, а не у нас в СНГ

    Тоже самое и по Flutter - он на Западе топит и его продвигают, а в СНГ пока что React.Native топит, отсюда и вакансий в 2-3 раза больше. Опирайтесь на вакансии в первую очередь - это ваша ЗП и опыт, а параллельно можете хоть Kotlin и Swift изучать
    Ответ написан
    Комментировать
  • На кого ассайнить баг?

    @Medovochka Автор вопроса
    В разных источниках ответили по-разному, вдруг кому-то еще пригодится:

    • Поскольку причиной все еще может быть серверная часть, то различие между серверной частью и интерфейсом кажется относительным. Можно ассайнить на любого из, потом переассайнят в случае чего
    • Ассайнить на фронт-энд разработчика, так как ошибки 500 - это только для бэк-энд разработчика, остальные - для фронт-энд разработчика
    • Уточнить у ТимЛида, как правильно заведено. Возможно, в начале на Лида вещаются, а он сам распределяет на кого надо
    • Если что-то связано с кнопками чтобы кликались (а сама логика кнопки, редиректы и далее - это бэк-энд) / отображением чего-то в браузере - это к фронт-энд разработчику, а по логике под капотом - это уже к бэк-энд разработчику. В моем случае ассайнить все эти баги на бэк-энд разработчика

    Ответ написан
    3 комментария
  • Возможно ли использовать Selenium на Android?

    @Medovochka
    Для мобилок ведь есть Appium, Espresso, UiAutomator и Katalon из самых используемых
    Ответ написан
  • Как дождаться элемента?

    @Medovochka
    • Проверить, находится ли элемент в iframe или внутри другого контейнера. Если так, сначала переключись в нужный фрейм с помощью команды driver.switchTo().frame()
    • Использовать wait until и/или explicit wait
    Ответ написан
    Комментировать
  • Как остановить handler?

    @Medovochka
    Попробуйте так для файла:

    # В userAdd.py
    def handle_number_input(bot, message, table_name):
        number = message.text
        cursor = mydb.cursor()
        sql_query = f"INSERT INTO {table_name} (phone_number, is_try) VALUES (%s, %s)"
        values = (number, 1)
        cursor.execute(sql_query, values)
        mydb.commit()
        cursor.close()
        bot.send_message(message.chat.id, text41)
    
    def handle_table_selection(bot, message, table_name):
        # Отправляем сообщение с запросом ввода номера
        bot.send_message(message.chat.id, text40)
        # Устанавливаем состояние пользователя в ожидание ввода номера
        bot.register_next_step_handler(message, lambda msg: handle_number_input(bot, msg, table_name))
    
    # В userDelete.py
    def handle_number_input2(bot, message, table_name):
        number = message.text
        cursor = mydb.cursor()
        sql_query = f"DELETE FROM {table_name} WHERE phone_number = %s"
        values = (number,)
        cursor.execute(sql_query, values)
        mydb.commit()
        cursor.close()
        bot.send_message(message.chat.id, text45)
    
    def handle_table_selection2(bot, message, table_name):
        # Отправляем сообщение с запросом ввода номера
        bot.send_message(message.chat.id, text40)
        # Устанавливаем состояние пользователя в ожидание ввода номера
        bot.register_next_step_handler(message, lambda msg: handle_number_input2(bot, msg, table_name))


    И соотвественно так для start.py :

    # Всякий нужный код до этого момента
        elif message.text == text42:
            userAdd.handle_table_selection(bot, message, table_name)
        elif message.text == text43:
            userDelete.handle_table_selection2(bot, message, table_name)
    # Всякий нужный код после этого момента


    А вообще, вы скорее всего пользуетесь бездумно ChatGPT, который может выполнить что-то легкое, и то часто с ошибками, не говоря о чем-то более сложном
    Ответ написан
  • В чём проблема?

    @Medovochka
    Попробуйте так:

    if data[str(ctx.message.guild.id)]["Users"][str(ctx.author.id)]["Balance"] >= arg:
        if arg >= 2:
            with open('data.json', 'w') as file:
                data[str(ctx.message.guild.id)]['Users'][str(member.id)]['Balance'] += arg
                data[str(ctx.message.guild.id)]['Users'][str(ctx.author.id)]['Balance'] -= arg
                json.dump(data, file, indent=4)
                file.close()
    Ответ написан
    Комментировать
  • ReplyKeyboardRemove() - после удаления поднимается клавиатура (андройд)?

    @Medovochka
    Проблема, с которой вы сталкиваетесь, связана с поведением стандартной клавиатуры телефона, которая автоматически поднимается после удаления пользовательской клавиатуры в боте. В рамках бота вы не можете контролировать поведение стандартной клавиатуры телефона. Это поведение зависит от настроек конкретного устройства пользователя, а не от бота.

    Решением может быть привлечение внимания пользователя к тому, что после удаления пользовательской клавиатуры необходимо свернуть стандартную клавиатуру вручную.
    Ответ написан
    1 комментарий
  • Как сохранить фото от одного пользователя и отправить другому?

    @Medovochka
    Попробуй так:

    @dp.message_handler(content_types=['text', 'photo'])
    async def main(message: types.Message):
        if message.text == 'Актуальное фото':
            if message.from_user.id == 111111111:
                photo = message.photo[0].file_id
                await bot.send_photo(message.chat.id, photo, message.caption)
            else:
                await bot.send_message(message.chat.id, 'У вас нет разрешения на получение актуального фото.')
    Ответ написан
    Комментировать
  • Что не так в этом коде?

    @Medovochka
    Ошибка возникает из-за того, что атрибут avatar_url_as отсутствует у объекта Member.

    Попробуй так:

    import requests
    import io
    
    @client.command(aliases=['leaderboard', 'lb'])
    async def __leaderboard(ctx):
        img = Image.new('RGBA', (680, 745), '#FFD700')
        embed = discord.Embed(title='Топ 10 сервера')
        counter = 0
        x = 0
        for row in cursor.execute("SELECT user_id, lvl FROM users WHERE server_id = {} ORDER BY cash DESC LIMIT 10".format(ctx.guild.id)):
            counter += 1
            member = ctx.guild.get_member(row[0])
            url = str(member.avatar_url)
            response = requests.get(url, stream=True)
            response = Image.open(io.BytesIO(response.content))
            response = response.convert('RGBA')
            response = response.resize((68, 68), Image.ANTIALIAS)
    
            img.paste(response, (0, x))
    
            idraw = ImageDraw.Draw(img)
            name = f'# {counter} | {member.display_name}'
            undertext = ImageFont.truetype('arial.ttf', size=20)
    
            idraw.text((75, x+20), f'{name}', font=undertext)
            x += 68
    
        img.save("user_card.png")
    
        await ctx.send(file=discord.File('user_card.png'))
    Ответ написан
    Комментировать
  • Как упростить проверку наличия данных в словаре?

    @Medovochka
    Для упрощения проверки наличия данных в словаре вы можете использовать метод get() для словаря.

    fields = ['email', 'birthday', 'gender']
    
    for field in fields:
        value = data.get(field)
        print(value)


    Также можно использовать словарное включение (dictionary comprehension) для создания нового словаря, содержащего только существующие поля:

    fields = ['email', 'birthday', 'gender']
    existing_fields = {field: data.get(field) for field in fields if field in data}
    print(existing_fields)
    Ответ написан
    Комментировать
  • Как исправит эту ошибку кода на питоне?

    @Medovochka
    Для исправления этой ошибки можно добавить условие в функцию f, чтобы она останавливалась, когда n достигает значения 5000. Вот исправленный код:

    from math import factorial
    
    def f(n):
        if n >= 5000:
            return factorial(n)
        else:
            return 2 * f(n + 1) / (n + 1)
    
    print(f(7))


    Теперь функция f будет вызывать factorial(n), когда n >= 5000, и возвращать результат. В противном случае, она будет вызывать себя рекурсивно, увеличивая значение n на 1 на каждом шаге, пока не достигнет значения 5000.
    Ответ написан
    Комментировать
  • Как добавить обязательную подписку на канал для тг-бота?

    @Medovochka
    Попробуй этот код:

    spoiler
    import logging
    import os
    
    from dotenv import load_dotenv
    from telegram import Update
    from telegram.ext import CallbackContext, CommandHandler, Filters, MessageHandler, Updater
    
    from openai_helper import OpenAIHelper, default_max_tokens
    from telegram_bot import ChatGPTTelegramBot
    
    # Global variable to store subscribed user IDs
    subscribed_users = set()
    
    # Command handler for the /subscribe command
    def subscribe(update: Update, context: CallbackContext):
        user_id = update.message.from_user.id
        subscribed_users.add(user_id)
        update.message.reply_text('Вы успешно подписались на канал!')
    
    # Command handler for the /unsubscribe command
    def unsubscribe(update: Update, context: CallbackContext):
        user_id = update.message.from_user.id
        subscribed_users.discard(user_id)
        update.message.reply_text('Вы успешно отписались от канала!')
    
    # Message handler to check if the user is subscribed before processing messages
    def process_message(update: Update, context: CallbackContext):
        user_id = update.message.from_user.id
        if user_id in subscribed_users:
            # User is subscribed, process the message
            chat_gpt_bot.process_message(update, context)
        else:
            # User is not subscribed, send a reply asking to subscribe
            update.message.reply_text('Пожалуйста, подпишитесь на канал, чтобы воспользоваться ботом.')
    
    def main():
        # Read .env file
        load_dotenv()
    
        # Setup logging
        logging.basicConfig(
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            level=logging.INFO
        )
    
        # Check if the required environment variables are set
        required_values = ['TELEGRAM_BOT_TOKEN', 'OPENAI_API_KEY']
        missing_values = [value for value in required_values if os.environ.get(value) is None]
        if len(missing_values) > 0:
            logging.error(f'The following environment values are missing in your .env: {", ".join(missing_values)}')
            exit(1)
    
        # Setup configurations
        model = os.environ.get('OPENAI_MODEL', 'gpt-3.5-turbo')
        max_tokens_default = default_max_tokens(model=model)
        openai_config = {
            'api_key': os.environ['OPENAI_API_KEY'],
            'show_usage': os.environ.get('SHOW_USAGE', 'false').lower() == 'true',
            'stream': os.environ.get('STREAM', 'true').lower() == 'true',
            'proxy': os.environ.get('PROXY', None),
            'max_history_size': int(os.environ.get('MAX_HISTORY_SIZE', 15)),
            'max_conversation_age_minutes': int(os.environ.get('MAX_CONVERSATION_AGE_MINUTES', 180)),
            'assistant_prompt': os.environ.get('ASSISTANT_PROMPT', 'You are a helpful assistant.'),
            'max_tokens': int(os.environ.get('MAX_TOKENS', max_tokens_default)),
            'n_choices': int(os.environ.get('N_CHOICES', 1)),
            'temperature': float(os.environ.get('TEMPERATURE', 1.0)),
            'image_size': os.environ.get('IMAGE_SIZE', '512x512'),
            'model': model,
            'presence_penalty': float(os.environ.get('PRESENCE_PENALTY', 0.0)),
            'frequency_penalty': float(os.environ.get('FREQUENCY_PENALTY', 0.0)),
            'bot_language': os.environ.get('BOT_LANGUAGE', 'en'),
        }
    
        # log deprecation warning for old budget variable names
        # old variables are caught in the telegram_config definition for now
        # remove support for old budget names at some point in the future
        if os.environ.get('MONTHLY_USER_BUDGETS') is not None:
            logging.warning('The environment variable MONTHLY_USER_BUDGETS is deprecated. '
                            'Please use USER_BUDGETS with BUDGET_PERIOD instead.')
        if os.environ.get('MONTHLY_GUEST_BUDGET') is not None:
            logging.warning('The environment variable MONTHLY_GUEST_BUDGET is deprecated. '
                            'Please use GUEST_BUDGET with BUDGET_PERIOD instead.')
    
        telegram_config = {
            'token': os.environ['TELEGRAM_BOT_TOKEN'],
            'admin_user_ids': os.environ.get('ADMIN_USER_IDS', '-'),
            'allowed_user_ids': os.environ.get('ALLOWED_TELEGRAM_USER_IDS', '*'),
            'enable_quoting': os.environ.get('ENABLE_QUOTING', 'true').lower() == 'true',
            'enable_image_generation': os.environ.get('ENABLE_IMAGE_GENERATION', 'true').lower() == 'true',
            'enable_transcription': os.environ.get('ENABLE_TRANSCRIPTION', 'true').lower() == 'true',
            'budget_period': os.environ.get('BUDGET_PERIOD', 'monthly').lower(),
            'user_budgets': os.environ.get('USER_BUDGETS', os.environ.get('MONTHLY_USER_BUDGETS', '*')),
            'guest_budget': float(os.environ.get('GUEST_BUDGET', os.environ.get('MONTHLY_GUEST_BUDGET', '100.0'))),
            'stream': os.environ.get('STREAM', 'true').lower() == 'true',
            'proxy': os.environ.get('PROXY', None),
            'voice_reply_transcript': os.environ.get('VOICE_REPLY_WITH_TRANSCRIPT_ONLY', 'false').lower() == 'true',
            'voice_reply_prompts': os.environ.get('VOICE_REPLY_PROMPTS', '').split(';'),
            'ignore_group_transcriptions': os.environ.get('IGNORE_GROUP_TRANSCRIPTIONS', 'true').lower() == 'true',
            'group_trigger_keyword': os.environ.get('GROUP_TRIGGER_KEYWORD', ''),
            'token_price': float(os.environ.get('TOKEN_PRICE', 0.002)),
            'image_prices': [float(i) for i in os.environ.get('IMAGE_PRICES', "0.016,0.018,0.02").split(",")],
            'transcription_price': float(os.environ.get('TOKEN_PRICE', 0.006)),
            'bot_language': os.environ.get('BOT_LANGUAGE', 'en'),
        }
    
        # Setup and run ChatGPT and Telegram bot
        openai_helper = OpenAIHelper(config=openai_config)
        telegram_bot = ChatGPTTelegramBot(config=telegram_config, openai=openai_helper)
    
        # Create an Updater and pass it the bot's token
        updater = Updater(token=telegram_config['token'], use_context=True)
    
        # Get the dispatcher to register handlers
        dispatcher = updater.dispatcher
    
        # Register the command handlers
        dispatcher.add_handler(CommandHandler("subscribe", subscribe))
        dispatcher.add_handler(CommandHandler("unsubscribe", unsubscribe))
    
        # Register the message handler
        dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, process_message))
    
        # Start the bot
        updater.start_polling()
        updater.idle()
    
    
    if __name__ == '__main__':
        main()

    Ответ написан
    1 комментарий
  • Как сделать минимальную сумму пополнения 20 руб и округлить число?

    @Medovochka
    Попробуйте этот код:

    elif message.text == "Приобрести валюту":
        message = bot.send_message(message.chat.id, "Введите сумму в рублях: ")
        bot.register_next_step_handler(message, start_2)
    
    def start_2(message):
        rubles = int(message.text)
        gold = round(rubles / 0.65)
        bot.send_message(message.chat.id,
                         f' Сумма: {rubles} руб. \n Вы получите: {gold} золота \n\nВыберите удобный способ оплаты:')
    Ответ написан
    Комментировать
  • Вызывает ошибку callbackquery has no attribute text.Как быть?

    @Medovochka
    Попробуй этот код:

    @dp.callback_query_handler(text='un_card')
    async def start(callback_query):
        message = callback_query.message
        db = await register_method.reg(message)
    
        await bot.delete_message(chat_id=message.chat.id, message_id=message.message_id)
    
        db[message.from_user.id]['balance'] = float(db[message.from_user.id]['balance']) - float(db[message.from_user.id]['invest'])
    
        await codecs_method.write('users.json', db)
    
        await bot.send_message(chat_id=message.from_user.id,
                               text='Введите платежные данные, чтобы вывести средства!', parse_mode='markdown')
    
        if callback_query.data == '333':
            await bot.send_message(chat_id=message.from_user.id,
                                   text='Заявка')
        else:
            await bot.send_message(chat_id=message.from_user.id,
                                   text='Неправильный ввод карты!'
                                        '\nВывод средств разрешен только на ту карту, с которой баланс был пополнен!')
    Ответ написан
    Комментировать