У меня естьсвоя тема, где я пишу софт и ботов на заказ по приятным ценам. Заходи, если что-то нужно! Приветствую вас. Что мы сделаем? Создадим телеграмм бота с функцией отложенных постов и возможностью добавлять кнопки для вашего канала. Начнем с того, зачем это нужно: дополнительный функционал телеграмм каналов можно получить исключительно используя его api, пользователям это не доступно. Для этого существуют различные боты, но вы не знаете их исходного кода, и не можете быть уверены, что ваш api ключ не сольют и канал не заспямят и т.п. Мы создадим бота, которому точно можно доверять. Процесс создания ниже. Исходники для ленивых можно получить в конце статьи. Для написания бота вместе со мной вам нужны будут: Знания python на уровне понимания функций, или осознание механизма работы telebot Немного времени Для использования готового кода: Для бесплатной работы: Понимание того, как использовать консоль в windows Немного времени и терпения (если не знакомы с Git и Heroku) Для платной работы: Аренда дедика 1. Установим Python Для работы нам понадобится Python версии 3.9+. Я буду пользоваться 3.9, так как 3.10 еще не очень стабильна и иногда вызывает проблемы с библиотеками. Переходим на сайт:https://www.python.org/downloads/release/python-399/ И скачиваем Python Скриншот Выбираем место для сохранения и открываем. При запуске меняйте настройки на ваш вкус. 2. Установим api для работы с Telegram в Python pip install PytelegramBotApi Не путайте С telebot, установится не та библиотека! Скриншот 1. Подготовка Я для работы используюPyCharm (Очевидно не реклама). Вы можете использовать даже встроенную в python IDLE, Wing, Atom, да даже блокнот для написания кода. Создадим 2 файла: main.py для основного кода и settings.py для настроек. Скриншот (зачем он вам?)) 2. Первые шаги 2.1. Создадим тестовый канал и бота. @ Botfather (без пробела) поможет нам в создании бота. Канал можно создать встроенными методами. Не забываем сделать бота админом! Скриншот. И еще 1. Что? Правильно: скриншот 2.2. Запишем нужные нам данные и проведем первый тест. В settings напишем: token = 'СЮДА ВАШ ТОКЕН' channel = '@test_lzt_posting_channel' Code token = 'СЮДА ВАШ ТОКЕН' channel = '@test_lzt_posting_channel' В main запишем import'ы нужных нам библиотек, и тестовый код. from telebot import TeleBot, types from settings import * bot = TeleBot(token=token) bot.send_message(channel, '123') Code from telebot import TeleBot, types from settings import * bot = TeleBot(token=token) bot.send_message(channel, '123') Если от имени канала пришло сообщение 123, все сделано правильно, и мы можем приступать к созданию бота! 3. Пишем код Для начала напишем код, который будет создавать отложенные сообщения без обработки запросов из telegram keyboard = types.InlineKeyboardMarkup() text = input('Текст для сообщения: ') for i in range(int(input('Сколько рядов необходимо сделать: '))): buttons = input().split(',') buttons = [j.split(';') for j in buttons] args = [types.InlineKeyboardButton(j[0].strip(), j[1].strip()) for j in buttons] keyboard.row(*args) bot.send_message(channel, text, reply_markup=keyboard) Code keyboard = types.InlineKeyboardMarkup() text = input('Текст для сообщения: ') for i in range(int(input('Сколько рядов необходимо сделать: '))): buttons = input().split(',') buttons = [j.split(';') for j in buttons] args = [types.InlineKeyboardButton(j[0].strip(), j[1].strip()) for j in buttons] keyboard.row(*args) bot.send_message(channel, text, reply_markup=keyboard) Данный обработчик принимает текст, количество рядов, и ряды из кнопок в формате Текст на кнопке; ссылка, Текст на другой кнопке; ссылка Количество кнопок в ряду может быть от 1 до максимального возможного значения в телеграмме. Посмотрим как сработал пример: Скриншоты Все кнопки рабочие и ведут на нужные нам сайты! Добавим отложенный постинг: В импорты внесем datetime и time и работу с потоками threading from time import sleep from datetime import datetime from threading import Thread Code from time import sleep from datetime import datetime from threading import Thread А также добавим 2 переменных в начало кода: bot = TeleBot(token=token) posts = {} action = '' new_post = [] Code bot = TeleBot(token=token) posts = {} action = '' new_post = [] Настроим задержку, lдобавим метод отправки сообщений с задержкой: def sleep_poster(date_post, message): while True: if date_post < datetime.now(): print('Отправили сообщение!') bot.send_message(message[0], message[1], reply_markup=message[2]) return else: sleep(60) Code def sleep_poster(date_post, message): while True: if date_post < datetime.now(): print('Отправили сообщение!') bot.send_message(message[0], message[1], reply_markup=message[2]) return else: sleep(60) Заменим send message на новый код обращения к потоку поста с задержкой date = input('Дата выхода поста: ').split('-') date = [int(i) for i in date] date = datetime(year=date[0], month=date[1], day=date[2], hour=date[3], minute=date[4]) identity = datetime.now().microsecond posts[identity] = Thread(target=sleep_poster, args=[date, [channel, text, keyboard]]) posts[identity].run() Code date = input('Дата выхода поста: ').split('-') date = [int(i) for i in date] date = datetime(year=date[0], month=date[1], day=date[2], hour=date[3], minute=date[4]) identity = datetime.now().microsecond posts[identity] = Thread(target=sleep_poster, args=[date, [channel, text, keyboard]]) posts[identity].run() Проверим работу: 4. Пишем код часть 2. Подключение к телеграмм. Обработчик запросов в консоли это хорошо, но мы сделаем обработку в телеграмм. Добавим переменную администратора в файл settings adm_id = 615711092 Как узнать свой id? Перейдите в любой getid бот и просто напишите /start. Добавим обработчки ответов: /start: @bot.message_handler(commands=['start']) def start_command(message): user = message.chat.id if user == adm_id: rp = types.ReplyKeyboardMarkup(True) rp.row('Новый пост') bot.send_message(user, 'Привет, используй кнопки для работы с ботом.', reply_markup=rp) Code @bot.message_handler(commands=['start']) def start_command(message): user = message.chat.id if user == adm_id: rp = types.ReplyKeyboardMarkup(True) rp.row('Новый пост') bot.send_message(user, 'Привет, используй кнопки для работы с ботом.', reply_markup=rp) Обработчик команды о новом посте: @bot.message_handler(content_types=['text']) def text(message): global action, new_post user = message.chat.id if message.text == 'Новый пост': if user == adm_id: bot.send_message(user, 'Введите текст для сообщения. Используй для *жирного текста*, _курсива_') action = 'text' Code @bot.message_handler(content_types=['text']) def text(message): global action, new_post user = message.chat.id if message.text == 'Новый пост': if user == adm_id: bot.send_message(user, 'Введите текст для сообщения. Используй для *жирного текста*, _курсива_') action = 'text' Обработчики следующих стадий бота (в том же разделе что и код выше): elif action == 'text': new_post.append(message.text) action = 'buttons' bot.send_message(user, 'Теперь введите кнопки по шаблону "Имя кнопки; ссылка.ru, ' 'Имя второй кнопки; example.com" (без ковычек). Ряды разделяются Enter`ом.') elif action == 'buttons': keyboard = types.InlineKeyboardMarkup() for i in message.text.split('\n'): buttons = i.split(',') buttons = [j.split(';') for j in buttons] args = [types.InlineKeyboardButton(j[0].strip(), j[1].strip()) for j in buttons] keyboard.row(*args) bot.send_message(user, 'Кнопки будут выглядеть вот так:', reply_markup=keyboard) bot.send_message(user, 'Теперь введите дату в виде часы - минуты - день - месяц (необязательно) - ' 'год (необязательно), или введите now, чтобы выпустить сейчас:') new_post.append(keyboard) action = 'data' elif action == 'data': t = message.text.split('-') if len(t) == 5: t = [int(i) for i in t] date = datetime(minute=t[1], hour=t[0], day=t[2], month=t[3], year=t[4]) elif len(t) == 4: t = [int(i) for i in t] date = datetime(minute=t[1], hour=t[0], day=t[2], month=t[3], year=datetime.now().year) elif len(t) == 3: t = [int(i) for i in t] date = datetime(minute=t[1], hour=t[0], day=t[2], month=datetime.now().month, year=datetime.now().year) else: date = 'Now!' new_post.append(date) inkb = types.InlineKeyboardMarkup() inkb.row(types.InlineKeyboardButton('Создать', callback_data='create')) inkb.row(types.InlineKeyboardButton('Нет!', callback_data='delete')) bot.send_message(user, 'Подтвердите создание отложенной записи:\n\n' f'Текст: {new_post[0]}\n' f'Дата: {str(new_post[2])}', reply_markup=inkb, parse_mode='Markdown') Code elif action == 'text': new_post.append(message.text) action = 'buttons' bot.send_message(user, 'Теперь введите кнопки по шаблону "Имя кнопки; ссылка.ru, ' 'Имя второй кнопки; example.com" (без ковычек). Ряды разделяются Enter`ом.') elif action == 'buttons': keyboard = types.InlineKeyboardMarkup() for i in message.text.split('\n'): buttons = i.split(',') buttons = [j.split(';') for j in buttons] args = [types.InlineKeyboardButton(j[0].strip(), j[1].strip()) for j in buttons] keyboard.row(*args) bot.send_message(user, 'Кнопки будут выглядеть вот так:', reply_markup=keyboard) bot.send_message(user, 'Теперь введите дату в виде часы - минуты - день - месяц (необязательно) - ' 'год (необязательно), или введите now, чтобы выпустить сейчас:') new_post.append(keyboard) action = 'data' elif action == 'data': t = message.text.split('-') if len(t) == 5: t = [int(i) for i in t] date = datetime(minute=t[1], hour=t[0], day=t[2], month=t[3], year=t[4]) elif len(t) == 4: t = [int(i) for i in t] date = datetime(minute=t[1], hour=t[0], day=t[2], month=t[3], year=datetime.now().year) elif len(t) == 3: t = [int(i) for i in t] date = datetime(minute=t[1], hour=t[0], day=t[2], month=datetime.now().month, year=datetime.now().year) else: date = 'Now!' new_post.append(date) inkb = types.InlineKeyboardMarkup() inkb.row(types.InlineKeyboardButton('Создать', callback_data='create')) inkb.row(types.InlineKeyboardButton('Нет!', callback_data='delete')) bot.send_message(user, 'Подтвердите создание отложенной записи:\n\n' f'Текст: {new_post[0]}\n' f'Дата: {str(new_post[2])}', reply_markup=inkb, parse_mode='Markdown') После этого добавим обработчики согласия и отказа к посту [CODE]@bot.callback_query_handler(func=lambda call: True) def answer(call): global new_post, action us = call.message.chat.id if call.data == 'create': identity = datetime.now().microsecond if type(new_post[2]) == str: bot.send_message(channel, new_post[0], reply_markup=new_post[1], parse_mode='Markdown') return inkb = types.InlineKeyboardMarkup() bot.send_message(us, 'Сообщение создано!', reply_markup=inkb) posts[identity] = Thread(target=sleep_poster, args=[new_post[2], [channel, new_post[0], new_post[1]]]) posts[identity].run() elif call.data == 'delete': new_post = [] action = '' bot.send_message(us, 'Создание отменено.')[/CODE]Ну вот и все. Бот работает, сообщения приходят: Ну и самое главное, напишем обработчик новых сообщений телеграмм бота [CODE]def main(): while True: try: bot.polling() except Exception as e: print(e) Thr = Thread(target=main) Thr.start() [/CODE] На этом код заканчивается. Ссылка на готовый код: Мини хайд от распространения без моего согласия Теперь приступим к установке на сервер или на heroku. 1. Устанавливаем бота на дедик (простой, но платный способ) Для установки на дедик перенесем файлы main и settings в любую папку на дедике. Также установим сюда python и PyTelegramBotApi (См. Начало создания, второй гайд писать не буду) Откроем консоль (Win + R --> cmd) И напишем в ней cd *путь до папки, в которой лежит скрипт* Далее просто напишем python main.py. Готово, скрипт стоит на дедике, теперь его нужно будет просто продлять когда нужно. 2. Установка бота на heroku (бесплатный, но чуть-чуть сложнее) Для установки на heroku нам понадобятся git. Скачайте его и ставьте настройки по желанию. Также нам нужен будет heroku cli. Установка также проблем не вызовет. Теперь зарегистрируем 2 аккаунта на heroku. Почему 2? heroku предоставляет 400 часов в месяц для ботов в бесплатном тарифе, и этого хватит ~на 25 дней. Если вы хотите непрерывной работы бота, когда в одном месте будут подходить часы, надо его выключить и включить второй. Скриншот Подтвердим почту и идем к следующему шагу. Создадим 2 файла в нашей директории: Procfile (без расширения) и requirements.txt. Для создания requirements можно использовать команду pip freeze > requirements.txt В Procfile внесем такую строку: [CODE]worker: python main.py $PORT[/CODE]Откроем консоль или terminal pycharm в папке со скриптом, и пишем команду git init Далее heroku login и нажимаем любую клавину (кроме q) У вас откроется окно входа, где нужно подтвердить вход Далее, git add . Далее, введем git commit -am "Запуск бота!" Вместо запуск бота может быть любой текст, он ни на что не влияет. Теперь создадим приложение на хероку. heroku create Теперь внесем все файлы на сервер heroku git push heroku master Это займет немного времени. Показатель что все прошло успешно: Spoiler Теперь перейдем на heroku чтобы запустить бота: Spoiler То же самое нужно повторить со вторым аккаунтом, но запускать его там не надо! Итого, мы написали бота, который может присылать сообщения с задержкой, кнопками, обрабатывать Markdown текст, но безусловно, бота еще можно дорабатывать и дорабатывать. Если эта статья вам зайдет, безусловно ждите продолжение. У меня есть своя тема, где я пишу софт и ботов на заказ по приятным ценам. Заходи, если что-то нужно!
ЖораПортималь, Не думаю, что появятся конкуренты от этой темы, конкуренты сами обучались, а те кто просто copy - paste - неконкурентно способны
Kranz, да я рофлю же, ну возможно эта статья заинтересует человека на изучение яп, вот и конкурент получится)
hex, Код сойдет, но чет в участках кода нет отступов, ладно, почему ты не показываешь как использовать виртуальное окружение питона, да, в пайчарме оно автоматом ставится, а кто будет сам писать в каком-нибудь саблайме, поэтому лучше покажи как установить его через cmd
Kranz, соблюдаю, соблюдаю. Единственная ошибка - остутствие telebot в requirements, которого там и быть не должно