• B правой части каждого сообщения есть стрелки и . Не стесняйтесь оценивать ответы. Чтобы автору вопроса закрыть свой тикет, надо выбрать лучший ответ. Просто нажмите значок в правой части сообщения.

Пишу телеграм бота на Python

TPOCTO4KA

New member
12.12.2023
1
0
BIT
11
Я в программировании полный ноль, но появилась задача которую нужно решить. Создать телеграм бота, который после нажатия кнопки /start проверял у меня подписку на телеграм канал. Если подписки нет, выводил информацию о том что нужно подписаться на канал и предлагал бы заново нажать на кнопку /start. Если подписка появилась, или она была, выводилось приветсвенное сообщение и на выбор две кнопки "Скачать файл" "Написать админу"
Весь код выглядит у меня так
Python:
import telebot
from telebot import types
import config as cfg
# в сonfig положил массив с инфой по каналу на котором нужно проверить подписку
# и константу с сообщенем
#CHANNEL = [
#    ['Канал 1', '-00000000', 'https://t.me']
#]
#NOT_SUB_MESSAGE = "Подпишитесь на канал чтобы получить руководство"

bot = telebot.TeleBot('13131')

def get_keyboard():
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    keyboard.add(types.KeyboardButton("Получить гайд"))
    keyboard.add(types.KeyboardButton("Связаться с экспертом"))
    keyboard.add(types.KeyboardButton("Подписаться на канал"))


def check_sub(channels, user_id):
    for channel in channels:
        chat_member = bot.get_chat_member(chat_id=channel[1], user_id=user_id)

        if chat_member.status == 'left':
            return False
    return True


@bot.message_handler(commands=['start'])
def start_message(message):
    user_id = message.from_user.id
    subscribed = check_sub(cfg.CHANNEL, user_id)

    if not subscribed:
        bot.send_message(message.from_user.id, cfg.NOT_SUB_MESSAGE, reply_markup=get_keyboard())


@bot.message_handler(func=lambda message: True)
def on_click(message):
    user_id = message.from_user.id
    subscribed = check_sub(cfg.CHANNEL, user_id)

    if message.text == "Подписаться на канал":
        if not subscribed:
            bot.send_message(message.chat.id, 'Подписывайтесь на наш канал: https://t.me')
            bot.send_message(message.chat.id, 'Для начала снова воспользуйтесь командой /start')
        else:
            bot.send_message(message.chat.id, 'Вы уже подписаны на канал.')

    elif not subscribed:
        bot.send_message(message.chat.id, 'Для получения подарка подпишитесь на телеграмм канал')
    elif message.text == "Получить гайд":
        bot.send_document(message.chat.id, open(r'file.pdf', 'rb'))
    elif message.text == "Связаться с экспертом":
        bot.send_message(message.chat.id, "t.me/link", parse_mode='html')

    bot.send_message(message.chat.id, 'Выберите действие:', reply_markup=get_keyboard())

bot.infinity_polling()
После проверки кода на подписание бот завис и не работает. Не знаю в чем может быть проблема. может где то в логике ошибка, или я не правильно выход из условия прописал в случае если подписка на канал есть
 
Для того чтобы бот брал данные из конфига, нужна библиотека asyncio, но telebot плохо с ней работает, т.к он не асинхронный, пишите лучше на airogram.
Там есть возможность использовать async.
В вашем случае эти функции будут выглядить вот так


Python:
async def check_sub_channels(channels, user_id):
    for channel in channels:
        chat_member = await bot.get_chat_member(chat_id=channel[1], user_id=user_id)
        if chat_member['status'] == 'left':
            return False
        return True
       

@bot.message_handler(commands=['start'])
async def start_message(message):
    if await check_sub_channels(cfg.CHANNELS, message.from_user.id) == True:
        await bot.send_message(message.from_user.id, "Приветик!")
 
Вот ваш main.py файл:
Python:
from aiogram import Bot, Dispatcher, executor, types
import markups as nav
import config as cfg

bot = Bot(token='YOUR_TOKEN')
dp = Dispatcher(bot)

async def get_keyboard():
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    keyboard.add(types.KeyboardButton("Получить гайд"))
    keyboard.add(types.KeyboardButton("Связаться с экспертом"))
    keyboard.add(types.KeyboardButton("Подписаться на канал"))


async def check_sub_channels(channels, user_id):
    for channel in channels:
        chat_member = await bot.get_chat_member(chat_id=channel[1], user_id=user_id)
        if chat_member['status'] == 'left':
            return False
        return True
        

@dp.message_handler(commands=['start'])
async def start_message(message):
    if await check_sub_channels(cfg.CHANNEL, message.from_user.id) == True:
        await bot.send_message(message.from_user.id, "Приветик!")


if __name__ == '__main__':
    executor.start_polling(dp, skip_updates=True)

И config.py
Python:
CHANNEL = ['Канал 1', '-1001049181524', 'https://t.me/codeby_sec']
NOT_SUB_MESSAGE = ["Подпишитесь на канал чтобы получить руководство"]

Нужно будет установить библиотеки aiogram и markup
pip install aiogram==2.23.1 pip install markup
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!