feat: geo location as Google Maps link in Telegram notifications
When signal has geo, show clickable Google Maps link instead of raw coordinates. Without geo, show "Гео нету". Added parse_mode=HTML to send_message for link rendering. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
04f7bd79e2
commit
47b89ded8d
4 changed files with 8 additions and 8 deletions
|
|
@ -223,9 +223,9 @@ async def signal(
|
||||||
|
|
||||||
ts = datetime.fromtimestamp(body.timestamp / 1000, tz=timezone.utc)
|
ts = datetime.fromtimestamp(body.timestamp / 1000, tz=timezone.utc)
|
||||||
geo_info = (
|
geo_info = (
|
||||||
f"📍 {lat}, {lon} (±{accuracy}м)"
|
f"📍 <a href=\"https://maps.google.com/maps?q={lat},{lon}\">{lat}, {lon}</a> (±{accuracy:.0f}м)"
|
||||||
if geo
|
if geo
|
||||||
else "Без геолокации"
|
else "Гео нету"
|
||||||
)
|
)
|
||||||
text = (
|
text = (
|
||||||
f"🚨 Сигнал от {user_name}\n"
|
f"🚨 Сигнал от {user_name}\n"
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ async def send_message(text: str) -> None:
|
||||||
url = _TELEGRAM_API.format(token=config.BOT_TOKEN, method="sendMessage")
|
url = _TELEGRAM_API.format(token=config.BOT_TOKEN, method="sendMessage")
|
||||||
async with httpx.AsyncClient(timeout=10) as client:
|
async with httpx.AsyncClient(timeout=10) as client:
|
||||||
for attempt in range(3):
|
for attempt in range(3):
|
||||||
resp = await client.post(url, json={"chat_id": config.CHAT_ID, "text": text})
|
resp = await client.post(url, json={"chat_id": config.CHAT_ID, "text": text, "parse_mode": "HTML"})
|
||||||
if resp.status_code == 429:
|
if resp.status_code == 429:
|
||||||
retry_after = resp.json().get("parameters", {}).get("retry_after", 30)
|
retry_after = resp.json().get("parameters", {}).get("retry_after", 30)
|
||||||
sleep = retry_after * (attempt + 1)
|
sleep = retry_after * (attempt + 1)
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ async def test_signal_message_contains_registered_username():
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_signal_message_without_geo_contains_bez_geolocatsii():
|
async def test_signal_message_without_geo_contains_bez_geolocatsii():
|
||||||
"""When geo is None, message must contain 'Без геолокации'."""
|
"""When geo is None, message must contain 'Гео нету'."""
|
||||||
async with make_app_client() as client:
|
async with make_app_client() as client:
|
||||||
api_key = await _register(client, _UUID_S3, "Bob")
|
api_key = await _register(client, _UUID_S3, "Bob")
|
||||||
with patch("backend.telegram.send_message", new_callable=AsyncMock) as mock_send:
|
with patch("backend.telegram.send_message", new_callable=AsyncMock) as mock_send:
|
||||||
|
|
@ -129,7 +129,7 @@ async def test_signal_message_without_geo_contains_bez_geolocatsii():
|
||||||
headers={"Authorization": f"Bearer {api_key}"},
|
headers={"Authorization": f"Bearer {api_key}"},
|
||||||
)
|
)
|
||||||
text = mock_send.call_args[0][0]
|
text = mock_send.call_args[0][0]
|
||||||
assert "Без геолокации" in text
|
assert "Гео нету" in text
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ async def test_signal_with_geo_send_message_contains_coordinates():
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_signal_without_geo_send_message_contains_no_geo_label():
|
async def test_signal_without_geo_send_message_contains_no_geo_label():
|
||||||
"""Criterion 1: when geo is null, Telegram message contains 'Без геолокации'."""
|
"""Criterion 1: when geo is null, Telegram message contains 'Гео нету'."""
|
||||||
sent_texts: list[str] = []
|
sent_texts: list[str] = []
|
||||||
|
|
||||||
async def _capture(text: str) -> None:
|
async def _capture(text: str) -> None:
|
||||||
|
|
@ -158,8 +158,8 @@ async def test_signal_without_geo_send_message_contains_no_geo_label():
|
||||||
await asyncio.sleep(0)
|
await asyncio.sleep(0)
|
||||||
|
|
||||||
assert len(sent_texts) == 1
|
assert len(sent_texts) == 1
|
||||||
assert "Без геолокации" in sent_texts[0], (
|
assert "Гео нету" in sent_texts[0], (
|
||||||
f"Expected 'Без геолокации' in message, got: {sent_texts[0]!r}"
|
f"Expected 'Гео нету' in message, got: {sent_texts[0]!r}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue