Skip to main content

Manage Paperless-NGX documents via Telegram bot. Upload, search, download, and organize.

Project description

paperless-telegram-bot banner

Manage Paperless-NGX documents entirely through Telegram.

Docker Build Tests Docker Pulls PyPI License Python 3.11+


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 -- /inbox lists 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 -- /recent shows the latest documents added to your archive.
  • System Statistics -- /stats displays document counts, tag usage, and storage information.
  • Health Endpoint -- Built-in /health HTTP 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:latest

Docker Compose

services:
  paperless-telegram-bot:
    image: drumsergio/paperless-telegram-bot:latest
    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 -r requirements.txt
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 No (open) Comma-separated Telegram user IDs allowed to use the bot
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
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
LOG_LEVEL No INFO Logging level (DEBUG, INFO, WARNING, ERROR)
HEALTH_PORT No 8080 Port for the /health HTTP endpoint

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-bot with httpx for 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_data to 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_tag field 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_USERS to restrict access. When empty, the bot accepts messages from anyone (not recommended for production).
  • Non-root container -- The Docker image runs as an unprivileged paperlessbot user (UID 1000).
  • No secrets in code -- All credentials are loaded from environment variables. Never commit .env files.
  • 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

More Telegram Tools

Project Description
Telegram-Archive Automated incremental Telegram backups with local web viewer
AskePub Telegram bot for ePub annotation with GPT-4
telegram-delay-channel-cloner Relay messages between channels with configurable delay
jellyfin-telegram-channel-sync Sync Jellyfin access with Telegram channel membership
telegram-slskd-local-bot Automated music discovery and download via Telegram

Contributing

Contributions are welcome. Please:

  1. Fork the repository
  2. Create a feature branch (feat/my-feature or fix/my-bug)
  3. Follow the existing code style (enforced by ruff)
  4. Add tests for new functionality
  5. Submit a pull request

This project follows Conventional Commits and Semantic Versioning.

License

This project is licensed under the GNU General Public License v3.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

paperless_telegram_bot-0.6.0.tar.gz (22.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

paperless_telegram_bot-0.6.0-py3-none-any.whl (20.9 kB view details)

Uploaded Python 3

File details

Details for the file paperless_telegram_bot-0.6.0.tar.gz.

File metadata

  • Download URL: paperless_telegram_bot-0.6.0.tar.gz
  • Upload date:
  • Size: 22.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for paperless_telegram_bot-0.6.0.tar.gz
Algorithm Hash digest
SHA256 8b78e017726574b280931e98e717516afc27565594a0579db1141f04ee956732
MD5 9cdd742d191ceb3eafd62f16f281c55e
BLAKE2b-256 771d0fb6e27a3db0f7a59b5ce259233cbde593a60e963cfa3bfa123e7cdaa4e9

See more details on using hashes here.

File details

Details for the file paperless_telegram_bot-0.6.0-py3-none-any.whl.

File metadata

File hashes

Hashes for paperless_telegram_bot-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c536c874865a5e68d3361d43009d6bd9ff51a9a085a1b1c9f51fe535827a88f7
MD5 311e3870566fc2bfb0b33b2042433df1
BLAKE2b-256 c278aee8a69fbf7d77bf8be1d4d375c6acfb5e80b89d616f65ecd9c8dd3b50d9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page