Production-ready Telegram bot for a small Linux VPS: a user sends a .doc or .docx file, the bot downloads it, converts it to PDF with LibreOffice headless, sends the PDF back, and removes temporary files.
The architecture is intentionally simple: Python 3.11+, aiogram 3.x, asyncio.Queue, one worker, and one LibreOffice conversion at a time. No Docker, Redis, Celery, or database.
- Accepts only
.docand.docxfiles. - Limits input files to 20 MB.
- Uses a bounded queue with
maxsize=5. - Runs only one conversion at a time.
- Creates a separate temporary directory for every job.
- Uses a separate LibreOffice profile directory for every conversion.
- Deletes temporary files after each job.
- Logs errors to stdout/stderr for
journalctl. - Preserves the original document name when sending the resulting PDF.
- Open Telegram and find
@BotFather. - Send
/newbot. - Choose a display name.
- Choose a username ending with
bot. - Copy the token and store it in
.envon your server.
Do not publish the token in GitHub, chats, logs, or README files.
sudo apt update
sudo apt install -y python3 python3-venv python3-pip libreoffice libreoffice-writer fonts-dejavu fonts-liberation fonts-crosextra-carlito fonts-crosextra-caladea fontconfig
fc-cache -f -vlibreoffice-writer is required for Word document conversion. Fonts matter for PDF quality: if the server does not have the fonts used by the document, LibreOffice will substitute similar fonts, and the layout may differ from the original.
cd /opt/docx-pdf-bot
python3 -m venv venv/opt/docx-pdf-bot/venv/bin/pip install --upgrade pip
/opt/docx-pdf-bot/venv/bin/pip install -r requirements.txtcp .env.example .env
nano .envThe file must contain:
BOT_TOKEN=123456789:your_real_bot_token.env is listed in .gitignore and must not be committed.
cd /opt/docx-pdf-bot
/opt/docx-pdf-bot/venv/bin/python bot.pyAfter startup, send the bot a DOC or DOCX file up to 20 MB. The bot should reply in Russian: Файл принят, конвертирую в PDF…, then send the PDF.
Copy the project to /opt/docx-pdf-bot, then install the unit:
sudo cp /opt/docx-pdf-bot/systemd/docx-pdf-bot.service /etc/systemd/system/docx-pdf-bot.service
sudo systemctl daemon-reload
sudo systemctl enable docx-pdf-bot
sudo systemctl start docx-pdf-botCheck status:
sudo systemctl status docx-pdf-botjournalctl -u docx-pdf-bot -fIf conversion fails, LibreOffice diagnostics and Python tracebacks will be visible in the logs.
LibreOffice converts most DOCX files well and can also handle many legacy DOC files, but the result can differ from Microsoft Word. Legacy .doc files are usually less predictable than .docx. Common causes:
- the document uses fonts missing on the server;
- the document contains complex tables, floating elements, SmartArt, macros, or unusual page settings;
- the document is damaged or was created by a partially compatible editor;
- the document contains external links or embedded objects LibreOffice cannot process correctly.
For important templates, test real documents and install the required fonts on the server when needed.
Word documents often store font names without embedding the font files themselves. If the server does not have a required font, LibreOffice substitutes another one. That can change line breaks, table sizes, page numbers, and the overall PDF layout.
The minimal font set above covers many common documents. Corporate templates may require additional licensed fonts.
LibreOffice headless can consume significant CPU and RAM. On a 2 GB RAM VPS, parallel conversions can cause stalls, OOM killer events, and unstable results. The bot therefore uses a queue but starts only one conversion process at a time.
sudo mkdir -p /opt/docx-pdf-bot
sudo chown "$USER":"$USER" /opt/docx-pdf-bot
git clone <your-repo-url> /opt/docx-pdf-bot
cd /opt/docx-pdf-bot
python3 -m venv venv
/opt/docx-pdf-bot/venv/bin/pip install --upgrade pip
/opt/docx-pdf-bot/venv/bin/pip install -r requirements.txt
cp .env.example .env
nano .env
sudo cp systemd/docx-pdf-bot.service /etc/systemd/system/docx-pdf-bot.service
sudo systemctl daemon-reload
sudo systemctl enable --now docx-pdf-bot