0
0
Lập trình
Sơn Tùng Lê
Sơn Tùng Lê103931498422911686980

Boilerplate cho bot Python năm 2025

Đăng vào 7 tháng trước

• 7 phút đọc

Giới thiệu

Trong bài viết này, chúng ta sẽ phân tích cấu trúc boilerplate cho bot Python từng bước, giải thích từng thành phần và cách chúng hoạt động cùng nhau. Với sự phát triển mạnh mẽ của các nền tảng như Discord và Telegram, việc xây dựng bot đã trở nên phổ biến hơn bao giờ hết. Hãy cùng khám phá cách thức hoạt động của boilerplate này và các thực tiễn tốt nhất để tối ưu hóa bot của bạn!

Mục lục

  1. Nhập khẩu và thiết lập
  2. Hệ thống cấu hình
  3. Lớp Bot cơ bản (Trừu tượng)
  4. Triển khai Bot Discord
  5. Triển khai Bot Telegram
  6. Triển khai Bot Web
  7. Quản lý Bot (Hỗ trợ đa bot)
  8. Luồng thực thi chính
  9. Cách mọi thứ hoạt động cùng nhau
  10. Ví dụ sử dụng
  11. Các mẫu thiết kế chính sử dụng

1. Nhập khẩu và thiết lập

python Copy
import os
import logging
import asyncio
import json
from abc import ABC, abstractmethod
from typing import Dict, Any, Optional
from dataclasses import dataclass
from datetime import datetime

Giải thích:

  • Các thư viện chuẩn được nhập khẩu cho các thao tác file, logging và lập trình bất đồng bộ.
  • ABCabstractmethod được sử dụng để tạo lớp cơ sở mà các lớp khác phải triển khai.
  • Gợi ý kiểu giúp cải thiện tài liệu mã và hỗ trợ IDE.
  • dataclass giúp quản lý cấu hình dễ dàng hơn.

Nhập khẩu điều kiện:

python Copy
try:
    import discord
    DISCORD_AVAILABLE = True
except ImportError:
    DISCORD_AVAILABLE = False

Tại sao lại sử dụng mẫu này:

  • Cho phép bot hoạt động ngay cả khi không có tất cả các thư viện được cài đặt.
  • Bạn chỉ cài đặt những gì bạn cần (Discord HOẶC Telegram HAY chỉ chức năng web).
  • Fallback nhẹ nhàng khi thiếu phụ thuộc.

2. Hệ thống cấu hình

python Copy
@dataclass
class BotConfig:
    token: str
    prefix: str = "!"
    admin_ids: list = None
    debug: bool = False
    database_url: Optional[str] = None

Chức năng:

  • @dataclass tự động tạo __init__, __repr__, v.v.
  • Lưu trữ tất cả cài đặt bot ở một nơi.
  • Giá trị mặc định có nghĩa là bạn chỉ cần chỉ định những gì bạn cần.
  • Gợi ý kiểu giúp phát hiện lỗi sớm hơn.

Tải cấu hình từ môi trường:

python Copy
def load_config() -> BotConfig:
    return BotConfig(
        token=os.getenv("BOT_TOKEN", ""),
        prefix=os.getenv("BOT_PREFIX", "!"),
        admin_ids=[int(x) for x in os.getenv("ADMIN_IDS", "").split(",") if x]
    )

3. Lớp Bot cơ bản (Trừu tượng)

python Copy
class BaseBot(ABC):
    def __init__(self, config: BotConfig):
        self.config = config
        self.logger = logging.getLogger(self.__class__.__name__)
        self.is_running = False

    @abstractmethod
    async def start(self):
        pass

    @abstractmethod  
    async def stop(self):
        pass

Thiết kế này có những điểm mạnh:

  • Kế thừa: Tất cả các loại bot chia sẻ chức năng chung.
  • Phương thức trừu tượng: Buộc mọi loại bot phải triển khai start()stop().
  • Đa hình: Bạn có thể xử lý tất cả các bot theo cùng một cách bất kể loại nào.
  • Nguyên tắc DRY: Mã chung (logging, kiểm tra admin) được viết một lần.

Chức năng chia sẻ:

python Copy
def is_admin(self, user_id: int) -> bool:
    return user_id in self.config.admin_ids

async def log_message(self, message: str, level: str = "info"):
    # Logging tập trung với thời gian

4. Triển khai Bot Discord

python Copy
class DiscordBot(BaseBot):
    def __init__(self, config: BotConfig):
        super().__init__(config)  # Gọi constructor của cha

        intents = discord.Intents.default()
        intents.message_content = True  # Cần thiết để đọc tin nhắn

        self.bot = commands.Bot(command_prefix=config.prefix, intents=intents)

Khái niệm chính:

  • Hệ thống sự kiện:
python Copy
@self.bot.event
async def on_ready():
    await self.log_message(f'{self.bot.user} đã kết nối!')

@self.bot.event
async def on_message(message):
    if message.author == self.bot.user:
        return  # Không phản hồi lại chính mình
    await self.bot.process_commands(message)
  • Hệ thống lệnh:
