Live location sharing (botovod) + SMS 'я тут' with Yandex Maps link
Feature 1 - opt-in live location: - set_live_config Rust command writes live_share.json (url/token stay on device) - LiveShare.kt singleton posts the current fix to /api/live/push every ~10s from the GPS flush loop, on a background thread; diagnostics in live_share_log.jsonl - profile toggle + endpoint/token fields, off by default; server side is in botovod Feature 2 - SMS 'я тут': - send_sms / pick_contact / get_contact_result Rust commands - MainActivity: system contact picker (no READ_CONTACTS), direct SmsManager send when SEND_SMS is granted else the prefilled system composer; SEND_SMS in the manifest - contact config in profile (manual + picker), 'СМС' button on the record screen with an in-app confirm; text carries coords + a Yandex Maps pin link README + session log updated.
This commit is contained in:
parent
762221d186
commit
1410062d85
8 changed files with 415 additions and 1 deletions
72
docs/session-logs/2026-10-26_live-location-and-sms.md
Normal file
72
docs/session-logs/2026-10-26_live-location-and-sms.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# 2026-10-26 - Трансляция местоположения (botovod) + СМС «я тут»
|
||||
|
||||
Плана в `docs/plans/` под эти две фичи не было - делали по устной постановке пользователя
|
||||
в этой сессии.
|
||||
|
||||
## Feature 1: live-локация через botovod (этап 1)
|
||||
|
||||
Постановка (подтверждена): точка со хвостом, отображение ТОЛЬКО после входа, доступ у админа
|
||||
и выбранных. Отправка раз в 10 секунд через интернет (пользователь поменял с минуты:
|
||||
«гадать что случилось за 10 секунд легче чем за минуту»). Переиспользуем SRP-авторизацию botovod.
|
||||
|
||||
### Серверная часть (botovod, /home/chaiman/dev/vps/botovod -> на VPS /home/chaiman/botovod)
|
||||
- `POST /api/live/push` - телефон шлёт `{token,lat,lng,spd,ts}`, авторизация общим токеном (без
|
||||
сессии, это фоновый сервис). Пишет `db/live.json` (last + хвост, максимум 240 точек ~40 мин).
|
||||
- `GET /api/live/pos` - отдаёт last+trail+stale, только залогиненному зрителю из списка доступа
|
||||
(`get_session_user` сверяется с `db/live_config.json.viewers`). Иначе 401.
|
||||
- `GET /live` - страница карты (`web/live.html`, Leaflet + публичные тайлы OSM, поллинг pos раз
|
||||
в 5с, точка + хвост, бар статуса в эфире/нет свежих). Без входа - 302 на `/login`.
|
||||
- Конфиг: `db/live_config.json` `{token, viewers:["4aiman","key55"]}`; состояние `db/live.json`.
|
||||
Оба в `.gitignore` botovod - токен в репозиторий не попадает. Код закоммичен (botovod
|
||||
`271d1a6`), секреты - нет.
|
||||
- Заведён пользователь `key55` (SRP, пароль задал пользователь; отдаст жене и сменит).
|
||||
|
||||
### Деплой и проверка на стенде (4aiman.top)
|
||||
- Серверная app.js == локальная база (md5 совпал) до правок - затёрли ровно её + свои роуты.
|
||||
Бэкап: `app.js.bak-pre-live-*` на VPS. Залиты app.js, web/live.html, db/live*.json,
|
||||
db/users/key55.json (только эти, не вся db/), владелец chaiman, `node -c` на VPS OK, рестарт
|
||||
botovod.service - active.
|
||||
- Проверено curl на живом 4aiman.top: неверный токен 401, верный push 200 `{ok:true}`
|
||||
(точка записалась в live.json), pos без сессии 401, `/live` без сессии 302 -> /login, кривые
|
||||
координаты 400. Тестовую точку из live.json убрал.
|
||||
|
||||
### Часть в приложении (baldav)
|
||||
- Rust `set_live_config(enabled,url,token)` -> `live_share.json` в корне приложения
|
||||
(`write_app_root_file`). url/token только на устройстве.
|
||||
- Kotlin `LiveShare.kt` (синглтон, как Hydration): читает конфиг, раз в 10с из flush-петли
|
||||
`GpsRecorderService` шлёт POST в фоновом потоке (HttpURLConnection, таймауты 5с), диагностика
|
||||
в `live_share_log.jsonl`. Проводка: `lastSpeed`, `LiveShare.tick(...)` в петле, `reset()` на
|
||||
старте сессии.
|
||||
- UI: галка + поля адреса/токена в профиле; дефолт адреса `https://4aiman.top/api/live/push`,
|
||||
выключено по умолчанию. Синк конфига на старте приложения (как гидратация).
|
||||
|
||||
## Feature 2: СМС «я тут»
|
||||
|
||||
Постановка: интент с предзаполненным текстом, ссылка на **Яндекс.Карты** (не гугл); контакт -
|
||||
и выбор из системных, и ручной ввод; кнопка во время трекинга -> подтверждение -> отправка.
|
||||
Работает на 2G/EDGE без интернета.
|
||||
|
||||
- Решение по отправке: если дано SEND_SMS - шлём напрямую `SmsManager` (одно подтверждение в
|
||||
приложении); иначе запрашиваем разрешение на будущее и открываем системный SMS-композер с
|
||||
предзаполненным текстом. Так работает в любом случае, ОС сама даёт выбор. (Это осознанный
|
||||
компромисс, не заглушка.)
|
||||
- Rust: `send_sms(number,text)` (пишет `sms_request.json` + команду `send_sms` в мост),
|
||||
`pick_contact()` (команда `pick_contact`), `get_contact_result()` (читает+чистит
|
||||
`contact_result.json`).
|
||||
- Kotlin (MainActivity): `pickContactLauncher` (ACTION_PICK по Phone.CONTENT_URI, номер читается
|
||||
из URI без READ_CONTACTS), команды `pick_contact`/`send_sms` в `processGpsCommand`, хелпер
|
||||
`sendSms` (прямая отправка или фолбэк на композер). Разрешение `SEND_SMS` в манифесте.
|
||||
- UI: контакт в профиле (ручной ввод + «Выбрать из контактов» с поллингом результата пикера);
|
||||
текст `Я тут: <lat>,<lon> https://yandex.ru/maps/?pt=<lon>,<lat>&z=16&l=map`; кнопка «СМС» в
|
||||
панели записи (видна, только если номер настроен), подтверждение через `appConfirm`.
|
||||
|
||||
## Статус проверки
|
||||
- Серверная часть Feature 1 - проверена на стенде (4aiman.top), работает.
|
||||
- Приложение (обе фичи) - собрано чисто, **build 0.1.524**, Rust+Kotlin компилируются. На
|
||||
устройстве НЕ проверено: телефон не был подключён на момент сборки. Поставить и проверить:
|
||||
(1) пуш координат и карту `/live` под key55; (2) выбор контакта и отправку СМС.
|
||||
|
||||
## TODO (следующий этап live-локации, записано со слов пользователя)
|
||||
- Отправлять на VPS все сохранённые маршруты из меню baldav + слать id маршрута вместе с
|
||||
координатами; опционально показывать сохранённые «проезженные дороги» как в baldav; key55
|
||||
должен видеть то же, что на экране трекинга; шарить статические данные из baldav по интернету.
|
||||
Loading…
Add table
Add a link
Reference in a new issue