Ответы пользователя по тегу Telegram
  • Почему не работает тг бот(Telebot, python)?

    shabelski89
    @shabelski89
    engineer
    кажется нужно заменить
    @bot.callback_query_handler(func=lambda callback: callback.data)

    на
    @bot.callback_query_handler(func=lambda callback: True)
    Ответ написан
  • Как выводить ответ на вопрос при нажатии InlineKeyboardButton в телеграмм боте на pyTelegramBotAPI?

    shabelski89
    @shabelski89
    engineer
    вот за 10 мин набросал тебе пример, изучай.
    Вместо словарей прикрутить запросы к БД, можно логику меню подправить, например добавить выход из викторины.

    from random import choice
    import telebot
    from telebot import types
    
    
    
    API_TOKEN = ""
    bot = telebot.TeleBot(API_TOKEN)
    
    
    guessing_game = {
        0: {'question': 'Кто убил Кеннеди?', 'choices': ['Lee Harvey Oswald', 'Pamela Denise Anderson', 'Joseph Robinette Biden'] , 'answer': 'Lee Harvey Oswald'},
        1: {'question': 'Кто президент России?', 'choices': ['Горбачёв', 'Путин', 'Медведев'] , 'answer': 'Путин'},
        2: {'question': 'Что?Где?Когда?', 'choices': ['1', '2', '3'] , 'answer': '2'}
    }
    answer_guessing_game = {
        0: 'Lee Harvey Oswald',
        1: 'Путин',
        2: '2',
    }
    
    @bot.message_handler(commands=["start"])
    def start_message(message):
        keyboardmain = types.InlineKeyboardMarkup()
        ask_button = types.InlineKeyboardButton(text="Угадывать!", callback_data="play")
        keyboardmain.add(ask_button)
        try:
            bot.send_message(message.chat.id, "Привет, я бот помощник по тестам!", reply_markup=keyboardmain)
        except telebot.apihelper.ApiException:
            print('Error')
    
    
    @bot.callback_query_handler(func=lambda call: True)
    def callback_inline(call):
        if call.data == "play":
            keyboard_main = types.InlineKeyboardMarkup()
            question_id = choice(list(guessing_game.keys()))
            question = guessing_game[question_id]['question']
            choices = guessing_game[question_id]['choices']
    
            choices_buttons = [types.InlineKeyboardButton(text=x, callback_data=f"{question_id}_answer_{x}") for x in choices]
            keyboard_main.add(*choices_buttons)
    
            bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id,
                                  text=question, reply_markup=keyboard_main)
    
        if "answer" in call.data:
            question_id, _, answer = call.data.split('_')
            right_answer = answer_guessing_game.get(int(question_id))
            keyboard = types.InlineKeyboardMarkup()
            if right_answer == answer:
                back_button = types.InlineKeyboardButton(text="back", callback_data="play")
                keyboard.add(back_button)
                bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id,
                                      text="Правильно!", reply_markup=keyboard)
            else:
                back_button = types.InlineKeyboardButton(text="back", callback_data="play")
                keyboard.add(back_button)
                bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id,
                                      text="Не правильно!", reply_markup=keyboard)
    
    
    
    if __name__ == '__main__':
        bot.infinity_polling()
    Ответ написан
    Комментировать
  • Как динамично создавать кнопки?

    shabelski89
    @shabelski89
    engineer
    Проще простого, вот мой ответ на аналогичный вопрос.
    Ответ написан
    Комментировать
  • Rest Api telegram BOT как отследить на какое сообщение ответил пользователь?

    shabelski89
    @shabelski89
    engineer
    Вы не указали на каком ЯП, но в общем случае смотрим АПИ
    у объекта message , если это был ответ на другой message будет и свой ИД и вложенный объект message, на который ответили.
    вот пример сообщения , запоминаем "message_id": 1165934,
    {
     "update_id": 933188596,
     "message": {
      "message_id": 1165934,
      "from": {
       "id": 534905,
       "is_bot": false,
       "first_name": "Aleksandr",
       "last_name": "Shabelsky",
       "username": "shabelsky",
       "language_code": "ru"
      },
      "chat": {
       "id": 534905,
       "first_name": "Aleksandr",
       "last_name": "Shabelsky",
       "username": "shabelsky",
       "type": "private"
      },
      "date": 1661801219,
      "text": "тест сообщения"
     }
    }


    а вот при ответе на него

    {
     "update_id": 933188598,
     "message": {
      "message_id": 1165936,
      "from": {
       "id": 534905,
       "is_bot": false,
       "first_name": "Aleksandr",
       "last_name": "Shabelsky",
       "username": "shabelsky",
       "language_code": "ru"
      },
      "chat": {
       "id": 534905,
       "first_name": "Aleksandr",
       "last_name": "Shabelsky",
       "username": "shabelsky",
       "type": "private"
      },
      "date": 1661801228,
      "reply_to_message": {
       "message_id": 1165934,
       "from": {
        "id": 534905,
        "is_bot": false,
        "first_name": "Aleksandr",
        "last_name": "Shabelsky",
        "username": "shabelsky",
        "language_code": "ru"
       },
       "chat": {
        "id": 534905,
        "first_name": "Aleksandr",
        "last_name": "Shabelsky",
        "username": "shabelsky",
        "type": "private"
       },
       "date": 1661801219,
       "text": "тест сообщения"
      },
      "text": "тест ответа на сообщение"
     }
    }

    как видно в блоке reply_to_message есть "message_id": 1165934 , ссылка на отвеченное сообщение
    Ответ написан
    4 комментария
  • Как отправить предложение из файла telebot?

    shabelski89
    @shabelski89
    engineer
    вот она имитация бота :)
    а серьезно, сначала книжку Лутца, как Вам уже написал Александр Нестеров
    import time
    from random import choice
    from threading import Thread
    
    
    version = [
        {'language': 'Навахо', 'phrase': 'Ayóó ánííníshí', 'pronunciation': 'Аийоо ианинииши'},
        {'language': 'Гавайский', 'phrase': 'Aloha wau iā ʻoe', 'pronunciation': 'Алоха ва уйа ой'},
        {'language': 'Бангладешский', 'phrase': 'আমিতোমাকেভালবাসি', 'pronunciation': 'Ами тумакэ палабаши'},
        {'language': 'Латинский', 'phrase': 'Te amo', 'pronunciation': 'Тэ амо'},
        ]
    
    
    def read_from_stdin():
        while True:
            input_phrase = input()
            if input_phrase.lower() == 'love':
                result = choice(version)
                print(result['language'])
                print(result['phrase'])
                print(result['pronunciation'])
            else:
                print(f'unknown command - {input_phrase}')
    
    
    def some_worker():
        while True:
            print("некая переписка")
            time.sleep(5)
    
    
    if __name__ == "__main__":
        reader_t = Thread(target=read_from_stdin).start()
        worker_t = Thread(target=some_worker).start()
    Ответ написан
    Комментировать
  • Проблемка с fetchall(). Можете помочь?

    shabelski89
    @shabelski89
    engineer
    Читаем учебник, а не пишем ботов. Что такое кортежи, списки, срезы.
    example = ('Valentine',)
    example[0]
    'Valentine'
    Ответ написан
    Комментировать
  • Как добавлять кнопки в клавиатуру в зависимости от данных из базы данных в Telebot?

    shabelski89
    @shabelski89
    engineer
    Предположим Вы знаете как из sqlite полчать данные, обычно при fetchall() получаем список кортежей, например такой: some_data_from_sqlite = [('one',), ('two',), ('ten',)] .
    а уж клавиатуру сделать проще простого:
    import telebot
    from telebot import types
    
    
    API_TOKEN = ""
    bot = telebot.TeleBot(API_TOKEN)
    
    
    @bot.message_handler(commands=['start'])
    def start(message):
        some_data_from_sqlite = [('one',), ('two',), ('ten',)]  # список кортежей из БД
        buttons_dict = {i: x[0] for i, x in enumerate(some_data_from_sqlite)}
        keyboard = types.InlineKeyboardMarkup()
        back_button = types.InlineKeyboardButton(text="Back", callback_data="MainMenu")
        button_list = [types.InlineKeyboardButton(text=x, callback_data=x) for x in buttons_dict.values()] # callback дата понадобится при обработке нажатий на кнопку, но это уже совсем другая история :)
        keyboard.add(*button_list, back_button)
        bot.send_message(chat_id=message.chat.id, text=message.text, reply_markup=keyboard)
    
    
    if __name__ == "__main__":
        try:
            bot.polling(none_stop=True)
        except Exception as e:
            print(e)
    Ответ написан
    5 комментариев
  • Почему бот не выполняет команду повторно?

    shabelski89
    @shabelski89
    engineer
    Код практически невозможно читать, куча копипастов даже из моих старых ответов :) ).

    На вашем текущем уровне понимания ЯП я бы предложил почистить код.
    выносим БД и все данные в отдельный модуль и наводим порядок.
    tanks_db.py

    import sqlite3
    from sqlite3 import Error
    from time import ctime
    
    
    def post_sql_query(sql_query, database='bazaa.db'):
        with sqlite3.connect(database) as connection:
            cursor = connection.cursor()
            try:
                cursor.execute(sql_query)
            except Error as E:
                print(E)
            result = cursor.fetchall()
            return result
    
    
    def register_user(user_id, username, first_name, last_name):
        user_check_query = f'SELECT * FROM USERS WHERE user_id = {user_id};'
        user_check_data = post_sql_query(user_check_query)
        if not user_check_data:
            insert_to_db_query = f'INSERT INTO USERS (user_id, username, first_name, last_name, reg_date) ' \
                                 f'VALUES ({user_id}, "{username}", "{first_name}", "{last_name}", "{ctime()}");'
            post_sql_query(insert_to_db_query)
    
    
    def user_exists(user_id):
        if get_user_name(user_id) is None:
            return False
        return True
    
    
    def get_user_name(user_id):
        user_check_query = f'SELECT username FROM USERS WHERE user_id = {user_id};'
        result = post_sql_query(user_check_query)
        if result is None:
            return None
        return result[0]
    
    
    
    users_tables = '''CREATE TABLE IF NOT EXISTS USERS 
                            (user_id INTEGER PRIMARY KEY NOT NULL,
                            username TEXT,
                            first_name TEXT,
                            last_name TEXT,
                            reg_date TEXT);'''
    
    post_sql_query(users_tables)
    
    tanks_tables = '''CREATE TABLE IF NOT EXISTS TANKS 
                            (name TEXT PRIMARY KEY, info TEXT, photo TEXT);'''
    
    post_sql_query(tanks_tables)
    tanks = [
        {'name': 'Т-26', 'info': '<======Т-26======>\n\nМасса (т) - 9.26\n\nПрочность - 270 ед.\n\nМощность двигателя (л.с.) - 130\n\nМаксимальная скорость (км/ч) - 36\n\nБронепробиваемость базовым снарядом (мм) - 37-51\n\nУрон базовым снарядом - 26-44\n\nСкорострельность орудия (выстр/мин) - 10.3', 'photo': r'C:\\Users\\User\\Desktop\\Bot_WotBlitz\\R09_T-26.png'},
        {'name': 'БТ-2', 'info': '<======БТ-2======>\n\nМасса (т) - 12.93\n\nПрочность - 380 ед.\n\nМощность двигателя (л.с.) - 350\n\nМаксимальная скорость (км/ч) - 44\n\nБронепробиваемость базовым снарядом (мм) - 37-51\n\nУрон базовым снарядом - 38-63\n\nСкорострельность орудия (выстр/мин) - 11.8', 'photo': r'C:\\Users\\User\\Desktop\\Bot_WotBlitz\\r08_bt-2_image_resized.png'},
        {'name': 'БТ-7', 'info': '<======БТ-7======>\n\nМасса (т) - 15.34\n\nПрочность - 470 ед.\n\nМощность двигателя (л.с.) - 375\n\nМаксимальная скорость (км/ч) - 45\n\nБронепробиваемость базовым снарядом (мм) - 48-64\n\nУрон базовым снарядом - 45-75\n\nСкорострельность орудия (выстр/мин) - 13.0', 'photo': r'C:\\Users\\User\\Desktop\\Bot_WotBlitz\\r03_bt-7_image_resized.png'},
        {'name': 'А-20', 'info': '<======А-20======>\n\nМасса (т) - 18.57\n\nПрочность - 520 ед.\n\nМощность двигателя (л.с.) - 400\n\nМаксимальная скорость (км/ч) - 45\n\nБронепробиваемость базовым снарядом (мм) - 71-97\n\nУрон базовым снарядом - 90-150\n\nСкорострельность орудия (выстр/мин) - 7.8', 'photo': r'C:\\Users\\User\\Desktop\\Bot_WotBlitz\\r12_a-20_image_resized.png'}
    ]
    
    for tank in tanks:
        name = tank['name']
        info = tank['info']
        photo = tank['photo']
        post_sql_query(f'INSERT OR IGNORE INTO TANKS (name, info, photo) VALUES("{name}","{info}","{photo}")')



    далее пишем основную логику, в целом там делов на 1 час, форматирование вывода и наполнение БД сделать.

    tanks_bot.py

    import os.path
    import telebot
    from telebot import types
    from tanks_bd import *
    
    
    API_TOKEN = ""
    bot = telebot.TeleBot(API_TOKEN)
    
    
    def get_photo(path):
        try:
            if os.path.exists(path):
                return open(path, 'rb')
        except Exception as E:
            print(E)
            return False
    
    
    def get_main_keyboard():
        keyboard_main = types.InlineKeyboardMarkup()
        tanks_menu = types.InlineKeyboardButton('Танки', callback_data="Tanks")
        profile_button = types.InlineKeyboardButton('Профиль', callback_data="Profile")
        keyboard_main.add(profile_button, tanks_menu)
        return keyboard_main
    
    
    @bot.message_handler(commands=['start'])
    def get_text_messages(message):
        username = message.from_user.first_name
        register_user(message.from_user.id, message.from_user.username, username, message.from_user.last_name)
        keyboard = get_main_keyboard()
        bot.send_message(message.chat.id, f'Добро пожаловать {username}', reply_markup=keyboard)
    
    
    @bot.callback_query_handler(func=lambda call: True)
    def callback_inline(call):
        if call.data == "MainMenu":
            keyboard = get_main_keyboard()
            username = call.message.chat.first_name
            bot.send_message(call.message.chat.id, f'Добро пожаловать {username}', reply_markup=keyboard)
    
        if call.data == "Profile":
            profile_query = f'SELECT * FROM USERS WHERE user_id = {call.message.chat.id};'
            profile = post_sql_query(profile_query)
            username, first_name, last_name = profile[0]
            keyboard = get_main_keyboard()
            bot.send_message(call.message.chat.id,
                             f'*username*\n{username}\n*first_name*\n{first_name}\n*last_name*\n{last_name}',
                             reply_markup=keyboard)
    
        if call.data == "Tanks":
            tanks_query = f'SELECT distinct(name) FROM TANKS;'
            tanks_result = post_sql_query(tanks_query)
            keyboard = types.InlineKeyboardMarkup()
            back_button = types.InlineKeyboardButton(text="Back", callback_data="MainMenu")
            button_list = [types.InlineKeyboardButton(text=elem[0], callback_data=elem[0]) for elem in tanks_result]
            keyboard.add(*button_list, back_button)
            bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id,
                                  text=call.message.text, reply_markup=keyboard)
    
        if call.data:
            check_data = f'SELECT name, info, photo FROM TANKS WHERE name = "{call.data}";'
            check = post_sql_query(check_data)
            if check:
                name, info, photo = check[0]
                bot.send_message(call.message.chat.id, f'*Name*\n{name}\n*Info*\n{info}')
                if get_photo(photo):
                    bot.send_photo(call.message.chat.id, get_photo(photo))
                keyboard = get_main_keyboard()
                username = call.message.chat.first_name
                bot.send_message(call.message.chat.id, f'Добро пожаловать {username}', reply_markup=keyboard)
    
    
    if __name__ == "__main__":
        try:
            bot.polling(none_stop=True)
        except Exception as e:
            print(e)


    622853c0baf07174276544.png
    Ответ написан
    Комментировать
  • Как "попросить" python код, при вводе команды " start" автоматически заносить в базу данных айди пользователя?

    shabelski89
    @shabelski89
    engineer
    То что Вы спрашиваете называется авто_инкремент ,
    но он в данном случае не очень нужен, так как user_id уникальный в телеграм, проще использовать в качестве ключа его - смотри пример кода тут. Нужно 1 раз создать таблицу create_tables и потом наполнять её функцией register_user.

    Если же надумаете добавить свой ид на основе автоинкремента, то просто изменить в коде как создаётся таблица и делает инсерт.
    Ответ написан
    Комментировать
  • Как и з телеграм подтягивать телефон?

    shabelski89
    @shabelski89
    engineer
    1 Можно ли сделать так, чтобы в БД подтягивалось имя?
    Да
    2 Можно ли сделать так чтобы в БД подтягивался телефон?
    Телефон можно получить только через запрос, либо человек нажмёт поделиться телефоном, либо нужно сделать кнопку поделиться телефоном
    3 Можно ли сделать так чтобы в БД подтягивался юзернейм?
    Да
    В телеге найти бота @ShowJsonBot и отправить ему сообщение, в ответ вы получит JSON с теми полями которые можно выцепить.
    Ответ написан
    Комментировать
  • Почему Telegram Bot неполностью форматирует текст?

    shabelski89
    @shabelski89
    engineer
    Sending large text messages

    Sometimes you must send messages that exceed 5000 characters. The Telegram API can not handle that many characters in one request, so we need to split the message in multiples. Here is how to do that using the API:

    from telebot import util
    large_text = open("large_text.txt", "rb").read()
    
    # Split the text each 3000 characters.
    # split_string returns a list with the splitted text.
    splitted_text = util.split_string(large_text, 3000)
    
    for text in splitted_text:
    	tb.send_message(chat_id, text)
    Ответ написан
    Комментировать
  • В чем заключается ошибка, Python Aiogram?

    shabelski89
    @shabelski89
    engineer
    В трейсе ошибки же написано :
    TypeError: a bytes-like object is required, not '_io.BytesIO'

    new_file.write(dowloaded_file_photo.read())
    или
    new_file.write(dowloaded_file_photo.getvalue())
    Ответ написан
    Комментировать
  • Как на питоне проверять статус платежа каждые 5 минут в telegram боте?

    shabelski89
    @shabelski89
    engineer
    Самое простое запустить функцию проверки в отдельном потоке. Примеры потоков тут.
    Ответ написан
    Комментировать
  • Почему не передается полностью значение переменной через API Telegram?

    shabelski89
    @shabelski89
    engineer
    Потому что пробелы заменить нужно на %20
    #!/bin/bash
    API_KEY="some_key"
    RES=$(echo "my time is $(date +%F)" | sed  "s/ /%20/g")
    echo $RES
    CHAT_ID=11111
    curl -s "https://api.telegram.org/bot$API_KEY/sendMessage?chat_id=$CHAT_ID&text="$RES"" >/dev/null
    Ответ написан
  • Я тут на быдлокодил, можно ли оптимизировать?

    shabelski89
    @shabelski89
    engineer
    Вот такое:
    if message.text in ['казино', 'Казино']:
    
    if message.text.lower() == "казино":


    или такое

    result = 'Выпало ' + str(a) + ', ты выиграл ' + str(bet) + ' мои поздравления!\nБанк ' + str(bank)
    result = f'Выпало {a}, ты выиграл {bet} - мои поздравления!\nБанк {bank}'


    ну и выше правильно написали, нечего тут "оптимизировать", кода пять строчек, логики тоже.
    Ответ написан
  • Как отправить сообщение Telegram боту(на python), после выполнения успешной команды ping?

    shabelski89
    @shabelski89
    engineer
    Для этой задачи не нужны библиотеки типа телебот.
    Нужно:
    1) токен
    2) python requests
    3) ваш код и логика
    4) отправить через http post сообщение
    Пример такого бота тут
    Ответ написан
    Комментировать
  • Как прикрепить фотографию к элементу списка в python?

    shabelski89
    @shabelski89
    engineer
    во-первых, не нужно называть переменные ключевыми словами ЯП (list )
    во-вторых, в данном случае лучше подходит структура данных - словарь
    from pprint import pprint
    cards = {'card_' + str(x): {'name': x, 'desc': x, 'photo': x} for x in range(1,22)}
    cards['card_21']['name'] = 'Мир'
    cards['card_21']['desc'] = 'Завершенность бла бла бла'
    cards['card_21']['photo'] = 'C:/Tools/tmp/card_21.png'
    pprint(cards)
    {'card_1': {'desc': 1, 'name': 1, 'photo': 1},
     'card_10': {'desc': 10, 'name': 10, 'photo': 10},
     'card_11': {'desc': 11, 'name': 11, 'photo': 11},
     'card_12': {'desc': 12, 'name': 12, 'photo': 12},
     'card_13': {'desc': 13, 'name': 13, 'photo': 13},
     'card_14': {'desc': 14, 'name': 14, 'photo': 14},
     'card_15': {'desc': 15, 'name': 15, 'photo': 15},
     'card_16': {'desc': 16, 'name': 16, 'photo': 16},
     'card_17': {'desc': 17, 'name': 17, 'photo': 17},
     'card_18': {'desc': 18, 'name': 18, 'photo': 18},
     'card_19': {'desc': 19, 'name': 19, 'photo': 19},
     'card_2': {'desc': 2, 'name': 2, 'photo': 2},
     'card_20': {'desc': 20, 'name': 20, 'photo': 20},
     'card_21': {'desc': 'Завершенность бла бла бла',
                 'name': 'Мир',
                 'photo': 'C:/Tools/tmp/card_21.png'},
     'card_3': {'desc': 3, 'name': 3, 'photo': 3},
     'card_4': {'desc': 4, 'name': 4, 'photo': 4},
     'card_5': {'desc': 5, 'name': 5, 'photo': 5},
     'card_6': {'desc': 6, 'name': 6, 'photo': 6},
     'card_7': {'desc': 7, 'name': 7, 'photo': 7},
     'card_8': {'desc': 8, 'name': 8, 'photo': 8},
     'card_9': {'desc': 9, 'name': 9, 'photo': 9}}

    как понятно из кода выше, в словарь добавляется ключ 'photo' и значение путь до файла.
    и дальше нужно передавать его через бота прочитав файл
    with open(cards['card_21']['photo'], "rb") as file:
        data = file.read()
    bot.send_photo(message.from_user.id, photo=data)

    но перед эти нужно написать функцию, которая будет принимать аргумент - ИД карты и подставлять его в open()
    Ответ написан
    Комментировать
  • Какую платформу для телеграм-бота выбрать?

    shabelski89
    @shabelski89
    engineer
    Вы можете написать этот код без телеграм бота ? Или хотя бы псевдокод?
    Ответ написан
  • Как сделать обратный таймер в телеграмм?

    shabelski89
    @shabelski89
    engineer
    Вот тут отвечал, а примере прямой и обратный отсчёт
    Ответ написан
    Комментировать