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.
- 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 info.txt to customize the bot's background knowledge. Seperate 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.) and a Bilibili URL (supports bilibili.com and b23.tv).
Handled in main.handle_all_text which calls:
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 download | app/youtube_dl.py |
| Reply decision + generation | app/reply2message.py |
| SQLite persistence | app/database.py |
| Secrets template | secret.py.template |
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
- Python 3.11+ (pycache indicates 3.13 compatible).
- Clone repository.
- Create virtual environment:
python -m venv .venv source .venv/bin/activate - Install Python dependencies:
bash pip_install.sh - Install Playwright browser:
playwright install chromium - Ensure FFmpeg available (for yt-dlp post-processing):
# Debian/Ubuntu sudo apt-get update && sudo apt-get install -y ffmpeg - Copy secrets:
Fill Azure + Telegram values in
cp secret.py.template secret.pysecret.py.
Set deployment name in main.py:
AZURE_OPENAI_DEPLOYMENT_NAME = "your-deployment"
API details passed from secret.pass_secret_variables into runtime constants in main.py.
python main.py
On first run SQLite file message_history.db created by app.database.init_db. Output images/videos stored temporarily in output/.
| Action | How |
|---|---|
| Start | /start |
| Markdown to image | /md2jpg ,,,...markdown...,,, |
| Plain text to image | /text2jpg ,,,...plain text...,,, |
| File to image | Upload .txt / .md |
| YouTube download | 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
secret.py. - 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 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
See [pip_install.sh](pip_install.sh). Core libs: python-telegram-bot (async), markdown2, playwright, Pillow, yt-dlp, openai (Azure), aiosqlite, requests, bs4.
---
## Disclaimer
AI replies are probabilistic; moderate in large groups.
