Converting Images to PDF with your own Python Telegram Bot

Converting Images to PDF with your own Python Telegram Bot

Building a Telegram Bot with Python: Image to PDF Converter

Image-to-PDF conversion can be useful when you need to bundle up several images into a single file. With the help of the Python programming language and the img2pdf library, it's possible to automate this task and even create a Telegram bot that converts images to PDFs on-the-fly.

In this tutorial, we will leverage the img2pdf library to convert an image sent via Telegram by a user to a PDF file and then send it back to the user. We will also show how to handle basic messages received by the bot and respond accordingly.

Prerequisites

To follow along with this tutorial, you should have the following installed on your machine:

  • Python 3.6 or higher

  • img2pdf library (can be installed using pip install img2pdf)

  • requests library (can be installed using pip install requests)

  • python-dotenv library (can be installed using pip install python-dotenv)

  • A Telegram account

  • The Telegram app for desktop or mobile

Setting Up Your Environment

Before we get to the code, let's set up our development environment. The first step is to install the required libraries. To do so, open your terminal or command prompt and run:

pip install python-dotenv requests img2pdf python-telegram-bot

This installs the required libraries for our project.

Setting up a new Telegram Bot

To create a new bot on Telegram, you will need to follow these steps:

  1. Open the Telegram app and search for the @BotFather bot.

  2. Start a chat with @BotFather and type the command /newbot.

  3. Follow the instructions to set a name and username for your bot.

  4. Once your bot is created, @BotFather will give you a token. Save this token somewhere safe, as you will need it later.

The Python Code

Let's start by importing the required libraries: os, dotenv, requests, img2pdf, and python-telegram-bot. The first four libraries are used to download and manipulate the image file, while the last is used to create and manage the Telegram bot.

import os
import dotenv
import requests
import img2pdf
from typing import Final
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes

We then load the environment variables from a .env file using the dotenv library. This file should contain your bot's API token.

dotenv.load_dotenv()
TOKEN: Final = os.getenv('TOKEN')

We also define the bot's username, which will be used to filter messages directed at our bot.

BOT_USERNAME: Final = '@image_to_pdfs_bot'

We then define some helper functions that handle different types of messages received by the bot.

The start_command function simply sends a greeting message to the user when they send the /start command using bot.

async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text('Hello there! I\'m a bot that converts image to pdf. What\'s up?')

The help_command function sends a message to the user explaining how to use the bot when the user selects /help command from bot menu.

async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text('Just upload an image and i will convert it to PDF format')

Lastly, we have the convert_to_pdf function, which handles image files sent by the user. It downloads the image file, converts it to PDF, and sends it back to the user.

async def convert_to_pdf(update:Update, context:ContextTypes.DEFAULT_TYPE):
    """Convert the image sent by the user to PDF and send it back."""
    # Get the photo file and file_id from the message sent by the user
    photo = update.message.photo[-1].file_id

    recieved_file =await context.bot.get_file(photo)
    path = recieved_file.file_path

    # Download the image file
    image_file =requests.get(path).content
    with open('image.jpg', 'wb') as f:
        f.write(image_file)

    # Convert the image to PDF
    with open('image.pdf', 'wb') as f:
        f.write(img2pdf.convert('image.jpg'))

    # Send the PDF file to the user
    await context.bot.send_document(chat_id=update.message.chat_id, document=open('image.pdf', 'rb'))

    # Clean up the temporary files
    os.remove('image.jpg')
    os.remove('image.pdf')

We also define a handle_response function to handle basic messages received by the bot. This function simply returns a response based on the message text.

def handle_response(text: str,update:Update) -> str:
    processed: str = text.lower()

    if 'hi' in processed:
        return f'Hi {update.message.chat.first_name.lower()} How are you'

    if 'how are you' in processed:
        return 'I\'m good!'

    return 'Sorry I don\'t understand'

Lastly, we have the handle_message function, which handles all messages received by the bot.

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
    # Get basic info of the incoming message
    message_type: str = update.message.chat.type
    text: str = update.message.text
    # React to group messages only if users mention the bot directly
    if message_type == 'group':
        # Replace with your bot username
        if BOT_USERNAME in text:
            new_text: str = text.replace(BOT_USERNAME, '').strip()
            response: str = handle_response(new_text,update)
        else:
            return  # We don't want the bot respond if it's not mentioned in the group
    else:
        response: str = handle_response(text,update)
    # Reply normal if the message is in private
    await update.message.reply_text(response)

Logging errors

We can have an error handling function to log the errors for debugging

# Log errors
async def error(update: Update, context: ContextTypes.DEFAULT_TYPE):
    print(f'Update {update} caused error {context.error}')

Handling Incoming Messages

Our bot will need to be able to handle incoming messages from users. The python-telegram-bot package provides several types of message handlers that we can use to accomplish this. In this tutorial, we'll focus on two types: CommandHandler and MessageHandler.

CommandHandler

A CommandHandler is a type of message handler that responds to bot commands. Commands are special messages that start with a forward slash ("/") and are followed by a keyword. For example, the command "/start" is a common command that many bots support.

MessageHandler

A MessageHandler is a type of message handler that responds to regular messages sent by users. This is the type of handler we'll be using to handle text messages and photos.

# Run the program
if __name__ == '__main__':
    app = Application.builder().token(TOKEN).build()

    # Commands
    app.add_handler(CommandHandler('start', start_command))
    app.add_handler(CommandHandler('help', help_command))

    # To handle Messages inputs
    app.add_handler(MessageHandler(filters.TEXT, handle_message))
    # To handle Picture inputs
    app.add_handler(MessageHandler(filters.PHOTO,convert_to_pdf))

    # Log all errors
    app.add_error_handler(error)

    print('Polling...')
    # Run the bot
    app.run_polling(poll_interval=5)

Make sure you run the above Python script in order to get your bot up and running.
To make the bot available 24/7 prefer an online hosting service to run your scripts on the cloud.

Feel free to ping me at sailokeshreddyg@gmail for the GitHub link for the above same code.

Did you find this article valuable?

Support Sai Lokesh Reddy by becoming a sponsor. Any amount is appreciated!