Пошаговое руководство: Как создать Telegram Mini App на Python в 2024 году

как создать приложение телеграм Python

Что такое Telegram Mini Apps и зачем их создавать

Telegram Mini Apps — это веб-приложения, которые можно запускать прямо внутри Telegram. Они позволяют расширить функциональность ботов и предоставить пользователям удобный интерфейс для взаимодействия. В этой статье мы рассмотрим, как создать Telegram Mini App с нуля, используя Python.

Для всех, кто не хочет разбираться в коде — собрал список конструкторов Telegram Mini App

Подготовка окружения для разработки Telegram Mini App

Для разработки нам понадобится:

  1. Python 3.8+
  2. FastAPI — современный и быстрый веб-фреймворк для Python
  3. python-telegram-bot — библиотека для работы с Telegram Bot API
  4. uvicorn — ASGI сервер для запуска FastAPI приложения

Установим необходимые зависимости:

pip install fastapi python-telegram-bot uvicorn

Я выбрал FastAPI, так как он обеспечивает высокую производительность и имеет встроенную поддержку асинхронного программирования, что важно для работы с Telegram API.

Создание базовой структуры Telegram Mini App на Python

Создадим файл main.py с базовой структурой нашего приложения:

from fastapi import FastAPI
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes

app = FastAPI()

# Telegram bot token
TOKEN = "YOUR_BOT_TOKEN"

# Initialize bot
bot = ApplicationBuilder().token(TOKEN).build()

@app.get("/")
async def root():
    return {"message": "Telegram Mini App is running"}

# Telegram command handler
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text("Welcome to our Telegram Mini App!")

# Add command handler to bot
bot.add_handler(CommandHandler("start", start))

# Run bot polling in the background
@app.on_event("startup")
async def startup_event():
    await bot.initialize()
    await bot.start()

@app.on_event("shutdown")
async def shutdown_event():
    await bot.stop()

Этот код создает базовую структуру для Telegram Mini App, используя FastAPI для веб-сервера и python-telegram-bot для обработки команд бота.

Реализация основных функций Telegram Mini App

Теперь добавим функциональность для нашего Mini App. Создадим простое приложение для заметок:

from fastapi import FastAPI, Request
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import ApplicationBuilder, CommandHandler, CallbackQueryHandler, ContextTypes

app = FastAPI()

TOKEN = "YOUR_BOT_TOKEN"
bot = ApplicationBuilder().token(TOKEN).build()

notes = {}

@app.get("/")
async def root():
    return {"message": "Telegram Mini App is running"}

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    keyboard = [
        [InlineKeyboardButton("Add Note", callback_data="add_note")],
        [InlineKeyboardButton("View Notes", callback_data="view_notes")]
    ]
    reply_markup = InlineKeyboardMarkup(keyboard)
    await update.message.reply_text("Welcome to NotesApp!", reply_markup=reply_markup)

async def button_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query
    await query.answer()

    if query.data == "add_note":
        await query.message.reply_text("Please send your note:")
        context.user_data["expecting_note"] = True
    elif query.data == "view_notes":
        user_id = query.from_user.id
        if user_id in notes:
            note_list = "\n".join(notes[user_id])
            await query.message.reply_text(f"Your notes:\n{note_list}")
        else:
            await query.message.reply_text("You don't have any notes yet.")

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if context.user_data.get("expecting_note"):
        user_id = update.message.from_user.id
        note = update.message.text
        if user_id not in notes:
            notes[user_id] = []
        notes[user_id].append(note)
        context.user_data["expecting_note"] = False
        await update.message.reply_text("Note added successfully!")

bot.add_handler(CommandHandler("start", start))
bot.add_handler(CallbackQueryHandler(button_callback))
bot.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))

@app.on_event("startup")
async def startup_event():
    await bot.initialize()
    await bot.start()

@app.on_event("shutdown")
async def shutdown_event():
    await bot.stop()

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

Этот код реализует простое приложение для заметок, где пользователи могут добавлять и просматривать свои заметки.

Интеграция Telegram Mini App с веб-интерфейсом

Для создания пользовательского интерфейса Mini App, мы будем использовать HTML, CSS и JavaScript. Создадим файл index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>NotesApp Mini App</title>
    <script src="https://telegram.org/js/telegram-web-app.js"></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: var(--tg-theme-bg-color, #ffffff);
            color: var(--tg-theme-text-color, #000000);
        }
        .button {
            background-color: var(--tg-theme-button-color, #3390ec);
            color: var(--tg-theme-button-text-color, #ffffff);
            border: none;
            padding: 10px 20px;
            margin: 5px;
            cursor: pointer;
            border-radius: 5px;
        }
    </style>
</head>
<body>
    <h1>NotesApp</h1>
    <button class="button" id="addNoteBtn">Add Note</button>
    <button class="button" id="viewNotesBtn">View Notes</button>
    <div id="notesList"></div>

    <script>
        let tg = window.Telegram.WebApp;
        tg.expand();

        document.getElementById('addNoteBtn').addEventListener('click', () => {
            tg.showPopup({
                title: 'Add Note',
                message: 'Enter your note:',
                buttons: [{type: 'ok', text: 'Add'}]
            }, (buttonId) => {
                if (buttonId === 'ok') {
                    // Here you would typically send the note to your server
                    alert('Note added!');
                }
            });
        });

        document.getElementById('viewNotesBtn').addEventListener('click', () => {
            // Here you would typically fetch notes from your server
            let notes = ['Sample note 1', 'Sample note 2'];
            let notesList = document.getElementById('notesList');
            notesList.innerHTML = notes.map(note => `<p>${note}</p>`).join('');
        });
    </script>
</body>
</html>

Этот HTML файл создает простой интерфейс для нашего Mini App, используя Telegram Web App JS SDK для интеграции с Telegram.

Оптимизация производительности Telegram Mini App

Для оптимизации производительности нашего Mini App, мы можем использовать кэширование и асинхронные операции:

from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import ApplicationBuilder, CommandHandler, CallbackQueryHandler, ContextTypes
import aioredis

app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")

TOKEN = "YOUR_BOT_TOKEN"
bot = ApplicationBuilder().token(TOKEN).build()

# Redis для кэширования
redis = aioredis.from_url("redis://localhost")

@app.get("/", response_class=HTMLResponse)
async def root():
    with open("index.html", "r") as f:
        return f.read()

async def get_notes(user_id: int):
    cached_notes = await redis.get(f"notes:{user_id}")
    if cached_notes:
        return cached_notes.decode().split(",")
    return []

async def add_note(user_id: int, note: str):
    notes = await get_notes(user_id)
    notes.append(note)
    await redis.set(f"notes:{user_id}", ",".join(notes))

@app.post("/add_note")
async def add_note_api(request: Request):
    data = await request.json()
    user_id = data["user_id"]
    note = data["note"]
    await add_note(user_id, note)
    return {"status": "success"}

@app.get("/get_notes/{user_id}")
async def get_notes_api(user_id: int):
    notes = await get_notes(user_id)
    return {"notes": notes}

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    keyboard = [
        [InlineKeyboardButton("Open Mini App", web_app={"url": "https://your-domain.com"})],
    ]
    reply_markup = InlineKeyboardMarkup(keyboard)
    await update.message.reply_text("Welcome to NotesApp!", reply_markup=reply_markup)

bot.add_handler(CommandHandler("start", start))

@app.on_event("startup")
async def startup_event():
    await bot.initialize()
    await bot.start()

@app.on_event("shutdown")
async def shutdown_event():
    await bot.stop()
    await redis.close()

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

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

Тестирование и отладка Telegram Mini App

Для тестирования нашего Mini App мы можем использовать инструменты разработчика в браузере и логирование на сервере:

import logging
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import ApplicationBuilder, CommandHandler, CallbackQueryHandler, ContextTypes
import aioredis

# Настройка логирования
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)
logger = logging.getLogger(__name__)

app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")

TOKEN = "YOUR_BOT_TOKEN"
bot = ApplicationBuilder().token(TOKEN).build()

redis = aioredis.from_url("redis://localhost")

@app.get("/", response_class=HTMLResponse)
async def root():
    with open("index.html", "r") as f:
        return f.read()

async def get_notes(user_id: int):
    cached_notes = await redis.get(f"notes:{user_id}")
    if cached_notes:
        return cached_notes.decode().split(",")
    return []

async def add_note(user_id: int, note: str):
    notes = await get_notes(user_id)
    notes.append(note)
    await redis.set(f"notes:{user_id}", ",".join(notes))
    logger.info(f"Added note for user {user_id}: {note}")

@app.post("/add_note")
async def add_note_api(request: Request):
    data = await request.json()
    user_id = data["user_id"]
    note = data["note"]
    await add_note(user_id, note)
    return {"status": "success"}

@app.get("/get_notes/{user_id}")
async def get_notes_api(user_id: int):
    notes = await get_notes(user_id)
    logger.info(f"Retrieved notes for user {user_id}: {notes}")
    return {"notes": notes}

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    keyboard = [
        [InlineKeyboardButton("Open Mini App", web_app={"url": "https://your-domain.com"})],
    ]
    reply_markup = InlineKeyboardMarkup(keyboard)
    await update.message.reply_text("Welcome to NotesApp!", reply_markup=reply_markup)
    logger.info(f"User {update.effective_user.id} started the bot")

bot.add_handler(CommandHandler("start", start))

@app.on_event("startup")
async def startup_event():
    await bot.initialize()
    await bot.start()
    logger.info("Bot started")

@app.on_event("shutdown")
async def shutdown_event():
    await bot.stop()
    await redis.close()
    logger.info("Bot stopped")

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

Этот код добавляет логирование, что поможет в отладке приложения.

Развертывание Telegram Mini App на сервере

Для развертывания нашего Mini App мы можем использовать Docker. Создадим Dockerfile:

FROM python:3.9

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Создадим файл docker-compose.yml:

version: '3.8'

services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
    depends_on:
      - redis

  redis:
    image: "redis:alpine"
    ports:
      - "6379:6379"

Этот файл определяет два сервиса: наше веб-приложение и Redis для кэширования.

Теперь создадим файл .env для хранения конфиденциальных данных:

TELEGRAM_BOT_TOKEN=your_bot_token_here

Для развертывания приложения выполните следующие команды:

docker-compose build
docker-compose up -d

Эти команды соберут и запустят ваше приложение в контейнерах Docker.

Оптимизация SEO для Telegram Mini App

Хотя Telegram Mini Apps работают внутри Telegram и не индексируются поисковыми системами напрямую, мы можем оптимизировать наше веб-приложение для лучшего обнаружения пользователями:

  1. Используйте осмысленные URL-адреса для различных функций вашего приложения.
  2. Добавьте метатеги для улучшения отображения ссылок на ваше приложение в чатах Telegram.

Обновим наш index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>NotesApp - Your Personal Note Taking Telegram Mini App</title>
    <meta name="description" content="NotesApp is a Telegram Mini App that allows you to create and manage your personal notes directly within Telegram.">
    <meta property="og:title" content="NotesApp - Personal Note Taking in Telegram">
    <meta property="og:description" content="Create, view, and manage your notes easily with NotesApp Telegram Mini App.">
    <meta property="og:image" content="https://your-domain.com/static/notesapp-preview.jpg">
    <script src="https://telegram.org/js/telegram-web-app.js"></script>
    <!-- Остальной код остается без изменений -->
</head>
<body>
    <!-- Содержимое body остается без изменений -->
</body>
</html>

Мониторинг и аналитика Telegram Mini App

Для отслеживания производительности и использования вашего Mini App, добавим базовую аналитику. Мы будем использовать простой подход с логированием в файл, но в реальном проекте вы можете использовать более продвинутые инструменты аналитики.

Добавим следующий код в main.py:

import logging
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
import time

# Настройка логирования
logging.basicConfig(
    filename='app_analytics.log',
    level=logging.INFO,
    format='%(asctime)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)

app = FastAPI()

# Добавляем middleware для CORS и аналитики
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    logging.info(f"Path: {request.url.path}, Method: {request.method}, Process Time: {process_time:.4f}s")
    return response

# Остальной код остается без изменений

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

Обеспечение безопасности Telegram Mini App

Безопасность критически важна для любого веб-приложения. Вот несколько мер, которые мы можем предпринять:

  1. Используйте HTTPS для всех соединений.
  2. Валидируйте все входные данные от пользователя.
  3. Используйте безопасные заголовки HTTP.

Обновим наш main.py:

from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from starlette.middleware.sessions import SessionMiddleware
import hashlib
import hmac
import json

app = FastAPI()

# Добавляем middleware
app.add_middleware(SessionMiddleware, secret_key="your-secret-key")
app.add_middleware(TrustedHostMiddleware, allowed_hosts=["your-domain.com"])
app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://your-domain.com"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

security = HTTPBearer()

def verify_telegram_data(init_data: str, bot_token: str) -> bool:
    try:
        data = dict(param.split('=') for param in init_data.split('&'))
        received_hash = data.pop('hash')
        data_check_string = '\n'.join(f"{k}={v}" for k, v in sorted(data.items()))
        secret_key = hmac.new("WebAppData".encode(), bot_token.encode(), hashlib.sha256).digest()
        calculated_hash = hmac.new(secret_key, data_check_string.encode(), hashlib.sha256).hexdigest()
        return calculated_hash == received_hash
    except Exception:
        return False

@app.post("/api/secure_endpoint")
async def secure_endpoint(request: Request, credentials: HTTPAuthorizationCredentials = Depends(security)):
    init_data = credentials.credentials
    if not verify_telegram_data(init_data, "YOUR_BOT_TOKEN"):
        raise HTTPException(status_code=403, detail="Invalid authentication")

    # Ваш защищенный код здесь
    return {"message": "Authenticated successfully"}

# Остальной код остается без изменений

Этот код добавляет проверку подлинности данных, полученных от Telegram, и использует безопасные заголовки и CORS настройки.

Secure Telegram Mini App

Будущее Telegram Mini Apps

Telegram Mini Apps открывают новые возможности для разработчиков и пользователей, позволяя создавать богатые интерактивные приложения прямо внутри Telegram. С помощью Python и современных веб-технологий мы можем создавать мощные, безопасные и эффективные Mini Apps.

В этой статье мы рассмотрели основы создания Telegram Mini App на Python, начиная с базовой структуры и заканчивая развертыванием, оптимизацией и обеспечением безопасности. Продолжайте экспериментировать и расширять возможности вашего Mini App, и не забывайте следить за обновлениями Telegram Bot API для использования новых функций по мере их появления.

Надеюсь, это руководство поможет вам начать свой путь в разработке Telegram Mini Apps!



Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x