Telegram Userbot Pairing other users issue

Describe the problem/error/question

Please i am having issues creating a telegram userbot that users can pair with, i keep on getting incomplete login issues from telegram, please help me anyone

What is the error message (if any)?

Please share your workflow

import asyncio
from telegram import Update
from telegram.ext import (
    Application,
    CommandHandler,
    MessageHandler,
    ConversationHandler,
    filters,
    ContextTypes,
)
from telethon import TelegramClient
from telethon.errors import (
    FloodWaitError,
    SessionPasswordNeededError,
    PhoneCodeInvalidError,
    PhoneCodeExpiredError,
)
import logging

# Enable logging
logging.basicConfig(
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
)
logger = logging.getLogger(__name__)

# Hardcoded API credentials (from your spare account)
MY_API_ID = 31          # Replace with your actual API ID
MY_API_HASH = "87"   # Replace with your actual API hash

# Bot token
BOT_TOKEN = "8370zscnGw"

# Conversation states
API_ID, API_HASH, PHONE, CODE, PASSWORD = range(5)

# In-memory storage for user data (user_id -> state dict)
user_data = {}

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
    """Start conversation, ask for API ID."""
    user_id = update.effective_user.id
    user_data[user_id] = {}  # Initialize user data
    await update.message.reply_text(
        "Welcome! To pair your account, please enter the API ID (the one from my spare account):"
    )
    return API_ID

async def api_id_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
    """Check API ID, ask for API hash."""
    user_id = update.effective_user.id
    text = update.message.text.strip()

    if text != str(MY_API_ID):
        await update.message.reply_text(
            "Invalid API ID. Please try again, or /cancel to abort."
        )
        return API_ID  # stay in same state

    user_data[user_id]["api_id"] = int(text)
    await update.message.reply_text("Correct. Now enter the API hash:")
    return API_HASH

async def api_hash_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
    """Check API hash, ask for phone number."""
    user_id = update.effective_user.id
    text = update.message.text.strip()

    if text != MY_API_HASH:
        await update.message.reply_text(
            "Invalid API hash. Please try again, or /cancel."
        )
        return API_HASH

    user_data[user_id]["api_hash"] = text
    await update.message.reply_text(
        "API hash accepted. Now send me your phone number (international format, e.g., +1234567890):"
    )
    return PHONE

async def phone_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
    """Store phone, create Telethon client and request login code."""
    user_id = update.effective_user.id
    phone = update.message.text.strip()

    # Basic phone format check
    if not phone.startswith("+") or not phone[1:].isdigit():
        await update.message.reply_text(
            "Please enter a valid phone number with country code, e.g., +1234567890."
        )
        return PHONE

    user_data[user_id]["phone"] = phone

    # Create Telethon client (in‑memory session)
    client = TelegramClient(None, user_data[user_id]["api_id"], user_data[user_id]["api_hash"])
    user_data[user_id]["client"] = client

    try:
        await client.connect()
        # Send code request
        await client.send_code_request(phone)
        await update.message.reply_text(
            "A verification code has been sent to your Telegram app. Please enter it:"
        )
        return CODE
    except FloodWaitError as e:
        await update.message.reply_text(f"Too many attempts. Please wait {e.seconds} seconds.")
        await client.disconnect()
        del user_data[user_id]
        return ConversationHandler.END
        await client.disconnect()
        del user_data[user_id]
        return ConversationHandler.END
    except Exception as e:
        logger.exception("Unexpected error during code request")
        await update.message.reply_text("An error occurred. Please try again later.")
        await client.disconnect()
        del user_data[user_id]
        return ConversationHandler.END

async def code_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
    """Verify the code, handle 2FA if needed."""
    user_id = update.effective_user.id
    code = update.message.text.strip()
    client = user_data[user_id].get("client")
    phone = user_data[user_id]["phone"]

    try:
        await client.sign_in(phone, code)
        # If no 2FA, sign_in succeeds
    except SessionPasswordNeededError:
        # 2FA is enabled
        await update.message.reply_text(
            "Two‑factor authentication is enabled. Please enter your password:"
        )
        return PASSWORD
    except PhoneCodeInvalidError:
        await update.message.reply_text("Invalid code. Please try again, or /cancel.")
        return CODE  # stay in CODE state
    except PhoneCodeExpiredError:
        await update.message.reply_text("Code expired. Please start over with /start.")
        await client.disconnect()
        del user_data[user_id]
        return ConversationHandler.END
    except Exception as e:
        logger.exception("Error during sign in")
        await update.message.reply_text("Login failed. Please try again later.")
        await client.disconnect()
        del user_data[user_id]
        return ConversationHandler.END
    else:
        # Success – no 2FA
        return await finalize_login(update, context)

async def password_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
    """Handle 2FA password and complete login."""
    user_id = update.effective_user.id
    password = update.message.text.strip()
    client = user_data[user_id]["client"]

    try:
        await client.sign_in(password=password)
    except Exception as e:
        logger.exception("2FA password error")
        await update.message.reply_text("Incorrect password. Please try again, or /cancel.")
        return PASSWORD
    else:
        return await finalize_login(update, context)

async def finalize_login(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
    """Login successful: send test message and clean up."""
    user_id = update.effective_user.id
    client = user_data[user_id]["client"]

    try:
        # Send a test message from the userbot to the original user
        await client.send_message(user_id, "Working")
        await update.message.reply_text(
            "âś… Success! You should have received a 'Working' message from your own account."
        )
    except Exception as e:
        logger.exception("Failed to send test message")
        await update.message.reply_text(
            "Login succeeded, but the test message could not be sent. You may still be logged in."
        )
    finally:
        # Disconnect the client (we don't keep it running)
        await client.disconnect()
        del user_data[user_id]

    return ConversationHandler.END

async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
    """Cancel the conversation."""
    user_id = update.effective_user.id
    if user_id in user_data:
        client = user_data[user_id].get("client")
        if client:
            await client.disconnect()
        del user_data[user_id]
    await update.message.reply_text("Operation cancelled.")
    return ConversationHandler.END

def main() -> None:
    """Start the bot."""
    application = Application.builder().token(BOT_TOKEN).build()

    conv_handler = ConversationHandler(
        entry_points=[CommandHandler("start", start)],
        states={
            API_ID: [MessageHandler(filters.TEXT & ~filters.COMMAND, api_id_handler)],
            API_HASH: [MessageHandler(filters.TEXT & ~filters.COMMAND, api_hash_handler)],
            PHONE: [MessageHandler(filters.TEXT & ~filters.COMMAND, phone_handler)],
            CODE: [MessageHandler(filters.TEXT & ~filters.COMMAND, code_handler)],
            PASSWORD: [MessageHandler(filters.TEXT & ~filters.COMMAND, password_handler)],
        },
        fallbacks=[CommandHandler("cancel", cancel)],
    )

    application.add_handler(conv_handler)
    application.run_polling()

if __name__ == "__main__":
    main()

Share the output returned by the last node

Incomplete login attempt. Dear [ᗪΛ᙭] ╰Ɣ╯, Telegram blocked an attempt to log into your account from a new device on 13/02/2026 at 11:14:36 UTC.
Device: DAXai, 1.42.0, PC 64bit, Web, 11
Location: Lagos, Nigeria
Nobody gained access to your chats because the login was not completed. The code was entered correctly, but sign in was not allowed, because this code was previously shared by your account.
Please don’t share login codes with others, because they allow anyone to log in to your account and access your chats.

Information on your n8n setup

  • n8n version:
  • Database (default: SQLite):
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app):
  • Operating system:

Hi @Mikky_Rose

Telegram is blocking your request because you are getting a code from the app, sharing it with your bot, telegram detects the code is shared and blocks it. You could send a code like this -

First, your user prompt

await update.message.reply_text(
“A verification code has been sent to your Telegram app.\n\n”
“:warning: IMPORTANT: Do NOT paste the code directly.\n”
“Add spaces or dashes between each digit.\n\n”
“Example: If your code is 12345, send it as:\n”
“1 2 3 4 5 or 1-2-3-4-5\n\n”
“This prevents Telegram from blocking the login.”,
parse_mode=“Markdown”,
)

Then the seperators -

async def code_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) → int:“”“Verify the code, handle 2FA if needed.”“”user_id = update.effective_user.id # Strip spaces, dashes, dots so user can send "1 2 3 4 5" or "1-2-3-4-5" raw = update.message.text.strip() code = raw.replace(" ", "").replace("-", "").replace(".", "")  client = user_data[user_id].get("client") phone = user_data[user_id]["phone"]  try:     await client.sign_in(phone, code) except SessionPasswordNeededError:     await update.message.reply_text(         "Two-factor authentication is enabled. Please enter your password:"     )     return PASSWORD except PhoneCodeInvalidError:     await update.message.reply_text(         "Invalid code. Please try again (remember: separate digits with spaces), or /cancel."     )     return CODE except PhoneCodeExpiredError:     await update.message.reply_text("Code expired. Please start over with /start.")     await client.disconnect()     del user_data[user_id]     return ConversationHandler.END except Exception as e:     logger.exception("Error during sign in")     await update.message.reply_text("Login failed. Please try again later.")     await client.disconnect()     del user_data[user_id]     return ConversationHandler.END else:     return await finalize_login(update, context)

Hope this helps!

2 Likes

Thanks Sir

Your welcome @Mikky_Rose , did this help?

2 Likes

Am currently applying the changes, i would tell you if it worked, Thanks once again

Am very grateful for your solutions sir, It worked, Thank you sir

Your welcome! Happy to help!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.