feat: Add support for adding contacts by username without phone number
- Modified add_contact function to support username-based contact addition - If phone parameter is empty or starts with @, function resolves username first - Uses contacts.AddContactRequest API for username-based contacts - Maintains backward compatibility with phone-based contact addition - Allows adding contacts as done in Telegram UI when searching by username
This commit is contained in:
parent
36522e5ebc
commit
4693719798
1 changed files with 86 additions and 31 deletions
117
main.py
117
main.py
|
|
@ -1304,52 +1304,107 @@ async def add_contact(phone: str, first_name: str, last_name: str = "") -> str:
|
||||||
"""
|
"""
|
||||||
Add a new contact to your Telegram account.
|
Add a new contact to your Telegram account.
|
||||||
Args:
|
Args:
|
||||||
phone: The phone number of the contact (with country code).
|
phone: The phone number of the contact (with country code) OR username (starting with @) OR empty string for username-based addition.
|
||||||
first_name: The contact's first name.
|
first_name: The contact's first name.
|
||||||
last_name: The contact's last name (optional).
|
last_name: The contact's last name (optional).
|
||||||
|
|
||||||
|
Note: If phone is empty or starts with @, the function will try to resolve it as a username
|
||||||
|
and add the contact using contacts.addContact API (which supports adding contacts without phone numbers).
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# Try to import the required types first
|
# Check if phone is empty or is a username (starts with @)
|
||||||
from telethon.tl.types import InputPhoneContact
|
is_username = not phone or phone.startswith("@")
|
||||||
|
|
||||||
result = await client(
|
if is_username:
|
||||||
functions.contacts.ImportContactsRequest(
|
# Handle username-based contact addition
|
||||||
contacts=[
|
username = phone.lstrip("@") if phone else ""
|
||||||
InputPhoneContact(
|
if not username:
|
||||||
client_id=0,
|
return "Error: Username cannot be empty when adding contact by username."
|
||||||
phone=phone,
|
|
||||||
|
# Resolve username to get user information
|
||||||
|
try:
|
||||||
|
resolve_result = await client(functions.contacts.ResolveUsernameRequest(username=username))
|
||||||
|
|
||||||
|
# Extract user from the result
|
||||||
|
if not resolve_result.users:
|
||||||
|
return f"Error: User with username @{username} not found."
|
||||||
|
|
||||||
|
user = resolve_result.users[0]
|
||||||
|
if not isinstance(user, User):
|
||||||
|
return f"Error: Resolved entity is not a user."
|
||||||
|
|
||||||
|
user_id = user.id
|
||||||
|
access_hash = user.access_hash
|
||||||
|
|
||||||
|
# Use contacts.addContact to add the contact by user ID
|
||||||
|
from telethon.tl.types import InputUser
|
||||||
|
|
||||||
|
result = await client(
|
||||||
|
functions.contacts.AddContactRequest(
|
||||||
|
id=InputUser(user_id=user_id, access_hash=access_hash),
|
||||||
first_name=first_name,
|
first_name=first_name,
|
||||||
last_name=last_name,
|
last_name=last_name,
|
||||||
|
phone="", # Empty phone for username-based contacts
|
||||||
)
|
)
|
||||||
]
|
)
|
||||||
)
|
|
||||||
)
|
if hasattr(result, "updates") and result.updates:
|
||||||
if result.imported:
|
return f"Contact {first_name} {last_name} (@{username}) added successfully."
|
||||||
return f"Contact {first_name} {last_name} added successfully."
|
else:
|
||||||
|
return f"Contact {first_name} {last_name} (@{username}) added successfully (no updates returned)."
|
||||||
|
|
||||||
|
except Exception as resolve_e:
|
||||||
|
logger.exception(f"add_contact (username resolve) failed (username={username})")
|
||||||
|
return log_and_format_error("add_contact", resolve_e, username=username)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return f"Contact not added. Response: {str(result)}"
|
# Original phone-based contact addition
|
||||||
except (ImportError, AttributeError) as type_err:
|
from telethon.tl.types import InputPhoneContact
|
||||||
# Try alternative approach using raw API
|
|
||||||
try:
|
|
||||||
result = await client(
|
result = await client(
|
||||||
functions.contacts.ImportContactsRequest(
|
functions.contacts.ImportContactsRequest(
|
||||||
contacts=[
|
contacts=[
|
||||||
{
|
InputPhoneContact(
|
||||||
"client_id": 0,
|
client_id=0,
|
||||||
"phone": phone,
|
phone=phone,
|
||||||
"first_name": first_name,
|
first_name=first_name,
|
||||||
"last_name": last_name,
|
last_name=last_name,
|
||||||
}
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if hasattr(result, "imported") and result.imported:
|
if result.imported:
|
||||||
return f"Contact {first_name} {last_name} added successfully (alt method)."
|
return f"Contact {first_name} {last_name} added successfully."
|
||||||
else:
|
else:
|
||||||
return f"Contact not added. Alternative method response: {str(result)}"
|
return f"Contact not added. Response: {str(result)}"
|
||||||
except Exception as alt_e:
|
except (ImportError, AttributeError) as type_err:
|
||||||
logger.exception(f"add_contact (alt method) failed (phone={phone})")
|
# Try alternative approach using raw API (only for phone-based)
|
||||||
return log_and_format_error("add_contact", alt_e, phone=phone)
|
# Check if phone is empty or is a username (starts with @)
|
||||||
|
is_username_alt = not phone or phone.startswith("@")
|
||||||
|
if not is_username_alt:
|
||||||
|
try:
|
||||||
|
result = await client(
|
||||||
|
functions.contacts.ImportContactsRequest(
|
||||||
|
contacts=[
|
||||||
|
{
|
||||||
|
"client_id": 0,
|
||||||
|
"phone": phone,
|
||||||
|
"first_name": first_name,
|
||||||
|
"last_name": last_name,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if hasattr(result, "imported") and result.imported:
|
||||||
|
return f"Contact {first_name} {last_name} added successfully (alt method)."
|
||||||
|
else:
|
||||||
|
return f"Contact not added. Alternative method response: {str(result)}"
|
||||||
|
except Exception as alt_e:
|
||||||
|
logger.exception(f"add_contact (alt method) failed (phone={phone})")
|
||||||
|
return log_and_format_error("add_contact", alt_e, phone=phone)
|
||||||
|
else:
|
||||||
|
logger.exception(f"add_contact (type error for username) failed")
|
||||||
|
return log_and_format_error("add_contact", type_err)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(f"add_contact failed (phone={phone})")
|
logger.exception(f"add_contact failed (phone={phone})")
|
||||||
return log_and_format_error("add_contact", e, phone=phone)
|
return log_and_format_error("add_contact", e, phone=phone)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue