feat(whatsapp): seed LID->phone mappings on startup
WhatsApp can deliver a sender LID instead of a phone number. The channel already learns the LID->phone mapping at runtime, but only after a message that carries both values, so the first message from a contact can't be resolved to a phone number. Seed the mapping on startup from two sources: - reverse mapping files the bridge persists in the auth directory (lid-mapping-<lid>_reverse.json), resolved via get_runtime_subdir so it respects a custom runtime dir - a new optional channels.whatsapp.lidMappings config dict for static mappings (takes precedence over the on-disk files) Malformed/empty mapping files are ignored rather than failing startup. Adds tests for both sources, precedence, malformed files and the no-auth-dir case, plus docs for the new config field.
This commit is contained in:
committed by
Xubin Ren
parent
e81968a32b
commit
99e158c062
@@ -449,3 +449,59 @@ async def test_start_sends_auth_message_with_generated_token(monkeypatch, tmp_pa
|
||||
assert sent_messages == [
|
||||
json.dumps({"type": "auth", "token": token_path.read_text(encoding="utf-8")})
|
||||
]
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# LID -> phone mapping seeding (startup): static config + bridge reverse files.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_lid_mappings_from_config():
|
||||
ch = WhatsAppChannel(
|
||||
{"enabled": True, "lidMappings": {"123456789012345": "15551234567"}},
|
||||
MagicMock(),
|
||||
)
|
||||
assert ch._lid_to_phone["123456789012345"] == "15551234567"
|
||||
|
||||
|
||||
def test_lid_mappings_from_bridge_reverse_files(tmp_path, monkeypatch):
|
||||
auth_dir = tmp_path / "whatsapp-auth"
|
||||
auth_dir.mkdir()
|
||||
(auth_dir / "lid-mapping-999888777666555_reverse.json").write_text(
|
||||
json.dumps("15559998888"), encoding="utf-8"
|
||||
)
|
||||
# malformed / empty files must be ignored, not crash startup
|
||||
(auth_dir / "lid-mapping-broken_reverse.json").write_text("{not json", encoding="utf-8")
|
||||
(auth_dir / "lid-mapping-empty_reverse.json").write_text(json.dumps(""), encoding="utf-8")
|
||||
|
||||
monkeypatch.setattr(
|
||||
"nanobot.config.paths.get_runtime_subdir", lambda name: auth_dir
|
||||
)
|
||||
|
||||
ch = WhatsAppChannel({"enabled": True}, MagicMock())
|
||||
assert ch._lid_to_phone == {"999888777666555": "15559998888"}
|
||||
|
||||
|
||||
def test_lid_mappings_config_takes_precedence_over_files(tmp_path, monkeypatch):
|
||||
auth_dir = tmp_path / "whatsapp-auth"
|
||||
auth_dir.mkdir()
|
||||
(auth_dir / "lid-mapping-555_reverse.json").write_text(
|
||||
json.dumps("from-file"), encoding="utf-8"
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"nanobot.config.paths.get_runtime_subdir", lambda name: auth_dir
|
||||
)
|
||||
|
||||
ch = WhatsAppChannel(
|
||||
{"enabled": True, "lidMappings": {"555": "from-config"}}, MagicMock()
|
||||
)
|
||||
assert ch._lid_to_phone["555"] == "from-config"
|
||||
|
||||
|
||||
def test_lid_mappings_empty_when_no_auth_dir(tmp_path, monkeypatch):
|
||||
missing = tmp_path / "does-not-exist"
|
||||
monkeypatch.setattr(
|
||||
"nanobot.config.paths.get_runtime_subdir", lambda name: missing
|
||||
)
|
||||
ch = WhatsAppChannel({"enabled": True}, MagicMock())
|
||||
assert ch._lid_to_phone == {}
|
||||
|
||||
Reference in New Issue
Block a user