Manage Paperless-NGX documents entirely through Telegram.
A full-featured Telegram bot that integrates with Paperless-NGX, giving you complete document management from your phone or desktop -- no web UI required. Upload documents and photos, search your archive with full-text search, manage metadata, review your inbox, and download files, all within Telegram.
Features
- Document Upload -- Send any file or photo to the bot and it gets uploaded to Paperless-NGX automatically. Duplicates are detected and linked.
- Full-Text Search -- Search across all your documents with
/search. Results are paginated with inline keyboard navigation. - Metadata Management -- After uploading (or on any document), assign tags, correspondents, and document types through interactive inline keyboards.
- Inbox Review --
/inboxlists all documents tagged with your inbox tag. Mark them as reviewed with a single tap. - Document Download -- Download original files directly to Telegram (up to 50 MB).
- Recent Documents --
/recentshows the latest documents added to your archive. - System Statistics --
/statsdisplays document counts, tag usage, and storage information. - Health Endpoint -- Built-in
/healthHTTP endpoint for Docker health checks and monitoring. - User Authorization -- Restrict bot access to specific Telegram user IDs via allowlist.
- Non-Root Docker -- Runs as an unprivileged user inside the container.
Quick Start
Docker (Recommended)
docker run -d \
--name paperless-telegram-bot \
--restart unless-stopped \
-e TELEGRAM_BOT_TOKEN=your_bot_token \
-e PAPERLESS_URL=http://your-paperless:8000 \
-e PAPERLESS_TOKEN=your_api_token \
-e TELEGRAM_ALLOWED_USERS=123456789 \
drumsergio/paperless-telegram-bot:v0.7.0
Docker Compose
services:
paperless-telegram-bot:
image: drumsergio/paperless-telegram-bot:v0.7.0
container_name: paperless-telegram-bot
restart: unless-stopped
environment:
TELEGRAM_BOT_TOKEN: "${TELEGRAM_BOT_TOKEN}"
PAPERLESS_URL: "http://paperless:8000"
PAPERLESS_TOKEN: "${PAPERLESS_TOKEN}"
TELEGRAM_ALLOWED_USERS: "${TELEGRAM_ALLOWED_USERS}"
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8080/health')"]
interval: 30s
timeout: 5s
retries: 3
Manual Installation
git clone https://github.com/GeiserX/paperless-telegram-bot.git
cd paperless-telegram-bot
python -m venv .venv && source .venv/bin/activate
pip install -e .
cp .env.example .env # Edit with your values
python -m paperless_bot run
Configuration
All configuration is done through environment variables. Copy .env.example to .env for local development.
| Variable | Required | Default | Description |
|---|---|---|---|
TELEGRAM_BOT_TOKEN |
Yes | -- | Telegram Bot API token from @BotFather |
PAPERLESS_URL |
Yes | -- | Paperless-NGX instance URL (e.g. http://localhost:8000) |
PAPERLESS_TOKEN |
Yes | -- | Paperless-NGX API authentication token |
TELEGRAM_ALLOWED_USERS |
Yes* | -- | Comma-separated Telegram user IDs allowed to use the bot. *Required unless ALLOW_OPEN_ACCESS=true; an empty allowlist refuses to start |
ALLOW_OPEN_ACCESS |
No | false |
Explicit opt-in to run without an allowlist (open to any Telegram user) |
PAPERLESS_PUBLIC_URL |
No | PAPERLESS_URL |
User-facing URL for clickable document links |
MAX_SEARCH_RESULTS |
No | 10 |
Number of results per page in search, recent, and inbox |
UPLOAD_TASK_TIMEOUT |
No | 300 |
Seconds to wait for Paperless to finish processing an upload (increase if slow tasks such as mail checks block the consume queue) |
REMOVE_INBOX_ON_DONE |
No | true |
Remove inbox tag when clicking "Done" in metadata flow |
INBOX_TAG |
No | (auto-detect) | Explicit inbox tag name. If unset, auto-detects via Paperless API |
DROP_PENDING_UPDATES |
No | false |
Discard Telegram updates that arrived while the bot was down instead of processing them on startup |
LOG_LEVEL |
No | INFO |
Logging level (DEBUG, INFO, WARNING, ERROR) |
HEALTH_PORT |
No | 8080 |
Port for the /health HTTP endpoint (returns 503 degraded when Paperless is unreachable) |
Compatible with Paperless-NGX 2.x and 3.x (both task-API response formats are handled).
Commands
| Command | Description |
|---|---|
/search <query> |
Full-text search across all documents |
/recent |
Show recently added documents |
/inbox |
List documents in the inbox with review actions |
/stats |
Display Paperless-NGX statistics |
/help |
Show available commands and usage |
In addition to commands, you can send any file or photo directly to the bot to upload it to Paperless-NGX. After upload, an interactive keyboard lets you assign tags, a correspondent, and a document type.
Architecture
paperless-telegram-bot
|-- src/paperless_bot/
| |-- __main__.py # Entry point, health server, CLI
| |-- config.py # Environment variable loading and validation
| |-- api/
| | +-- client.py # Async Paperless-NGX API client with caching
| +-- bot/
| |-- handlers.py # Command handlers, callback routing, upload flow
| +-- keyboards.py # Inline keyboard builders for metadata selection
+-- tests/ # pytest + respx test suite
Key design decisions:
- Async throughout -- Uses
python-telegram-botwithhttpxfor fully asynchronous I/O. - Metadata caching -- Tags, correspondents, and document types are cached in memory and refreshed on demand, minimizing API calls.
- Callback data encoding -- Telegram limits
callback_datato 64 bytes. All prefixes are kept short (meta:tags:,dl:,sp:, etc.) and long search queries are stored server-side per chat. - Inbox auto-detection -- The bot reads the
is_inbox_tagfield from the Paperless API rather than matching by name, so it works with any language or custom tag name. - Duplicate handling -- Upload failures containing "duplicate" are parsed to extract and link to the existing document.
Security
- User allowlist -- Set
TELEGRAM_ALLOWED_USERSto restrict access. An empty allowlist refuses to start unlessALLOW_OPEN_ACCESS=trueis set explicitly (running open is not recommended). - Non-root container -- The Docker image runs as an unprivileged
paperlessbotuser (UID 1000). - No secrets in code -- All credentials are loaded from environment variables. Never commit
.envfiles. - API token scoping -- The bot uses a single Paperless-NGX API token. Create a dedicated user/token with appropriate permissions.
Development
# Install dev dependencies
pip install -e ".[dev]"
# Run linter and formatter
ruff check src/ && ruff format src/
# Run tests
python -m pytest tests/ -v
# Run tests with coverage
python -m pytest tests/ --cov=paperless_bot --cov-report=term-missing
Contributing
Contributions are welcome. Please:
- Fork the repository
- Create a feature branch (
feat/my-featureorfix/my-bug) - Follow the existing code style (enforced by
ruff) - Add tests for new functionality
- Submit a pull request
This project follows Conventional Commits and Semantic Versioning.
Related Projects
| Project | Description |
|---|---|
| Telegram-Archive | Automated, incremental Telegram backups with a local web viewer |
| telegram-delay-channel-cloner | Telegram bot that relays messages between channels with configurable delay |
| telegram-slskd-local-bot | Automated music discovery and download via Telegram bot with Soulseek |
| AskePub | Telegram bot for ePub annotation with GPT-4 |
| jellyfin-telegram-channel-sync | Sync Jellyfin access with Telegram channel membership |
| telegram-archive-mcp | MCP Server for Telegram-Archive |
| n8n-nodes-telegram-archive | n8n community node for Telegram-Archive |
License
This project is licensed under the GNU General Public License v3.0.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file paperless_telegram_bot-0.7.0.tar.gz.
File metadata
- Download URL: paperless_telegram_bot-0.7.0.tar.gz
- Upload date:
- Size: 38.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
118c55ffda631ca7332d82e6fd790781ff704f21318c7607484e3659a4370b33
|
|
| MD5 |
93addf5f2ebd2a9367fa9e69456caaaa
|
|
| BLAKE2b-256 |
7b362b6969893b3eeafb42c0293c5c86e7dd6664f79209be3e5af9c08700a68b
|
File details
Details for the file paperless_telegram_bot-0.7.0-py3-none-any.whl.
File metadata
- Download URL: paperless_telegram_bot-0.7.0-py3-none-any.whl
- Upload date:
- Size: 22.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
03a3d4871e6cac617b25930cfdbd55d68553ec27c80204d7b4b00603eef9a5b3
|
|
| MD5 |
b82bdf24f70771b1b455ef389a374dc2
|
|
| BLAKE2b-256 |
f84f7070c8766199b28fe2cd141182909a0b61f2946c31bf237dee21569e6ed1
|