refactor: Add separate username parameter to add_contact function

- Changed phone parameter to Optional[str] = None
- Added separate username parameter (Optional[str] = None)
- Improved function signature clarity - username is now explicit parameter
- Updated validation logic to check for either phone or username
- Maintains backward compatibility with phone-based contacts
- Better API design - no longer need to pass username via phone parameter
This commit is contained in:
gvidonind-commits 2026-01-29 20:32:08 +03:00
parent 4693719798
commit afb02be510

53
main.py
View file

@ -1300,34 +1300,41 @@ async def get_message_context(
title="Add Contact", openWorldHint=True, destructiveHint=True, idempotentHint=True title="Add Contact", openWorldHint=True, destructiveHint=True, idempotentHint=True
) )
) )
async def add_contact(phone: str, first_name: str, last_name: str = "") -> str: async def add_contact(phone: Optional[str] = None, first_name: str = "", last_name: str = "", username: Optional[str] = None) -> 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) OR username (starting with @) OR empty string for username-based addition. phone: The phone number of the contact (with country code). Required if username is not provided.
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).
username: The Telegram username (without @). Use this for adding contacts without phone numbers.
Note: If phone is empty or starts with @, the function will try to resolve it as a username Note: Either phone or username must be provided. If username is provided, the function will resolve it
and add the contact using contacts.addContact API (which supports adding contacts without phone numbers). and add the contact using contacts.addContact API (which supports adding contacts without phone numbers).
""" """
try: try:
# Check if phone is empty or is a username (starts with @) # Normalize None to empty string for easier checking
is_username = not phone or phone.startswith("@") phone = phone or ""
username = username or ""
if is_username: # Validate that at least one identifier is provided
# Handle username-based contact addition if not phone and not username:
username = phone.lstrip("@") if phone else "" return "Error: Either phone or username must be provided."
if not username:
return "Error: Username cannot be empty when adding contact by username." # If username is provided, use it for username-based contact addition
if username:
# Remove @ if present
username_clean = username.lstrip("@")
if not username_clean:
return "Error: Username cannot be empty."
# Resolve username to get user information # Resolve username to get user information
try: try:
resolve_result = await client(functions.contacts.ResolveUsernameRequest(username=username)) resolve_result = await client(functions.contacts.ResolveUsernameRequest(username=username_clean))
# Extract user from the result # Extract user from the result
if not resolve_result.users: if not resolve_result.users:
return f"Error: User with username @{username} not found." return f"Error: User with username @{username_clean} not found."
user = resolve_result.users[0] user = resolve_result.users[0]
if not isinstance(user, User): if not isinstance(user, User):
@ -1349,15 +1356,15 @@ async def add_contact(phone: str, first_name: str, last_name: str = "") -> str:
) )
if hasattr(result, "updates") and result.updates: if hasattr(result, "updates") and result.updates:
return f"Contact {first_name} {last_name} (@{username}) added successfully." return f"Contact {first_name} {last_name} (@{username_clean}) added successfully."
else: else:
return f"Contact {first_name} {last_name} (@{username}) added successfully (no updates returned)." return f"Contact {first_name} {last_name} (@{username_clean}) added successfully (no updates returned)."
except Exception as resolve_e: except Exception as resolve_e:
logger.exception(f"add_contact (username resolve) failed (username={username})") logger.exception(f"add_contact (username resolve) failed (username={username_clean})")
return log_and_format_error("add_contact", resolve_e, username=username) return log_and_format_error("add_contact", resolve_e, username=username_clean)
else: elif phone:
# Original phone-based contact addition # Original phone-based contact addition
from telethon.tl.types import InputPhoneContact from telethon.tl.types import InputPhoneContact
@ -1377,11 +1384,11 @@ async def add_contact(phone: str, first_name: str, last_name: str = "") -> str:
return f"Contact {first_name} {last_name} added successfully." return f"Contact {first_name} {last_name} added successfully."
else: else:
return f"Contact not added. Response: {str(result)}" return f"Contact not added. Response: {str(result)}"
else:
return "Error: Phone number is required when username is not provided."
except (ImportError, AttributeError) as type_err: except (ImportError, AttributeError) as type_err:
# Try alternative approach using raw API (only for phone-based) # Try alternative approach using raw API (only for phone-based)
# Check if phone is empty or is a username (starts with @) if phone and not username:
is_username_alt = not phone or phone.startswith("@")
if not is_username_alt:
try: try:
result = await client( result = await client(
functions.contacts.ImportContactsRequest( functions.contacts.ImportContactsRequest(
@ -1403,11 +1410,11 @@ async def add_contact(phone: str, first_name: str, last_name: str = "") -> str:
logger.exception(f"add_contact (alt method) failed (phone={phone})") logger.exception(f"add_contact (alt method) failed (phone={phone})")
return log_and_format_error("add_contact", alt_e, phone=phone) return log_and_format_error("add_contact", alt_e, phone=phone)
else: else:
logger.exception(f"add_contact (type error for username) failed") logger.exception(f"add_contact (type error) failed")
return log_and_format_error("add_contact", type_err) 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}, username={username})")
return log_and_format_error("add_contact", e, phone=phone) return log_and_format_error("add_contact", e, phone=phone, username=username)
@mcp.tool( @mcp.tool(