python Copy
@self.bot.command(name='hello')
async def hello(ctx):
    await ctx.send(f'Xin chào {ctx.author.mention}!')
  • Xử lý lỗi:
python Copy
@self.bot.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.CommandNotFound):
        await ctx.send("Không tìm thấy lệnh!")

5. Triển khai Bot Telegram

python Copy
class TelegramBot(BaseBot):
    def __init__(self, config: BotConfig):
        super().__init__(config)
        self.application = Application.builder().token(config.token).build()

Mẫu xử lý:

python Copy
async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text('Xin chào!')

# Đăng ký trình xử lý
self.application.add_handler(CommandHandler("start", start_command))

Khác với Discord:

  • Telegram sử dụng trình xử lý thay vì decorators.
  • Đối tượng Update chứa thông tin tin nhắn.
  • Cấu trúc API khác nhưng cùng mẫu bất đồng bộ.

6. Triển khai Bot Web

python Copy
class WebBot(BaseBot):
    def __init__(self, config: BotConfig):
        super().__init__(config)
        self.session = None  # Phiên HTTP
        self.tasks = []      # Tác vụ nền

Yêu cầu HTTP:

python Copy
async def make_request(self, method: str, url: str, **kwargs):
    async with self.session.request(method, url, **kwargs) as response:
        return await response.json()

Tác vụ định kỳ:

python Copy
async def periodic_task(self):
    while self.is_running:
        await self.log_message("Đang chạy tác vụ...")
        await asyncio.sleep(60)  # Mỗi phút

7. Quản lý Bot (Hỗ trợ đa bot)

python Copy
class BotManager:
    def __init__(self):
        self.bots = {}

    async def start_all(self):
        tasks = []
        for name, bot in self.bots.items():
            tasks.append(asyncio.create_task(bot.start()))
        await asyncio.gather(*tasks)  # Chạy tất cả các bot cùng một lúc

Tại sao điều này hữu ích:

  • Chạy nhiều bot cùng lúc (Discord + Telegram).
  • Quản lý tập trung.
  • Tắt tất cả các bot một cách nhẹ nhàng.

8. Luồng thực thi chính

python Copy
async def main():
    config = load_config()

    if not config.token:
        logger.error("Cần BOT_TOKEN!")
        return

    bot_type = os.getenv("BOT_TYPE", "discord").lower()

    if bot_type == "discord":
        bot = DiscordBot(config)
    elif bot_type == "telegram":
        bot = TelegramBot(config)
    # ...

    await bot.start()

Thực thi:

python Copy
if __name__ == "__main__":
    asyncio.run(main())

9. Cách mọi thứ hoạt động cùng nhau

Giải thích từng bước:

  1. Tải cấu hình từ các biến môi trường.
  2. Xác định loại bot từ biến môi trường BOT_TYPE.
  3. Tạo phiên bản bot phù hợp (Discord/Telegram/Web).
  4. Bot kế thừa từ BaseBot nên nó có chức năng chung.
  5. Bot thiết lập các trình xử lý/sự kiện cụ thể của nó.
  6. Bot bắt đầu và bắt đầu lắng nghe tin nhắn/sự kiện.
  7. Khi nhận được tin nhắn, trình xử lý thích hợp xử lý nó.
  8. Logging diễn ra liên tục thông qua các phương thức kế thừa.
  9. Tắt nhẹ nhàng khi bị ngắt.

10. Ví dụ sử dụng

Thiết lập môi trường (.env file):

plaintext Copy
BOT_TOKEN=your_discord_bot_token
BOT_TYPE=discord
BOT_PREFIX=!
ADMIN_IDS=123456789,987654321

Chạy:

bash Copy
python bot.py

Điều gì xảy ra:

  1. Tải token Discord từ .env.
  2. Tạo phiên bản DiscordBot.
  3. Thiết lập các lệnh như !hello, !ping, !info.
  4. Bắt đầu lắng nghe tin nhắn Discord.
  5. Tự động phản hồi các lệnh.

11. Các mẫu thiết kế chính sử dụng

  • Abstract Factory: BaseBot định nghĩa giao diện, các bot cụ thể triển khai nó.
  • Strategy Pattern: Các loại bot khác nhau sử dụng các chiến lược khác nhau (API Discord vs API Telegram).
  • Template Method: BaseBot cung cấp cấu trúc chung, các lớp con bổ sung chi tiết.
  • Dependency Injection: Cấu hình được truyền cho các bot thay vì cứng nhắc.

Thiết kế này giúp mã trở thành:

  • Modular: Dễ dàng thêm các loại bot mới.
  • Dễ bảo trì: Thay đổi chức năng chung ảnh hưởng đến tất cả các bot.
  • Dễ kiểm tra: Mỗi thành phần có thể được kiểm tra độc lập.
  • Mở rộng: Dễ dàng thêm các tính năng như cơ sở dữ liệu, plugin, v.v.

Boilerplate này xử lý các thiết lập phức tạp để bạn có thể tập trung vào việc thêm chức năng bot cụ thể của bạn!

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào