Skip to content

justpresident/telegram_printer_bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Telegram printer bot

CI Coverage

This is a simple bot that allows you to print on your home printer from anywhere from any device that has a telegram client. It also exposes some basic printer diagnostics and print job management. In order to print something, just upload a file without any commands. A lot of formats are supported.

When you send a file, the bot replies with a first-page preview and an interactive print-options panel. Tap the buttons to adjust how it prints, then press Print. After printing, the message keeps you posted on the job's progress and offers a Cancel button.

Commands:

  • /start - Starts interaction and prints current state
  • /auth <password> - Authenticates the user with a password against the password stored in the auth_password file
  • /settings - Edit the per-printer default print options (see below)
  • /pending - Lists all pending print jobs
  • /completed - Lists last 10 completed print jobs
  • /cancel <job_id> - Cancels a pending job with a given id

The full command list is also registered with Telegram, so it shows up in the / autocomplete menu.

Print options

Both the per-file panel and /settings expose the same controls (translated to CUPS lp options). Copies use a ➖ / ➕ stepper; the rest are tap-to-expand selectors (marked ) — tapping one shows all of its choices (current marked 🔘), and tapping a choice selects it and returns to the panel:

  • Copies➖ / ➕ stepper
  • Sides — single-sided / double-sided (long or short edge)
  • Color — color / grayscale
  • Paper size — A4 / Letter / Legal / A3
  • Pages per sheet — 1 / 2 / 4 / 6 (N-up)
  • Page range — type e.g. 2-5 or 1,3,5, or all
  • Printer — when more than one CUPS printer is available, pick the target (or "System default")

Per-printer defaults

Saved defaults are kept per printer, not per user — each printer (and "System default") has its own remembered options, since e.g. a duplex laser and a single-sided photo printer want different settings. /settings opens the defaults for your system-default printer; pick a different printer in the panel to edit its defaults instead. When you send a file it's seeded with the default printer's saved options, and choosing a different printer in the per-file panel loads that printer's defaults too (keeping the copies and page range you picked for the document).

Dry run

/settings also has a 🧪 Dry run toggle. When it's on, sending a file (or pressing Print) logs the exact lp command that would run, to printerbot.log, and reports back that nothing was printed — useful for testing the bot without wasting paper. Like the other options it's saved per printer, so it applies to every file printed to that printer until you turn it off.

Details

  • Password authentication; authorized users are persisted across restarts (in state.json)
  • Per-printer default print settings are persisted in the same state.json
  • Uses libreoffice to convert files to PDF format before printing
  • Uses pdftoppm (poppler) to render the first-page preview
  • Uses lp (CUPS) to send a file to the printer with the chosen options, and lpstat/cancel for status and cancellation
  • Uses the python-telegram-bot package to interface with the Telegram API

Architecture

The code is a small printerbot/ package, split into single-responsibility modules, each collaborator behind an interface so it can be swapped or tested in isolation:

Module Responsibility
domain.py Plain data types — PrintOptions, PrintResult, JobState, enums
commands.py CommandRunner — the single seam for external commands (no shell, captures output)
storage.py StateStore — persistent key/value store with atomic update() (JsonFileStore / InMemoryStateStore)
interfaces.py Abstract PrinterInterface, FileProcessorInterface, AuthManagerInterface, PrinterSettingsStoreInterface
adapters.py SystemPrinter (CUPS), LibreOfficeFileProcessor, auth + settings stores
service.py PrinterBotService — backend-agnostic business logic
ui.py Pure keyboard/option logic (build_options_keyboard, apply_option_action) — unit-tested without Telegram
bot.py TelegramPrinterBot — Telegram I/O; offloads blocking work off the event loop
app.py setup_logging + main wiring

printerbot/__init__.py re-exports the public API, so from printerbot import … works from anywhere.

Install Dependencies

  • Python 3.11+ and the python-telegram-bot package: pip3 install python-telegram-bot
  • LibreOffice and poppler-utils (pdftoppm, pdfinfo). Install with your package manager, e.g. apt install libreoffice poppler-utils
  • CUPS, with at least one configured printer (lp, lpstat, cancel)

Running the bot

Put your bot token in ./token and the shared password in ./auth_password, then run from the project directory:

python3 -m printerbot      # or: make run

Installing as a service

The included Makefile renders printerbot.service.in for this checkout — its directory, your user, and the active python3 — so nothing is hardcoded. Run it from the directory you want the bot to live in:

make install          # per-user service (systemctl --user), runs as you, no root

This installs the unit to ~/.config/systemd/user/, starts it, and enables lingering so it keeps running after you log out. Follow logs with journalctl --user -u printerbot.service -f, and remove it with make uninstall.

Prefer a system-wide service (starts at boot independent of any login)?

make install-system   # installs to /etc/systemd/system with User=<you> (uses sudo)

make print-unit shows the rendered unit without installing anything; make help lists all targets.

Running the tests

pip3 install pytest pytest-asyncio
python3 -m pytest tests.py -v

To measure coverage (as CI does):

pip3 install pytest-cov
python3 -m pytest tests.py --cov=printerbot --cov-report=term-missing

About

Printer Bot for telegram

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages