@@ -1300,59 +1300,132 @@ async def get_message_context(
13001300 title = "Add Contact" , openWorldHint = True , destructiveHint = True , idempotentHint = True
13011301 )
13021302)
1303- async def add_contact (phone : str , first_name : str , last_name : str = "" ) -> str :
1303+ async def add_contact (
1304+ phone : Optional [str ] = None ,
1305+ first_name : str = "" ,
1306+ last_name : str = "" ,
1307+ username : Optional [str ] = None ,
1308+ ) -> str :
13041309 """
13051310 Add a new contact to your Telegram account.
13061311 Args:
1307- phone: The phone number of the contact (with country code).
1312+ phone: The phone number of the contact (with country code). Required if username is not provided.
13081313 first_name: The contact's first name.
13091314 last_name: The contact's last name (optional).
1315+ username: The Telegram username (without @). Use this for adding contacts without phone numbers.
1316+
1317+ Note: Either phone or username must be provided. If username is provided, the function will resolve it
1318+ and add the contact using contacts.addContact API (which supports adding contacts without phone numbers).
13101319 """
13111320 try :
1312- # Try to import the required types first
1313- from telethon .tl .types import InputPhoneContact
1321+ # Normalize None to empty string for easier checking
1322+ phone = phone or ""
1323+ username = username or ""
1324+
1325+ # Validate that at least one identifier is provided
1326+ if not phone and not username :
1327+ return "Error: Either phone or username must be provided."
1328+
1329+ # If username is provided, use it for username-based contact addition
1330+ if username :
1331+ # Remove @ if present
1332+ username_clean = username .lstrip ("@" )
1333+ if not username_clean :
1334+ return "Error: Username cannot be empty."
1335+
1336+ # Resolve username to get user information
1337+ try :
1338+ resolve_result = await client (
1339+ functions .contacts .ResolveUsernameRequest (username = username_clean )
1340+ )
13141341
1315- result = await client (
1316- functions .contacts .ImportContactsRequest (
1317- contacts = [
1318- InputPhoneContact (
1319- client_id = 0 ,
1320- phone = phone ,
1342+ # Extract user from the result
1343+ if not resolve_result .users :
1344+ return f"Error: User with username @{ username_clean } not found."
1345+
1346+ user = resolve_result .users [0 ]
1347+ if not isinstance (user , User ):
1348+ return f"Error: Resolved entity is not a user."
1349+
1350+ user_id = user .id
1351+ access_hash = user .access_hash
1352+
1353+ # Use contacts.addContact to add the contact by user ID
1354+ from telethon .tl .types import InputUser
1355+
1356+ result = await client (
1357+ functions .contacts .AddContactRequest (
1358+ id = InputUser (user_id = user_id , access_hash = access_hash ),
13211359 first_name = first_name ,
13221360 last_name = last_name ,
1361+ phone = "" , # Empty phone for username-based contacts
13231362 )
1324- ]
1325- )
1326- )
1327- if result .imported :
1328- return f"Contact { first_name } { last_name } added successfully."
1329- else :
1330- return f"Contact not added. Response: { str (result )} "
1331- except (ImportError , AttributeError ) as type_err :
1332- # Try alternative approach using raw API
1333- try :
1363+ )
1364+
1365+ if hasattr (result , "updates" ) and result .updates :
1366+ return (
1367+ f"Contact { first_name } { last_name } (@{ username_clean } ) added successfully."
1368+ )
1369+ else :
1370+ return f"Contact { first_name } { last_name } (@{ username_clean } ) added successfully (no updates returned)."
1371+
1372+ except Exception as resolve_e :
1373+ logger .exception (
1374+ f"add_contact (username resolve) failed (username={ username_clean } )"
1375+ )
1376+ return log_and_format_error ("add_contact" , resolve_e , username = username_clean )
1377+
1378+ elif phone :
1379+ # Original phone-based contact addition
1380+ from telethon .tl .types import InputPhoneContact
1381+
13341382 result = await client (
13351383 functions .contacts .ImportContactsRequest (
13361384 contacts = [
1337- {
1338- " client_id" : 0 ,
1339- " phone" : phone ,
1340- " first_name" : first_name ,
1341- " last_name" : last_name ,
1342- }
1385+ InputPhoneContact (
1386+ client_id = 0 ,
1387+ phone = phone ,
1388+ first_name = first_name ,
1389+ last_name = last_name ,
1390+ )
13431391 ]
13441392 )
13451393 )
1346- if hasattr ( result , "imported" ) and result .imported :
1347- return f"Contact { first_name } { last_name } added successfully (alt method) ."
1394+ if result .imported :
1395+ return f"Contact { first_name } { last_name } added successfully."
13481396 else :
1349- return f"Contact not added. Alternative method response: { str (result )} "
1350- except Exception as alt_e :
1351- logger .exception (f"add_contact (alt method) failed (phone={ phone } )" )
1352- return log_and_format_error ("add_contact" , alt_e , phone = phone )
1397+ return f"Contact not added. Response: { str (result )} "
1398+ else :
1399+ return "Error: Phone number is required when username is not provided."
1400+ except (ImportError , AttributeError ) as type_err :
1401+ # Try alternative approach using raw API (only for phone-based)
1402+ if phone and not username :
1403+ try :
1404+ result = await client (
1405+ functions .contacts .ImportContactsRequest (
1406+ contacts = [
1407+ {
1408+ "client_id" : 0 ,
1409+ "phone" : phone ,
1410+ "first_name" : first_name ,
1411+ "last_name" : last_name ,
1412+ }
1413+ ]
1414+ )
1415+ )
1416+ if hasattr (result , "imported" ) and result .imported :
1417+ return f"Contact { first_name } { last_name } added successfully (alt method)."
1418+ else :
1419+ return f"Contact not added. Alternative method response: { str (result )} "
1420+ except Exception as alt_e :
1421+ logger .exception (f"add_contact (alt method) failed (phone={ phone } )" )
1422+ return log_and_format_error ("add_contact" , alt_e , phone = phone )
1423+ else :
1424+ logger .exception (f"add_contact (type error) failed" )
1425+ return log_and_format_error ("add_contact" , type_err )
13531426 except Exception as e :
1354- logger .exception (f"add_contact failed (phone={ phone } )" )
1355- return log_and_format_error ("add_contact" , e , phone = phone )
1427+ logger .exception (f"add_contact failed (phone={ phone } , username= { username } )" )
1428+ return log_and_format_error ("add_contact" , e , phone = phone , username = username )
13561429
13571430
13581431@mcp .tool (
0 commit comments