Skip to content

Instantly share code, notes, and snippets.

@DeNcHiK3713
Forked from PolarNick239/printerbot.py
Last active May 1, 2026 17:33
Show Gist options
  • Select an option

  • Save DeNcHiK3713/0c0f0b889056d63f0ee56dc1dd2b4c35 to your computer and use it in GitHub Desktop.

Select an option

Save DeNcHiK3713/0c0f0b889056d63f0ee56dc1dd2b4c35 to your computer and use it in GitHub Desktop.
Telegram bot for printer (Linux)
import os
import pathlib
import logging
import json
from telegram import Update
from telegram.ext import (
ApplicationBuilder,
CommandHandler,
Defaults,
MessageHandler,
ContextTypes,
filters,
)
# This is the Telegram Bot that prints all input documents. It can print pdf and txt files.
# Before sending files for printing user must enter the password by command "/auth <password>".
# This implementation uses "lp -d <printer> <file>" to print files (see function "print_file").
# To adopt this for Windows - extend print_file function with something like https://stackoverflow.com/questions/4498099/silent-printing-of-a-pdf-in-python
# TODO: Set here printer name (Choose one from output of command 'lpstat -p'):
printer_name = "PRINTER_NAME"
# TODO: Set here your bot's token key (from Telegram BotFather)
token_key = "239239239:UNICORNSUNICORNSUNICORNSUNICORNS239"
password = "password"
file_size_limit = 20 * 1024 * 1024
auth_file = "authorized_chats.json"
# Directory where files for printing should be saved
files_dir = "printed_files"
pathlib.Path(files_dir).mkdir(parents=True, exist_ok=True)
# Configuring logging
logging.basicConfig(
format="%(asctime)s [%(levelname)s] %(message)s",
level=logging.INFO,
)
# set higher logging level for httpx to avoid all GET and POST requests being logged
logging.getLogger("httpx").setLevel(logging.WARNING)
logger = logging.getLogger(__name__)
authorized_chats = set()
def system_print(file_path):
os.system(f'lp -d {printer_name} "{file_path}"')
def load_authorized_chats():
global authorized_chats
try:
with open(auth_file, "r") as f:
authorized_chats = set(json.load(f))
logger.info("Authorized chats loaded.")
except FileNotFoundError:
authorized_chats = set()
logger.info("No authorized chats file found.")
def save_authorized_chats():
with open(auth_file, "w") as f:
json.dump(list(authorized_chats), f)
def auth_passed(update: Update):
return update.effective_chat.id in authorized_chats
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
logger.info(f"User {update.effective_user.username} started")
await update.message.reply_text(
"I'm a printer bot!\n"
"Authorize with /auth <password> to print files."
)
async def authorize(update: Update, context: ContextTypes.DEFAULT_TYPE):
args = ''.join(context.args)
if auth_passed(update):
await update.message.reply_text("Already authorized!")
return
if password == args:
authorized_chats.add(update.effective_chat.id)
save_authorized_chats()
logger.info(f"{update.effective_user.username} authorized")
await update.message.reply_text("Authorized successfully!")
else:
logger.warning(f"Wrong password from {update.effective_user.username}: {args}")
await update.message.reply_text("Wrong password!")
async def handle_document(update: Update, context: ContextTypes.DEFAULT_TYPE):
if not auth_passed(update):
await update.message.reply_text("Use /auth <password> first.")
return
doc = update.message.document
file_name = doc.file_name
file_size = doc.file_size
if file_size > file_size_limit:
await update.message.reply_text("File too large!")
return
await update.message.reply_text("Downloading...")
file = await context.bot.get_file(doc.file_id)
file_path = os.path.join(files_dir, file_name)
logger.info(f"Downloading {file_name}...")
await file.download_to_drive(file_path)
logger.info(f"Printing {file_path}...")
system_print(file_path)
await update.message.reply_text("Printed!")
def main():
load_authorized_chats()
app = ApplicationBuilder().token(token_key).defaults(Defaults(do_quote=True)).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("auth", authorize))
app.add_handler(MessageHandler(filters.Document.ALL, handle_document))
logger.info("Bot started...")
app.run_polling()
if __name__ == "__main__":
main()
@DeNcHiK3713

Copy link
Copy Markdown
Author

Updated to python-telegram-bot v22.7
Authorized chats are now saved after restart.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment