fix(tools): recognize email addresses as explicit targets in send_message
When using send_message with the email platform, valid email addresses like user@example.com were not recognized as explicit targets by _parse_target_ref(). This caused the function to return (None, None, False), forcing the system into channel-name resolution which has no way to resolve a raw email address, resulting in 'No home channel set for email' errors. Add _EMAIL_TARGET_RE pattern and email platform handler in _parse_target_ref() so email addresses are treated as explicit targets and routed directly without requiring a home target configuration.
This commit is contained in:
@ -1220,6 +1220,42 @@ class TestParseTargetRefSlack:
|
||||
assert _parse_target_ref("telegram", "C0B0QV5434G")[2] is False
|
||||
|
||||
|
||||
class TestParseTargetRefEmail:
|
||||
"""_parse_target_ref recognizes email addresses as explicit for the email platform."""
|
||||
|
||||
def test_standard_email_is_explicit(self):
|
||||
chat_id, thread_id, is_explicit = _parse_target_ref("email", "user@example.com")
|
||||
assert chat_id == "user@example.com"
|
||||
assert thread_id is None
|
||||
assert is_explicit is True
|
||||
|
||||
def test_email_with_dots_in_local_part(self):
|
||||
chat_id, _, is_explicit = _parse_target_ref("email", "first.last@example.co.uk")
|
||||
assert chat_id == "first.last@example.co.uk"
|
||||
assert is_explicit is True
|
||||
|
||||
def test_email_with_plus_tag(self):
|
||||
chat_id, _, is_explicit = _parse_target_ref("email", "user+tag@gmail.com")
|
||||
assert chat_id == "user+tag@gmail.com"
|
||||
assert is_explicit is True
|
||||
|
||||
def test_email_strips_whitespace(self):
|
||||
chat_id, _, is_explicit = _parse_target_ref("email", " user@example.com ")
|
||||
assert chat_id == "user@example.com"
|
||||
assert is_explicit is True
|
||||
|
||||
def test_invalid_email_not_explicit(self):
|
||||
assert _parse_target_ref("email", "not-an-email")[2] is False
|
||||
assert _parse_target_ref("email", "@example.com")[2] is False
|
||||
assert _parse_target_ref("email", "user@")[2] is False
|
||||
assert _parse_target_ref("email", "user@.com")[2] is False
|
||||
|
||||
def test_email_not_explicit_for_other_platforms(self):
|
||||
assert _parse_target_ref("telegram", "user@example.com")[2] is False
|
||||
assert _parse_target_ref("discord", "user@example.com")[2] is False
|
||||
assert _parse_target_ref("slack", "user@example.com")[2] is False
|
||||
|
||||
|
||||
class TestSendDiscordThreadId:
|
||||
"""_send_discord uses thread_id when provided."""
|
||||
|
||||
|
||||
@ -40,6 +40,10 @@ _NUMERIC_TOPIC_RE = _TELEGRAM_TOPIC_TARGET_RE
|
||||
# downstream adapters (signal, etc.) expect.
|
||||
_PHONE_PLATFORMS = frozenset({"signal", "sms", "whatsapp"})
|
||||
_E164_TARGET_RE = re.compile(r"^\s*\+(\d{7,15})\s*$")
|
||||
# Email addresses — a valid email like "user@domain.com" should be treated as
|
||||
# an explicit target for the email platform, not fall through to channel-name
|
||||
# resolution which has no way to resolve a raw address.
|
||||
_EMAIL_TARGET_RE = re.compile(r"^\s*[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\s*$")
|
||||
_IMAGE_EXTS = {".jpg", ".jpeg", ".png", ".webp", ".gif"}
|
||||
_VIDEO_EXTS = {".mp4", ".mov", ".avi", ".mkv", ".3gp"}
|
||||
_AUDIO_EXTS = {".ogg", ".opus", ".mp3", ".wav", ".m4a", ".flac"}
|
||||
@ -383,6 +387,10 @@ def _parse_target_ref(platform_name: str, target_ref: str):
|
||||
if target_ref.strip().isdigit():
|
||||
return f"group:{target_ref.strip()}", None, True
|
||||
return None, None, False
|
||||
if platform_name == "email":
|
||||
match = _EMAIL_TARGET_RE.fullmatch(target_ref)
|
||||
if match:
|
||||
return target_ref.strip(), None, True
|
||||
if platform_name in _PHONE_PLATFORMS:
|
||||
match = _E164_TARGET_RE.fullmatch(target_ref)
|
||||
if match:
|
||||
|
||||
Reference in New Issue
Block a user