Telegram Bot /multiple Command Not Working as Expected

114 Views Asked by At

problem :-

I'm currently working on a Telegram bot using the Telepot library in Python, and I've implemented a /multiple command to allow users to input multiple URLs at once. However, I've encountered an issue where the /multiple command doesn't seem to work as expected. I would appreciate some guidance on resolving this problem

Description

I've added a /multiple command to my Telegram bot, which should allow users to enter multiple URLs at once, separated by a space. Here's the relevant code snippet:

# Handling the /multiple command
def input_multiple(update: Update) -> int:
    chat_id = update['chat']['id']
    user_input = update['text']

    # Check if the input contains links separated by a single space
    links_list = user_input.strip().split(" ")

    if len(links_list) > 25:
        bot.sendMessage(chat_id, "You can only add up to 25 links at a time. Please try again.")
    else:
        valid_links = [link for link in links_list if is_valid_url(link)]

        if valid_links:
            with open("links.txt", "w") as links_file:
                links_file.write("\n".join(valid_links))
            bot.sendMessage(chat_id, f'Links are added:\n' + '\n'.join(valid_links))
            bot.sendMessage(chat_id, "To stop adding links and proceed, type /generate_links or /generate_qr.\n"
                                     "To cancel the operation, type /cancel.")
        else:
            bot.sendMessage(chat_id, "No valid URLs found in your input. Please enter valid URLs.")

    return INPUT_LINKS

The expected behavior is that users should be able to input URLs in the format "https://link_1 https://link_2 https://link_3" and have them added to a list. However, it appears that the /multiple command is not working as intended, and I'm not sure why.

What I've Tried

I've already checked my code for potential issues, and I can confirm that the input is reaching the input_multiple function. However, I'm not getting the expected output when I input multiple URLs. Additionally, I'm receiving error messages in my bot's responses that input urls in specified format even if send it in that specified format.

Expected Outcome:

I expect the /multiple command to allow users to input multiple URLs in the specified format, and I want these URLs to be added to a list for further processing. If any invalid URLs are included, I want to display an error message to the user.

example if user send links like this :- "https://link1https://link2https://link3" even in this case also the code should get links_list like this :- ['link1','link2','link3']

Here is the entire code if you want :-

import os
import re
import subprocess
import telepot
from telepot.loop import MessageLoop
from telepot.namedtuple import Update
import validators

# Define states for conversation
INPUT_LINKS, INPUT_MULTIPLE_LINKS = range(2)

# Store user's input links
user_links = {}

# Function to start the conversation
def start(update: Update) -> int:
    chat_id = update['chat']['id']
    user_links[chat_id] = []  # Initialize/clear user's links list
    bot.sendMessage(chat_id,
                    "Hi! I'm your URL Bot. Send me a long URL, and I will help you generate a shortened link or QR code."
                    "\n\nJust send me the long URL you want to shrink."
                    "\nType /cancel to stop."
                    "\nType /help for instructions.")
    return INPUT_LINKS

# Function to handle user input links
def input_links(update: Update) -> int:
    user_input = update['text']
    chat_id = update['chat']['id']

    if chat_id not in user_links:
        user_links[chat_id] = []

    if user_input.lower() == '/generate_links' or user_input.lower() == '/generate_qr':
        return choose_action(update)
    elif user_input.lower() == '/cancel':
        return cancel(update)
    elif user_input.lower() == '/help':
        show_help(update)
    elif user_input.lower() == '/start':
        bot.sendMessage(chat_id,
            "Hi! I'm your URL Bot. Send me a long URL, and I will help you generate a shortened link or QR code."
            "\n\nJust send me the long URL you want to shrink."
            "\nType /cancel to stop."
            "\nType /help for instructions.")
    elif user_input.lower() == '/multiple':
        bot.sendMessage(chat_id,
            "You can enter multiple URLs (up to a 25 links limit) at once by providing them in the following format :\n"
            "https://link_1 https://link_2 https://link_3\n\n"
            "Please enter the URLs separated by one space.")
        return INPUT_MULTIPLE_LINKS  # Switch to the INPUT_MULTIPLE_LINKS state
    elif not user_input.startswith('/'):
        if is_valid_url(user_input):
            user_links[chat_id].append(user_input)
            bot.sendMessage(chat_id,
                            f'Added link: {user_input}\n\n'
                            f'To stop adding links and proceed, type /generate_links or /generate_qr.\n'
                            f'To add more links at once, type /multiple.\n'
                            f'To cancel the operation, type /cancel.\n'
                            f'To see help, type /help.')
        else:
            bot.sendMessage(chat_id, "Invalid URL. Please enter a valid URL.")

    return INPUT_LINKS


# Function to handle /multiple command
def input_multiple(update: Update) -> int:
    chat_id = update['chat']['id']
    user_input = update['text']

    # Check if the input starts with / to avoid interference with input_links
    if user_input.startswith('/'):
        return INPUT_LINKS

    # Check if the input contains links separated by a single space
    links_list = user_input.strip().split(" ")

    if len(links_list) > 25:
        bot.sendMessage(chat_id, "You can only add up to 25 links at a time. Please try again.")
        return INPUT_LINKS

    # Save the links to a text file (links.txt)
    with open("links.txt", "w") as links_file:
        links_file.write("\n".join(links_list))

    bot.sendMessage(chat_id, f'Links are added:\n' + '\n'.join(links_list))
    bot.sendMessage(chat_id, "The links have been stored successfully.")

    return INPUT_MULTIPLE_LINKS

# Function to check if a URL is valid
def is_valid_url(url):
    if validators.url(url) or validators.domain(url):
        return True
    return False

# Function to choose the action (generate links or generate QR codes)
def choose_action(update: Update) -> int:
    user_choice = update['text'].lower()
    if user_choice == '/generate_links':
        generate_links(update)
    elif user_choice == '/generate_qr':
        generate_qr_codes(update)
    else:
        bot.sendMessage(update['chat']['id'], "Invalid command. Please type /generate_links or /generate_qr.")
    return INPUT_LINKS

# Function to generate links using PHP script
def generate_links(update: Update):
    chat_id = update['chat']['id']
    with open("links.txt", "w") as links_file:
        links_file.write("\n".join(user_links[chat_id]))
    try:
        subprocess.run(["php", "link_gen.php"], check=True, text=True)
        with open("babylinks.txt", "r") as baby_links_file:
            baby_links = baby_links_file.read()
        bot.sendMessage(chat_id, "Generated links:\n" + baby_links)
    except subprocess.CalledProcessError:
        bot.sendMessage(chat_id, "Error generating links.")

# Function to generate QR codes using PHP script
def generate_qr_codes(update: Update):
    chat_id = update['chat']['id']
    try:
        subprocess.run(["php", "qrgen.php"], check=True, text=True)
        with open("qrlinks.txt", "r") as qr_links_file:
            qr_links = qr_links_file.read()
        bot.sendMessage(chat_id, "Generated QR code links:\n" + qr_links)
    except subprocess.CalledProcessError:
        bot.sendMessage(chat_id, "Error generating QR code links.")

# Function to show help instructions
def show_help(update: Update):
    chat_id = update['chat']['id']
    help_message = "BABY-URL Bot Help:\n\n" \
                   "/start - Start the bot and send URLs.\n" \
                   "/generate_links - Generate shortened links using babyurl.\n" \
                   "/generate_qr - Generate QR codes using babyurl.\n" \
                   "/cancel - clear stored links and start new.\n" \
                   "/help - Show this help message."
    bot.sendMessage(chat_id, help_message)

# Function to handle /cancel command
def cancel(update: Update) -> int:
    chat_id = update['chat']['id']
    user_links[chat_id] = []  # Clear user's links list
    bot.sendMessage(chat_id, "Links are cleared. Send /start to begin again.")
    return INPUT_LINKS

# Initialize the Telegram Bot
bot = telepot.Bot("6493539478:AAHul1-k7dLPk1R05Pd5IFt7YGhsyBG_gR0")
MessageLoop(bot, {
    'chat': input_links,
    'text': input_multiple
}).run_as_thread()

print('Listening for messages...')

# Keep the bot running
while True:
    pass
0

There are 0 best solutions below