• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Изучаем python ,часть 3

network work

HDD-drive
Пользователь
Регистрация
11.07.2024
Сообщения
47
Реакции
5
Гарант сделки
3
Автор network work
Источник https://xss.pro


Всем доброго дня друзья , в этой статье я напишу про создание ботов в тг , начнем с простого закончим более трудным .

Начнем с простого , почему именно python ? Какие возможности этого языка ?

Все просто - телеграмм боты можно писать на таких языках как JS ,php,go(golang) и другие .Но почему именно python ,питон отличается простотой и читаемостью кода , множество разных библиотек имеется ,а так же нельзя забывать про хорошую документацию .python сам по себе простой язык но как не странно полезный , если говорить касательно тг то python дает возможность быстро написать и протестировать бота без лишнего геморроя .



Практическая часть
Давайте начнем с простого телеграмм бота который при запуске будет показывать актуальный курс крипто валюту , пусть будет биток ,эфир и лайт коин. Начнем!!!
Python:
import logging
import requests
from aiogram import Bot, Dispatcher, types
from aiogram.types import ParseMode
from aiogram.utils import executor


api_bota = '6672409243:AAHfoFHqaFGpOpkbjHAgGRPALz_ZqxTZmng'

api_saita = 'https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,ethereum,litecoin&vs_currencies=usd'

logging.basicConfig(level=logging.INFO)

bot = Bot(token=api_bota)
dp = Dispatcher(bot)

async def get_crypto_price() -> str:
    response = requests.get(api_saita)
    data = response.json()

    price = []
    for crypto in data:
        price.append(f"{crypto.capitalize()}: ${data[crypto]['usd']:.2f}")

    return "\n".join(price)

@dp.message_handler(commands=['start'])
async def send_welcome(message: types.Message):
    crypto_price = await get_crypto_price()
    response_message = f"Здравствуйте ,Курсы криптовалют на данный момент \n{crypto_price}"
    await message.reply(response_message, parse_mode=ParseMode.MARKDOWN)

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

Давайте разберем код

Python:
import logging
- импортируем модуль который отвечает за логи .Данный модуль дает возможность отслеживать работу бота ( что большой плюс для мониторинга )

Python:
import requests
- импортируем модуль который отвечает за выполнение http запросов ( она нам нужна будет для получение самих данных о курсах криптовалюты )

Python:
from aiogram import Bot, Dispatcher, types
- импортируем основные классы aiogram , давай разберем каждый .
Bot - класс который отвечает за взаимодействия с телеграммом
Dispatcher - класс отвечает за обратботкой и управлением входящих сообщений
types - модуль который может содержать различные типы данных

Python:
from aiogram.types import ParseMode
- строчка импортирует "ParseMode" которая нужна для указания стиля текста при отправке сообщений юзеру

Python:
from aiogram.utils import executor
- в данном случаи мы импортируем "executor" , который нужен для запуска бота и принципе для обработки входящих сообщений

Python:
api_bota = '   '
- сюда вводим апи нашего бота
Кто не знает как получить апи бота то
1. находим бота BotFather
2.прописываем /newbot для создание нового бота (затем следуйте инструкции )

Python:
api_saita = 'https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,ethereum,litecoin&vs_currencies=usd'
- api_saita хранит url которая в свою очередь отвечает за получение актуальных цен на нашу крипту .

Python:
logging.basicConfig(level=logging.INFO)
- строчка настраивает можно сказать базовую конфигурацию для мониторинга бота .Для этого мы и прописали "import logging"

Python:
bot = Bot(token=api_bota)
- строчка можно сказать создает экземпляр "Bot" , используя токен нашего бота .Зачем же это строчка нужна ? Все просто , она дает возможность для взаимодействия с telegram api

Python:
dp = Dispatcher(bot)
- строчка создает экземпляр "Dispatcher" который в свою очередь отвечает за управлением и обработкой сообщений.

Python:
async def get_crypto_price() -> str:
- строчка определяет асинхронную функцию "get_crypto_price" которая в свою очередь возвращает строчку с ценами на крипту

Python:
 response = requests.get(api_saita)
- строчка отвечает за выполнение http запроса к API ( для получение цен на криптовалюты)

Python:
    data = response.json()
- строчка преобразует ответ api (в формате json) в python словарь. Зачем же спросите вы ? Конвертация json ответа в python словарь дает возможность удобнее и эффективнее работать с данными от api. json формат - это текстовый формат , которой не предназначен для работы в коде .Что нельзя сказать о python словаре , который позволяет легко извлекать и управлять данными

Python:
   price = []
- строчка создает пустой список который будет служить для хранение строк с ценами крипты

Python:
   for crypto in data:
- можно сказать перебирает каждую крипту в полученных данных

Python:
       price.append(f"{crypto.capitalize()}: ${data[crypto]['usd']:.2f}")
-строчка настраивает можно сказать строку с названием крипты и ее ценной , а так же добавляет ее в выше созданный нами список .Мы использовали метод capitalize() для конвертации первой буквы в верхний регистр , а так же строчка форматирует цену с двумя знаками после запятой

Python:
   return "\n".join(price)
- строчка преобразует список строк ("price") в одну строку , а так же она разделяет все элементы новой строкой

Python:
@dp.message_handler(commands=['start'])
- если простыми словами то строчка отвечает за обработку сообщения "/start" . А значит бот будет работать при получение команды "/start" от юзера

Python:
async def send_welcome(message: types.Message):
- определят функцию "send_welcome" которая принимает сообщение "message"

Python:
   crypto_price = await get_crypto_price()
- строчка вызывает асинхронную функцию "get_crypto_price" которая в свою очередь отвечает за получения актуальных цен на крипту

Python:
    response_message = f"Здравствуйте ,Курсы криптовалют на данный момент \n{crypto_price}"
- строчка отвечает за форматирование строки приветствия с актуальными ценами на крипту

Python:
 await message.reply(response_message, parse_mode=ParseMode.MARKDOWN)
- отправляет сообщение юзеру ("response_message") + использует формат Markdown

Python:
if __name__ == '__main__':
- строчка проверяет выполняется ли скрипт напрямую ( а не импортируется как модуль )

Python:
    executor.start_polling(dp, skip_updates=True)
- строчка можно сказать запускает цикл обработки входящих сообщений и событий . А так же устанавливает "skip_updates=True", чтобы игнорировать старые сообщения

Первый скрипт был для отслеживания актуальной цены на крипту , скрипт простенький .Давайте сейчас разберем более полезный и сложный код , а точнее напишем инфо бота + добавим базовую админ панель ( рассылка + статистика )

Python:
import logging
from aiogram import Bot, Dispatcher, types
from aiogram.types import ParseMode
from aiogram.utils import executor

API_TOKEN = ''
ADMIN_ID = 12345789

logging.basicConfig(level=logging.INFO)

bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)

user_data = {
    "user": 0,
    "user_adm": set()
}

@dp.message_handler(commands=['start'])
async def send_welcome(message: types.Message):
    user_id = message.from_user.id
    user_data['user'] += 1
    user_data['user_adm'].add(user_id)
   
    response_message = (
        "Здравствуйте! Я информационный бот , тут может быть ваш текст \n\n"
        "Используйте команды:\n"
        "/info - информация о боте\n"
    )
    await message.reply(response_message, parse_mode=ParseMode.MARKDOWN)

@dp.message_handler(commands=['info'])
async def info(message: types.Message):
    response_message = (
        "Этот бот может содержать ваш текст , для дальнейших идей \n\n"
        "Команды:\n"
        "/start - запустить бота\n"
        "/info - информация о боте\n"
    )
    await message.reply(response_message, parse_mode=ParseMode.MARKDOWN)

@dp.message_handler(commands=['admin'])
async def admin_panel(message: types.Message):
    if message.from_user.id != ADMIN_ID:
        await message.reply("Вы не имеете доступа к админ-панели.")
        return
   
    response_message = (
        "Админ-панель\n\n"
        "/rasilka <message> - отправить рассылку всем пользователям\n"
        "/stata - статистика пользователей"
    )
    await message.reply(response_message, parse_mode=ParseMode.MARKDOWN)

@dp.message_handler(commands=['rasilka'])
async def rasilka(message: types.Message):
    if message.from_user.id != ADMIN_ID:
        await message.reply("Вы не имеете доступа к админ-панели.")
        return

    text = message.get_args()
    if not text:
        await message.reply("Пожалуйста, укажите сообщение для рассылки.")
        return
   
    sent = 0
    failed = 0
    for user_id in user_data['user_adm']:
        try:
            await bot.send_message(user_id, text, parse_mode=ParseMode.MARKDOWN)
            sent += 1
        except Exception as e:
            logging.error(f"Не удалось отправить сообщение пользователю {user_id}: {e}")
            failed += 1

    await message.reply(f"Рассылка завершена.\nОтправлено: {sent}\nНе удалось отправить: {failed}")

@dp.message_handler(commands=['stata'])
async def stata(message: types.Message):
    if message.from_user.id != ADMIN_ID:
        await message.reply("Вы не имеете доступа к админ-панели.")
        return

    response_message = (
        f"Общее количество пользователей: {user_data['user']}\n"
        f"Пользователи с админкой: {len(user_data['user_adm'])}"
    )
    await message.reply(response_message, parse_mode=ParseMode.MARKDOWN)

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

Давайте разберем выше написанный код

Python:
import logging
- импортируем модуль для логирование и мониторинга

Python:
from aiogram import Bot, Dispatcher, types
- импортируем базовые компоненты библиотеки "aiogram" .

Python:
from aiogram.types import ParseMode
- импортируем "ParseMode" которая предназначена для указания формата сообщений

Python:
from aiogram.utils import executor
- строчка импортирует "executor" ,который предназначен для помощи запуска бота и управление процессом можно сказать

Python:
API_TOKEN = ''
- сюда вводим токен вашего бота (как его получить написал вверху)

Python:
ADMIN_ID = 12345789
- заменяем 123456789 на id юзера которого хотите сделать админом .id можно узнать тут https://t.me/getmyid_bot ( не реклама)

Python:
logging.basicConfig(level=logging.INFO)
- в этой строчке мы настроили базовые параметры логирование

Python:
bot = Bot(token=API_TOKEN)
- строчка создает обьек бота , используя токен (указанный выше)

Python:
dp = Dispatcher(bot)
- строчка отвечает за создание объекта диспетчера ,который в свою очередь управляет обработкой сообщений и т.п

Python:
user_data = {
    "user": 0,
    "user_adm": set()
}
- создаем словарь для хранения информации о пользователях ("user_data") , "user" хранит общее кол-во юзеров .А "user_adm" хранит id юзеров которые будут иметь доступ к админ панели

Python:
@dp.message_handler(commands=['start'])
- строчка обрабатывает команды ( в данном случаи команду /start

Python:
async def send_welcome(message: types.Message):
- асинхронная функция которая отвечает за обработки команды "/start"

Python:
   user_id = message.from_user.id
- строчка получает id пользователя (который отправил сообщение )

Python:
  user_data['user'] += 1
- строчка увеличивает число общих юзеров

Python:
 user_data['user_adm'].add(user_id)
- добавляет id пользователя в админ панель

Python:
  response_message = (
        "Здравствуйте! Я информационный бот , тут может быть ваш текст \n\n"
        "Используйте команды:\n"
        "/info - информация о боте\n"
    )
- создаем сообщение для пользователя ( в данном случаи мы написали приветствие и список активных команд)

Python:
    await message.reply(response_message, parse_mode=ParseMode.MARKDOWN)
- строчка отправляет ответ пользователю ("response_message")

Python:
@dp.message_handler(commands=['info'])
- строчка создана для обработки команды "/info"

Python:
async def info(message: types.Message):
- Асинхронная функция для обработки команды "/info"

Python:
  response_message = (
        "Этот бот может содержать ваш текст , для дальнейших идей \n\n"
        "Команды:\n"
        "/start - запустить бота\n"
        "/info - информация о боте\n"
    )
- формирует сообщение с указанной нами информацией о боте

Python:
  await message.reply(response_message, parse_mode=ParseMode.MARKDOWN)
- отправляет выше написанное нами сообщение пользователю

Python:
@dp.message_handler(commands=['admin'])
- строчка обрабатывает команду "/admin"

Python:
async def admin_panel(message: types.Message):
- Асинхронная функция для обработки команды "/admin"

Python:
    if message.from_user.id != ADMIN_ID:
- строчка отвечает за проверку пользователя на наличии доступа к админ панели

Python:
await message.reply("Вы не имеете доступа к админ-панели.")
        return
- если не имеет пользователь доступ к админ панели то бот показывает выше написанное сообщение

Python:
    response_message = (
        "Админ-панель\n\n"
        "/rasilka <message> - отправить рассылку всем пользователям\n"
        "/stata - статистика пользователей"
    )
- строчка формирует выше написанное сообщение (данный текст для юзеров у которых есть доступ к админ панели)

Python:
   await message.reply(response_message, parse_mode=ParseMode.MARKDOWN)
- строчка отправляет выше написанное сообщение юзерам у которых есть доступ к админ панели

Python:
@dp.message_handler(commands=['rasilka'])
- строчка будет обрабатывать команду "/rasilka"

Python:
async def rasilka(message: types.Message):
- Асинхронная функция для обработки команды "/rasilka"

Python:
    if message.from_user.id != ADMIN_ID:
- строчка отвечает за проверку юзеров на права доступа к админ панели

Python:
        await message.reply("Вы не имеете доступа к админ-панели.")
       return
- если у юзера нету доступа к админ панели , то бот отправляет вышенаписанное сообщение

Python:
    text = message.get_args()
- строчка отвечает за получение текста сообщение для рассылки

Python:
    if not text:
        await message.reply("Пожалуйста, укажите сообщение для рассылки.")
        return
- данный кусочек кода отвечает за проверку был ли передан текст сообщения .Если нет , отправляет выше написанное сообщение

Python:
  sent = 0
- счетчик для отслеживание успешных отправок сообщений
Python:
  failed = 0
- счетчик для отслеживание неуспешных попыток отправки сообщений

Python:
   for user_id in user_data['user_adm']:
- Итперация по всем пользователям с правами администратора.

Python:
       try:
            await bot.send_message(user_id, text, parse_mode=ParseMode.MARKDOWN)
            sent += 1
        except Exception as e:
- кусочек кода отвечает за отправку сообщения каждому пользователю

Python:
         logging.error(f"Не удалось отправить сообщение пользователю {user_id}: {e}")
            failed += 1
-данный кусок кода отвечает за отправление сообщение если что то пошло не так

Python:
   await message.reply(f"Рассылка завершена.\nОтправлено: {sent}\nНе удалось отправить: {failed}")
- строчка отправляет сообщение с результатом рассылки(показывает сколько было отправлено успешных/не успешных сообщений

Python:
@dp.message_handler(commands=['stata'])
- строчка отвечает за обработку команды "/stata"

Python:
async def stata(message: types.Message):
- Асинхронная функция для обработки команды "/stata"

Python:
    if message.from_user.id != ADMIN_ID:
        await message.reply("Вы не имеете доступа к админ-панели.")
        return
- кусок кода отвечает за проверку прав доступка к админ панели , если нету то выводит выше написанное сообщение

Python:
  response_message = (
        f"Общее количество пользователей: {user_data['user']}\n"
        f"Пользователи с админкой: {len(user_data['user_adm'])}"
    )
- строчки формируют сообщение с статистикой пользователей

Python:
 await message.reply(response_message, parse_mode=ParseMode.MARKDOWN)
- отправка собственно сообщение со статистикой пользователю (админу)

Python:
if __name__ == '__main__':
- строчка проверяет скрипт на выполнение как основной модуль , а не импортированный

Python:
 executor.start_polling(dp, skip_updates=True)
- строчка отвечает за скип всех накопленных команд до запуска бота

Вот скрины что мы получим в конце


Давайте сейчас разберем бота автоответчика , то есть пользователю смогу отправлять сообщение боту . А тот в свою очередь будет отправлять все админу, так же добавим функцию отправка сообщения со стороны админа пользователю .Мы до этого писали на библиотеке aiogram , сейчас попрактикуемся на библиотеке telebot.

Python:
import telebot

TOKEN = ""
admin_id = 12345

bot = telebot.TeleBot(TOKEN)

@bot.message_handler(commands=['start'])
def handle_start(message: telebot.types.Message):
    if message.from_user.id == admin_id:
        bot.send_message(message.chat.id, "Приветствую, администратор!")
    else:
        bot.send_message(message.chat.id, f"Здравствуйте, {message.from_user.first_name}! Если у вас есть вопросы или предложения, не стесняйтесь обращаться.")

@bot.message_handler(commands=['help'])
def handle_help(message: telebot.types.Message):
    bot.send_message(message.chat.id, "Я могу помочь вам с различными задачами. Просто напишите ваш вопрос или отправьте файл. Администратор свяжется с вами в ближайшее время.")

@bot.message_handler(commands=['info'])
def handle_info(message: telebot.types.Message):
    bot.send_message(message.chat.id, "Этот бот предназначен для связи с администрацией. Вы можете отправлять сообщения, фотографии и документы. Все сообщения будут переданы администратору.")

@bot.message_handler(commands=['reply'])
def handle_reply_command(message: telebot.types.Message):
    if message.from_user.id == admin_id:
        try:
            args = message.text.split(maxsplit=2)
            if len(args) < 3:
                bot.send_message(message.chat.id, "Используйте: /reply <user_id> <текст сообщения>")
                return

            user_id = int(args[1])
            reply_text = args[2]

            bot.send_message(user_id, reply_text)
            bot.send_message(message.chat.id, f"Сообщение отправлено пользователю с ID {user_id}.")
        except ValueError:
            bot.send_message(message.chat.id, "Неверный формат ID. Убедитесь, что это число.")
    else:
        bot.send_message(message.chat.id, "У вас нет прав на выполнение этой команды.")

@bot.message_handler(func=lambda message: not message.reply_to_message and message.text and '/start' not in message.text)
def handle_text(message: telebot.types.Message):
    text_to_forward = (
        f"Сообщение от пользователя {message.from_user.first_name} (ID: {message.from_user.id}):\n"
        f"{message.text}"
    )
    bot.forward_message(admin_id, message.chat.id, message.message_id)
    bot.send_message(admin_id, text_to_forward)
    bot.send_message(message.chat.id, f"Ваше сообщение получено! Администратор вскоре ответит. Ваш ID: {message.from_user.id}")

@bot.message_handler(func=lambda message: message.reply_to_message)
def handle_reply(message: telebot.types.Message):
    if message.from_user.id == admin_id:
        if message.reply_to_message.forward_from:
            bot.send_message(message.reply_to_message.forward_from.id, message.text)
    else:
        bot.send_message(message.chat.id, "Ответы на сообщения не разрешены.")

@bot.message_handler(content_types=['photo'])
def handle_photo(message: telebot.types.Message):
    text_to_forward = (
        f"Фото от пользователя {message.from_user.first_name} (ID: {message.from_user.id})"
    )
    bot.forward_message(admin_id, message.chat.id, message.message_id)
    bot.send_message(message.chat.id, f"Фото получено и передано администратору. Ваш ID: {message.from_user.id}")

@bot.message_handler(content_types=['document'])
def handle_document(message: telebot.types.Message):
    text_to_forward = (
        f"Документ от пользователя {message.from_user.first_name} (ID: {message.from_user.id})"
    )
    bot.forward_message(admin_id, message.chat.id, message.message_id)
    bot.send_message(admin_id, text_to_forward)
    bot.send_message(message.chat.id, f"Документ получен и передан администратору. Ваш ID: {message.from_user.id}")

@bot.message_handler(content_types=['voice'])
def handle_voice(message: telebot.types.Message):
    text_to_forward = (
        f"Голосовое сообщение от пользователя {message.from_user.first_name} (ID: {message.from_user.id})"
    )
    bot.forward_message(admin_id, message.chat.id, message.message_id)
    bot.send_message(admin_id, text_to_forward)
    bot.send_message(message.chat.id, f"Голосовое сообщение получено и отправлено администратору. Ваш ID: {message.from_user.id}")

if __name__ == '__main__':
    print("Бот запущен...")
    bot.polling(none_stop=True)

начнем разбор кода !!!!

import telebot - импортируем библиотеку "telebot" .Данная библиотека используется для создание работы с телеграмм ботами, она намного упрощает взаимодействие с телеграмм api . Но по сравнению с aiogram по моему telebot чутка но отстает

Python:
TOKEN = ""
- сюда вводим токен нашего бота
Python:
admin_id = 12345
- вместо 12345 вводим свой id

Python:
bot = telebot.TeleBot(TOKEN)
- создаем можно сказать экземпляр бота с помощью токена , который в свою очередь передается "telebot.TeleBot"

Python:
@bot.message_handler(commands=['start'])
- строчка будет обрабатывать сообщение с командой "/start"

Python:
def handle_start(message: telebot.types.Message):
- строчка отвечает за определение функции сообщения можно сказать

Python:
if message.from_user.id == admin_id:
- строчка проверяет соответствует ли id юзера на наличие доступа к админке

Python:
      bot.send_message(message.chat.id, "Приветствую, администратор!")
- если юзер прошел проверку и имеет доступ к админ панели то бот е го приветствует
Python:
 else:
        bot.send_message(message.chat.id, f"Здравствуйте, {message.from_user.first_name}! Если у вас есть вопросы или предложения, не стесняйтесь обращаться.")
- если юзер не является администратором то бот отправляет выше написанное сообщение

Python:
@bot.message_handler(commands=['help'])
- строчка обрабатывает команду "/help"

Python:
def handle_help(message: telebot.types.Message):
- можно сказать это функция обработки команды "/help"

Python:
    bot.send_message(message.chat.id, "Я могу помочь вам с различными задачами. Просто напишите ваш вопрос или отправьте файл. Администратор свяжется с вами в ближайшее время.")
- данное сообщение бот отправляет если человек прописал команду "/help"

Python:
@bot.message_handler(commands=['info'])
- строчка обрабатывает команду "/info"

Python:
def handle_info(message: telebot.types.Message):
- функция для обработки команды "/info"

Python:
    bot.send_message(message.chat.id, "Этот бот предназначен для связи с администрацией. Вы можете отправлять сообщения, фотографии и документы. Все сообщения будут переданы администратору.")
- если человек прописал команду "/info" то бот отправляет выше написанное сообщение

Python:
@bot.message_handler(commands=['reply'])
- обработчик команды "/reply"

Python:
def handle_reply_command(message: telebot.types.Message):
- Функция для обработки команды "/reply"

Python:
   if message.from_user.id == admin_id:
- проверяет имеет ли юзер доступ к админ панели

Python:
        try:
            args = message.text.split(maxsplit=2)
- строчка отвечает за разделение текста сообщение , "maxsplit=2", позволяет разбить текст на три части(максимум)

Python:
          if len(args) < 3:
- строчка отвечает за проверку достатка количество символов

Python:
            bot.send_message(message.chat.id, "Используйте: /reply <user_id> <текст сообщения>")
                return
- бот отправляет выше написанное сообщение если админ хочет отправить сообщение юзеру

Python:
       user_id = int(args[1])
- Преобразование второго аргумента в целое число, представляющее ID пользователя.
Python:
      reply_text = args[2]
- текст ответа

Python:
      bot.send_message(user_id, reply_text)
- строчка отправляет сообщение пользователю по указанному выше id

Python:
       bot.send_message(message.chat.id, f"Сообщение отправлено пользователю с ID {user_id}.")
- если отправка сообщение закончилась успехом то бот показывает выше написанное сообщение

Python:
  except ValueError:
- можно сказать строчка обработает ошибку в случае неверного id
bot.send_message(message.chat.id, "Неверный формат ID. Убедитесь, что это число.")[/CODE] - бот отправит выше написанное сообщение если юзер с таким ид не зарегистрирован в боте
Python:
   else:
        bot.send_message(message.chat.id, "У вас нет прав на выполнение этой команды.")
- если юзер не имеет доступ к админ панели то бот покажет выше написанное сообщение

Python:
@bot.message_handler(func=lambda message: not message.reply_to_message and message.text and '/start' not in message.text)
- можно сказать это обработчик сообщений , которые не являются ответами или не содержит команду "/start"

Python:
def handle_text(message: telebot.types.Message):
- можно сказать это функция для обработки сообщений

Python:
   text_to_forward = (
        f"Сообщение от пользователя {message.from_user.first_name} (ID: {message.from_user.id}):\n"
        f"{message.text}")
- данный кусок кода отвечает за отправку сообщение от юзера к админу в нужном нам формате

Python:
 bot.forward_message(admin_id, message.chat.id, message.message_id)
- строчка пересылает сообщение юзера админу

Python:
  bot.send_message(admin_id, text_to_forward)
- сама отправка сообщения от юзера к админу

Python:
  bot.send_message(message.chat.id, f"Ваше сообщение получено! Администратор вскоре ответит. Ваш ID: {message.from_user.id}")
- если все прошло успешно то бот отправит выше написанное сообщение юзеру

Python:
@bot.message_handler(func=lambda message: message.reply_to_message)
- строчка отвечает за обработку сообщений , которые являются ответами на другие сообщения

Python:
def handle_reply(message: telebot.types.Message):
- сама функция для обработки ответов

Python:
  if message.from_user.id == admin_id:
- строчка проверяет отправителя сообщение на наличие доступа к админ панельки

Python:
    if message.reply_to_message.forward_from:
- строчка проверяет исходное сообщение ( если простыми словами ,то строчка проверяет есть ли отправитель у сообщения )

Python:
        bot.send_message(message.reply_to_message.forward_from.id, message.text)
- строчка отправляет ответ
Python:
   else:
        bot.send_message(message.chat.id, "Ответы на сообщения не разрешены.")
- если человек ответил на сообщение то бот его предупреждает что это может делать только админ

Python:
@bot.message_handler(content_types=['photo'])
- строчка будет обрабатывать сообщение где есть фотка

Python:
def handle_photo(message: telebot.types.Message):
- данная функция нужна для обработки фотографий

Python:
    text_to_forward = (
        f"Фото от пользователя {message.from_user.first_name} (ID: {message.from_user.id})"
    )
- кусочек кода отвечает за формирования текста сообщение администратору

Python:
 bot.forward_message(admin_id, message.chat.id, message.message_id)
- строчка отправляет (пересылает ) фотографию админу

Python:
   bot.send_message(message.chat.id, f"Фото получено и передано администратору. Ваш ID: {message.from_user.id}")
- если все прошло успешно то бот показывает выше написанное сообщение

Python:
@bot.message_handler(content_types=['document'])
- данная строчка будет обрабатывать сообщения содержащих какие либо документы (файлы)

Python:
def handle_document(message: telebot.types.Message):
- сама функция для обработки документов (файлов)

Python:
    text_to_forward = (
        f"Документ от пользователя {message.from_user.first_name} (ID: {message.from_user.id})"
    )
- кусок кода формирует сообщение для отправления администратору

Python:
    bot.forward_message(admin_id, message.chat.id, message.message_id)
- строчка пересылает документы администратору

Python:
   bot.send_message(admin_id, text_to_forward)
- сама отправка сообщение админу

Python:
  bot.send_message(message.chat.id, f"Документ получен и передан администратору. Ваш ID: {message.from_user.id}")
- если все прошло успешно бот показывает выше написанное сообщение


Python:
@bot.message_handler(content_types=['voice'])
- строчка обрабатывает голосовые сообщения

Python:
def handle_voice(message: telebot.types.Message):
- сама функция для обработки голосовых сообщений

Python:
  text_to_forward = (
        f"Голосовое сообщение от пользователя {message.from_user.first_name} (ID: {message.from_user.id})"
    )
- кусок кода формирует сообщение с информацией по выше указанному принципу

Python:
  bot.forward_message(admin_id, message.chat.id, message.message_id)
- пересылка голосового сообщения админу

Python:
  bot.send_message(admin_id, text_to_forward)
- сама отправка голосового сообщение админу

Python:
   bot.send_message(message.chat.id, f"Голосовое сообщение получено и отправлено администратору. Ваш ID: {message.from_user.id}")
- если все прошло успешно то бот отправляет выше написанное сообщение

Python:
if __name__ == '__main__':
- можно сказать это проверка что скрипт запускается напрямую а не импортируется как модуль

Python:
  print("Бот запущен...")
- сообщение показывает успешный запуск бота

Python:
  bot.polling(none_stop=True)
- Метод "polling" позволяет боту получать обновления от Telegram и обрабатывать их. Параметр "none_stop=True" указывает, что бот должен продолжать работу в случае возникновения ошибок.

Вот что у нас получилось
1722524513519.png


Давайте напишем последний для этой статьи бот , который будет показывать самые новые новости по команде /news .Мы напишем все на telebote , я напишу отдельную статью по aiogram .

Python:
import telebot
import requests

TELEGRAM_TOKEN = '6672409243:AAHfoFHqaFGpOpkbjHAgGRPALz_ZqxTZmng'
NEWS_API_KEY = '1ddfaaf6f6b24e4a8b8c47833edb8501'

bot = telebot.TeleBot(TELEGRAM_TOKEN)

def get_latest_news():
    url = f'https://newsapi.org/v2/top-headlines?country=ru&apiKey={NEWS_API_KEY}'
    response = requests.get(url)
    if response.status_code == 200:
        data = response.json()
        articles = data.get('articles', [])
        if articles:
            news_list = []
            for article in articles[:5]: 
                title = article.get('title', 'Нет заголовка')
                url = article.get('url', 'Нет URL')
                news_list.append(f'{title}\n{url}')
            return '\n\n'.join(news_list)
        else:
            return "Новости не найдены."
    else:
        return "Не удалось получить новости."

@bot.message_handler(commands=['start'])
def handle_start(message):
    bot.reply_to(message, "Приветствую! Используйте команду /news, чтобы получить последние новости.")

@bot.message_handler(commands=['news'])
def handle_news(message):
    news = get_latest_news()
    bot.send_message(message.chat.id, news)

if __name__ == '__main__':
    print("Бот запущен")
    bot.polling(none_stop=True)

Начнем разбор самого кода !

Python:
import telebot
- строчка импортирует библиотеку "pyTelegramBotAPI" для дальнейшей работы

Python:
import requests
- импортируем библиотеку которая нужна для работы http запросами

Python:
TELEGRAM_TOKEN = ''
- сюда вводим наш телеграмм токен
Python:
NEWS_API_KEY = ' '
- сюда вводим наш апи ключ ( его можно взять тут https://newsapi.org/account(не реклама ))

Python:
bot = telebot.TeleBot(TELEGRAM_TOKEN)
- можно сказать строчка создает новый объект используя токен .Это нужно для взаимодействия с телеграмм api

Python:
def get_latest_news(): 
    url = f'https://newsapi.org/v2/top-headlines?country=ru&apiKey={NEWS_API_KEY}'
- создаем url запрос для получение новостей . а так же используем "country=ru" для получение российских новостей а "apiKey={NEWS_API_KEY}" нужен для авторизации

Python:
response = requests.get(url)
- Выполняем GET-запрос к API новостей

Python:
   if response.status_code == 200:
- строчка проверяет успешен ли наш запрос

Python:
       data = response.json()
- получает данные ответа в формате JSON

Python:
     articles = data.get('articles', [])
- строчка извлекает список статей из ответа .А если "articles" отсутствует ,то возвращаем список но уже пустым

Python:
      if articles:
- проверка на наличии статей в списке

Python:
        news_list = []
- строчка создает пустой список (для хранение новостей)

Python:
     for article in articles[:5]:
- перебираем первые 5 статей ( кол во статей можете изменить )

Python:
         title = article.get('title', 'Нет заголовка')
- строчка получает заголовок статьи , если его нет то пишет об этом

Python:
         url = article.get('url', 'Нет URL')
- получаем url статьи , если url нету то пишет об этом

Python:
        news_list.append(f'{title}\n{url}')
- строчка добавляет заголовок и url самой статьи в список

Python:
     return '\n\n'.join(news_list)
- строчка формирует строку с новостями

Python:
  else:
            return "Новости не найдены."
- если новостей новых нету то от отправляет выше написанное сообщение
Python:
 else:
        return "Не удалось получить новости."
- если запрос по какой-то ошибки не удался то бот отправляет выше написанное сообщение

Python:
@bot.message_handler(commands=['start'])
- строчка выполняет функцию обработки команды "/start"

Python:
def handle_start(message):
    bot.reply_to(message, "Приветствую! Используйте команду /news, чтобы получить последние новости.")
- если юзер успешно запустил бота то бот отправляет вышенаписанное сообщение

Python:
@bot.message_handler(commands=['news'])
- строчка отвечает за обработку команды "/news"

Python:
def handle_news(message):
- сама функция обработки команды "/news"

Python:
 news = get_latest_news()
- при помощи "get_latest_news" получаем последние новости

Python:
 bot.send_message(message.chat.id, news)
- отправляем готовый результат пользователю

Python:
if __name__ == '__main__':
- строчка проверяет скрипт что он выполняется напрямую а не через импорт

Python:
  print("Бот запущен")
- если все успешно получилось то в консоли можно увидеть такой текст

Вот что мы получаем на выходе
1722527953192.png

Этот код позволяет создать бота в телеграмм , который в свою очередь отвечает за свежие новости с региона РФ по команду /news . Скрипт работает по по апи , да и принципе я добавил данный скрипт для усвоение работы с апи

Давайте подведем итоги данной статьи .Мы разобрали пару скриптов на telebote а так же на библиотеке aiogram, мы начали изучение с простого и закончили более сложным.А так же рассмотрели работу телеграмм ботов по апи , надеюсь статьи была интересной .Назовите мне тематику на которую мне стоит написать статью ( я обязательно напишу если это будет в моих силах ) .Удачного дня всем

1722514082138.png


1722514154442.png
 
Последнее редактирование модератором:
лайк однозначно. Тут вопрос даже не пользе статьи. Материал довольно легко гуглится. Но, судя по всему, автор решил таки взять на вооружение акиому "успех программиста прямопропорционален квадрату его задницы"
Продолжайте в том же духе и не обращайте ни на кого внимания, но соглашусь с постом выше - комментарии лучше писать непосредственно в коде. А еще лучше - не писать их вообще, а писать самодокументируемый код. Ъто не касается статьи, просто на будущее.
 
лайк однозначно. Тут вопрос даже не пользе статьи. Материал довольно легко гуглится. Но, судя по всему, автор решил таки взять на вооружение акиому "успех программиста прямопропорционален квадрату его задницы"
Продолжайте в том же духе и не обращайте ни на кого внимания, но соглашусь с постом выше - комментарии лучше писать непосредственно в коде. А еще лучше - не писать их вообще, а писать самодокументируемый код. Ъто не касается статьи, просто на будущее.
ну на диване виднее , надеюсь ты не только пиздеть критиковать можешь но и что то показать к примеру . Ждем от всезнайки Snow ,интересную статью =)
 
ну на диване виднее , надеюсь ты не только пиздеть критиковать можешь но и что то показать к примеру . Ждем от всезнайки Snow ,интересную статью =)
а я разве критиковал? я вроде как наоборот постарался поддержать тебя, дабы не отбить желание писать. Если ты считаешь критикой эту фразу: "Тут вопрос даже не пользе статьи. Материал довольно легко гуглится." - где я тут не прав? Я не говорил, что статья бесполезная, вовсе наооборот. Я просто указал, что материал достаточно легко гуглится и мануалов по используемым библиотекам пруд пруди.
Или, быть может, тебя оскорбила аксиома о квадратуре задницы? Разве я не прав, утверждая, что ты одним только объемом проделанной работы прокладываешь путь к успеху? Я специально слежу за твоими статьями и вижу как количество постепенно начинает переходить в качество.
А по поводу интересных статей - считай, что вызов принят. В ближайшие дни будет от меня статья еще. А чтобы тебе не скучно было, почитай пока вот это - раз, два, три.
 
Последнее редактирование:
ну на диване виднее , надеюсь ты не только пиздеть критиковать можешь но и что то показать к примеру . Ждем от всезнайки Snow ,интересную статью =)
Грубите, уважаемый. Вам Snow все по фактам раскидал. Почему бы свой "hello world" для публики не комментировать в коде? А ну да, так статья по правилам для оплаты не пройдет, надо же растянуть до 5 тысяч символов.
Мы с admin общались по поводу такого хитрого подхода, я говорил что на одну строчку кода некоторые генерируют кучу символов из воды чтобы получить оплату, а комменты в коде напримере моих исходников не идут в зачёт. Вот и получаем такие статьи. Он сказал что делать примерно, как делает ТС. По этому статьи такого формата я выкладывать никогда не буду, а просто оставлю лаконичный исходник с комментариями. Кому надо, тот поймет.
 
Последнее редактирование:
Грубите, уважаемый. Вам Snow все по фактам раскидал. Почему бы свой "hello world" для публики не комментировать в коде? А ну да, так статья по правилам для оплаты не пройдет, надо же растянуть до 5 тысяч символов.
Мы с admin общались по поводу такого хитрого подхода, я говорил что на одну строчку кода некоторые генерируют кучу символов из воды чтобы получить оплату, а комменты в коде напримере моих исходников не идут в зачёт. Вот и получаем такие статьи. Он сказал что делать примерно, как делает ТС. По этому статьи такого формата я выкладывать никогда не буду, а просто оставлю лаконичный исходник с комментариями. Кому надо, тот поймет.
в планах было с каждой статьей все глубже и глубже вникать в тот же питон и объяснять все от А до Я .Я пока чутка занят делами но обещаю что выпущу более интересную и информационную статью которая будет отличаться от всех написанных .
 
в планах было с каждой статьей все глубже и глубже вникать в тот же питон и объяснять все от А до Я .Я пока чутка занят делами но обещаю что выпущу более интересную и информационную статью которая будет отличаться от всех написанных .
Мне кажется это слишком амбициозная затея, которую можно и на 100 статей (примерно) растянуть. Это если делать таким подходом как например в этой статье, вон монументальный труд Марка Лутца по питону вообще в 2 тома написан. Ну смотрите, дело Ваше.
ИМХО Если хорошо знаете язык, лучше сосредоточить свои усилия на чем-нибудь полезном и оригинальном.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
в планах было с каждой статьей все глубже и глубже вникать в тот же питон и объяснять все от А до Я .Я пока чутка занят делами но обещаю что выпущу более интересную и информационную статью которая будет отличаться от всех написанных .
Не пиши больше, плиз
Python:
def get_latest_news():
    url = f'https://newsapi.org/v2/top-headlines?country=ru&apiKey={NEWS_API_KEY}'
    response = requests.get(url)
    if response.status_code == 200:
        data = response.json()
        articles = data.get('articles', [])
        if articles:
            news_list = []
            for article in articles[:5]:
                title = article.get('title', 'Нет заголовка')
                url = article.get('url', 'Нет URL')
                news_list.append(f'{title}\n{url}')
            return '\n\n'.join(news_list)
        else:
            return "Новости не найдены."
    else:
        return "Не удалось получить новости."
Исходи от условия "не истина", сбереги отступы
Python:
def get_latest_news():
    url = f'https://newsapi.org/v2/top-headlines?country=ru&apiKey={NEWS_API_KEY}'
    response = requests.get(url)
    if response.status_code != 200:
        return "Не удалось получить новости."

    data = response.json()
    articles = data.get('articles', [])
    
    if not articles:
        return "Новости не найдены."

    news_list = []
    for article in articles[:5]:
        title = article.get('title', 'Нет заголовка')
        url = article.get('url', 'Нет URL')
        news_list.append(f'{title}\n{url}')
    return '\n\n'.join(news_list)
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх