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: