MioBot 是一个异步 Telegram 机器人,提供以下功能:
- 将内联 Markdown 或纯文本转换为图片。
- 支持上传
.txt/.md文件并转成图片。 - 识别消息里的 YouTube 以及 Bilibili 链接并下载 720p H.264 MP4。
- 在群聊中根据最近上下文与随机概率(或被直接回复时必定)的一位“猫娘”Bot。
- 使用 SQLite 保存消息,每次API Call使用最近最多 100 条群消息,供上下文生成回复。
- 基于 Azure OpenAI(自定义部署模型)完成文本格式化与对话生成。
核心流程:
/md2jpg或/text2jpg指令解析内容 →(可选:调用 LLM 转 Markdown)→ Playwright 渲染 HTML → 截图 → Pillow 转换格式。- 群消息写入 SQLite → 条件触发 → LLM 决策 + 生成 JSON → 发送简短猫娘风格回复。
- 发现 YouTube 链接 → yt-dlp + ffmpeg 合成 mp4 → 回传。
特点:轻量、模块化、异步、易扩展。适合需要内容可视化 + 轻社交陪伴的中文/多语言群。
Async Telegram bot that:
- Converts inline Markdown or plain text to themed images (formal code or cute anime).
- Converts uploaded
.txt/.mdfiles to images. - Downloads YouTube videos (up to 720p AVC) on link detection, and auto-compresses oversized files to Telegram's 50MB limit before sending.
- Occasionally (or when directly addressed / replied to) participates in group chats in a cat‑girl persona using Azure OpenAI.
- Persists recent group chat history in SQLite for contextual replies.
You can edit the information in config/info.txt to customize the bot's background knowledge. Separate each piece of information with a new line. The bot will use this information to generate replies.
Commands (content wrapped by ,,, sent in one message):
/md2jpg ,,,# Title
Some *markdown* here,,,
/text2jpg ,,,Some plain unformatted text here,,,
Plain text is first converted to Markdown via Azure OpenAI using app.text2md.plain_text_to_markdown, then rendered to HTML + screenshot via Chromium (Playwright) using app.md2jpg.md_to_image.
More examples in output/.
Upload a .txt (will be converted first) or .md (used as-is). Bot returns an image.
Paste (no command needed) a YouTube URL (supports watch, shorts, youtu.be, etc.), a Bilibili URL (supports bilibili.com and b23.tv), or a Twitter/X status link.
Handled in main.handle_all_text which calls:
app.youtube_dl.get_video_titleapp.youtube_dl.download_video_720p_h264app.twitter_downloader.TwitterDownloader.extract_twitter_mediafor Twitter/X links
Stores messages in SQLite via:
app.database.add_messageapp.database.get_messages
Decision + generation handled byapp.reply2message.should_reply_and_generateusing Azure OpenAI (JSON-mode). Logic:- Always reply if user directly replies to bot.
- Otherwise random sampling gate (1 in 5) to reduce noise.
- Uses last N (100) messages from DB.
Themes: formal_code (default) or cute_anime (see CSS in app.md2jpg.md_to_image). Multi-format support: jpg / webp / avif / png.
| Concern | File |
|---|---|
| Entry point & handlers | main.py |
| Markdown → Image | app/md2jpg.py |
| Plain Text → Markdown (LLM) | app/text2md.py |
| YouTube/Bilibili download | app/youtube_dl.py |
| Twitter/X media extraction | app/twitter_downloader.py |
| Reply decision + generation | app/reply2message.py |
| SQLite persistence | app/database.py |
| Runtime secret template | config/runtime.env.template |
| Runtime config loader | app/runtime_config.py |
Key symbols:
app.md2jpg.md_to_imageapp.text2md.plain_text_to_markdownapp.youtube_dl.download_video_720p_h264app.youtube_dl.get_video_titleapp.reply2message.should_reply_and_generateapp.database.init_dbapp.database.add_messageapp.database.get_messages
- Install Python 3.11+.
- Install uv (https://docs.astral.sh/uv/getting-started/installation/).
- Clone repository.
- Sync environment and dependencies:
uv sync - Install Playwright browser:
uv run playwright install chromium - Ensure FFmpeg available (for yt-dlp post-processing):
# Debian/Ubuntu sudo apt-get update && sudo apt-get install -y ffmpeg - Configure runtime secrets in config folder:
Fill Azure/Telegram/API values in
cp config/runtime.env.template config/runtime.local.envconfig/runtime.local.env.
Set deployment name in main.py:
AZURE_OPENAI_DEPLOYMENT_NAME = "your-deployment"
API details are loaded at startup from config env files by app/runtime_config.py and injected into runtime env before bot initialization.
uv run miobot
Alternative (equivalent):
uv run python main.py
On first run SQLite file data/message_history.db is created by app.database.init_db. You can override this via DB_FILE in runtime env. Output images/videos are stored temporarily in output/.
Build image:
docker build -t miobot:latest .Run with mounted runtime config + persistent storage:
docker run --rm -it \
--name miobot \
-v "$PWD/config/runtime.local.env:/app/config/runtime.local.env:ro" \
-v "$PWD/data:/app/data" \
-v "$PWD/output:/app/output" \
miobot:latestNotes:
- Mount
config/runtime.local.envso secrets stay outside the image. - Mount
data/to persist SQLite history across container restarts. - Mount
output/to keep generated images and downloaded media on host.
| Action | How |
|---|---|
| Start | /start |
| Markdown to image | /md2jpg ,,,...markdown...,,, |
| Plain text to image | /text2jpg ,,,...plain text...,,, |
| File to image | Upload .txt / .md |
| Video download (YouTube/Bilibili/Twitter-X) | Paste link |
| Group playful reply | Bot auto-decides (see logic) |
Notes:
- Wrap payload exactly with leading and trailing
,,,. - Bot deletes original YouTube link message after sending video.
SQLite keeps last 100 messages per chat (trim done in app.database.add_message). Retrieval ordered ascending for model consumption in app.database.get_messages.
- (Optional) LLM formatting:
app.text2md.plain_text_to_markdown - Markdown → HTML (markdown2).
- HTML → headless Chromium screenshot (Playwright) in
app.md2jpg.md_to_image. - Convert PNG → target format via Pillow.
- Each handler wraps generation / download with try–except and reports concise Telegram error.
- Video / image temporary artifacts removed after send.
- LLM / API failures logged; reply generation returns None gracefully.
Ideas:
- Add rate limiting per user.
- Add admin-only commands for purging DB.
- Add more rendering themes.
- Add inline query support.
- Cache YouTube titles.
- Do not commit
config/runtime.local.envor cookie files inconfig/. - Current design keeps API keys only in memory.
- Consider Dockerizing & injecting secrets via environment variables instead of Python file.
| Symptom | Cause | Fix |
|---|---|---|
| Playwright error | Browser not installed | Run uv run playwright install chromium |
| Video fails | Missing ffmpeg | Install ffmpeg |
| No AI replies | Deployment name mismatch | Check AZURE_OPENAI_DEPLOYMENT_NAME |
| Unicode issues | Font fallback missing | Add Noto fonts system-wide if needed |
GNU General Public License v3.0
This project is licensed under the GNU GPLv3. See LICENSE for details.
Markdown request:
/md2jpg ,,,# Title
Some code:
```python
print("Hello")
,,,
Plain text request:
/text2jpg ,,,This is raw text that should become markdown.,,,
---
## Dependency Reference
Dependencies are managed via [pyproject.toml](pyproject.toml). A `uv.lock` file is generated after `uv sync`.
Core libs: python-telegram-bot (async), markdown2, playwright, Pillow, yt-dlp, httpx, aiosqlite, numpy, requests.
---
## Refactoring Aims
Refactoring targets are tracked in [REFACTORING_AIMS.md](REFACTORING_AIMS.md).
---
## Disclaimer
AI replies are probabilistic; moderate in large groups.
