ESTRUTURA NOVA: mobile/ + scripts/sync-html.mjs - mobile/package.json: Capacitor 6 + plugins (geolocation, local-notifications, network, preferences, status-bar) - mobile/capacitor.config.json: appId br.com.pontualtech.shivao, allowNavigation pra OSM/Windy/CDNs - mobile/.gitignore: protege keystore (NUNCA commitar chaves privadas) - mobile/README.md: setup completo (JDK + Android Studio + keystore + build APK/AAB + Play Store submission + iOS futuro + troubleshooting) - scripts/sync-html.mjs: copia app/diario-bordo.html → server/public + mobile/www (1 fonte da verdade) ADAPTER NATIVO no HTML (sincronizado app/ + server/public/): - isNative() / nativePlatform() detecta Capacitor - nativeWatchPosition() usa Capacitor.Geolocation (background-capable) com fallback navigator.geolocation - nativeNotify() usa Capacitor.LocalNotifications com fallback toast - initServiceWorker() pula registro no Capacitor (WebView nativo já tem cache próprio) NÃO INCLUI (ainda): - Build local: precisa JDK 17 + Android Studio (~3GB) — instruções no README - Keystore: gerar 1 vez via keytool (script no README) - AAB pra Play Store: comandos no README - Conta Google Play Developer: $25 1× pelo dono Próximo passo manual: instalar JDK + Android Studio, rodar 'npm install && npx cap add android'. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| public | ||
| src | ||
| .gitignore | ||
| docker-compose.yml | ||
| Dockerfile | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
Shivao Cloud
Backend para o Diário de Bordo do Shivao com:
- ☁️ Sincronização dos dados na nuvem (multi-dispositivo)
- 📷 Mídia (fotos, áudios, vídeos) armazenada no servidor
- 🚨 Notificações automáticas (Telegram, e-mail, SMS, WhatsApp, ntfy, webhook) — sem precisar tocar em botão
- 🛡️ Dead-man switch: se o celular perde sinal/bateria enquanto fundeado, o servidor mesmo dispara o alarme
Deploy no Coolify (passo a passo)
1. Subir o código para um repositório Git
Crie um repo no GitHub/GitLab e envie esta pasta. Ou use o "Public Repository" do Coolify direto.
2. No painel Coolify
- + New Resource → Application → Public/Private Repository
- Cole a URL do seu repositório
- Build Pack:
Dockerfile - Port:
3000 - Domain: configure seu domínio (ex:
shivao.seu-dominio.com) — Coolify gera SSL automático
3. Variáveis de ambiente
Em Environment Variables no Coolify, adicione (mínimo):
| Variável | Valor |
|---|---|
BOAT_TOKEN |
string aleatória longa (ex: openssl rand -hex 32) |
TELEGRAM_BOT_TOKEN |
seu token do BotFather |
TELEGRAM_CHAT_IDS |
seu chat ID |
Veja .env.example para todas as opções (e-mail, SMS, etc.). Configure pelo menos um canal.
4. Volume persistente
Em Storages → Persistent Storage:
- Name:
shivao-data - Mount Path:
/data
Sem isso, ao reiniciar o container você perde o banco e as mídias.
5. Deploy
Clique em Deploy. Aguarde o build. Acesse https://shivao.seu-dominio.com — vai aparecer o app.
Configurando o Telegram (5 minutos, recomendado)
- No Telegram, fale com @BotFather →
/newbot - Escolha um nome e username → ele dá um token
- Inicie uma conversa com o bot que você criou (mande qualquer mensagem)
- Acesse
https://api.telegram.org/bot<SEU_TOKEN>/getUpdatesno navegador - No JSON, procure
"chat":{"id":123456789...}— esse é seuTELEGRAM_CHAT_IDS - Cole no Coolify e redeploy
Para receber em grupo: adicione o bot ao grupo, mande uma mensagem, repita o passo 4 (chat ID será negativo).
Configurando ntfy.sh (sem cadastro, push grátis)
- Instale o app ntfy (Android / iOS)
- No app, Subscribe → invente um tópico único e secreto (ex:
shivao-aljg29x71kqp) - Coloque esse mesmo nome em
NTFY_TOPICno Coolify
⚠️ Como ntfy é público, qualquer pessoa que adivinhe o tópico vê suas notificações. Use algo aleatório e longo.
Configurando E-mail SMTP
Gmail (mais comum):
- Ative verificação em 2 etapas na conta Google
- Vá em Senhas de app
- Gere uma senha → use ela em
SMTP_PASS - Configure:
SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_SECURE=false SMTP_USER=seu-email@gmail.com SMTP_PASS=senha-de-app-de-16-caracteres SMTP_FROM=Shivao Alertas <seu-email@gmail.com> SMTP_TO=destinatario@email.com,outro@email.com
Resend, SendGrid, Mailgun: similar, basta seguir o painel deles e usar SMTP.
Configurando Twilio (SMS / WhatsApp — pago)
Apenas se quiser SMS ou WhatsApp realmente automático.
- Crie conta em twilio.com
- Para SMS: compre um número (Brasil custa ~$1/mês + $0.05 por SMS)
- Para WhatsApp: ative o sandbox grátis OU peça aprovação Business
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=xxxxxxxxxxxxx
TWILIO_FROM_NUMBER=+15551234567
TWILIO_SMS_TO=+5521999998888
TWILIO_WHATSAPP_FROM=whatsapp:+14155238886
TWILIO_WHATSAPP_TO=whatsapp:+5521999998888
Como funciona o Dead-Man Switch
- Quando você toca em "Fundear" no app, ele avisa o servidor
- Enquanto a vigia está ativa, o app envia um heartbeat a cada 30 segundos: "estou vivo, GPS aqui"
- Se o servidor não receber heartbeat por 5 minutos (
HEARTBEAT_TIMEOUT_SECconfigurável), ele assume que algo deu errado (celular morreu, perdeu sinal, app fechou) e dispara o alarme remoto automaticamente para todos os contatos - Quando você levanta âncora normalmente, o app avisa o servidor para parar a vigia
Isso garante que mesmo se você dormir e o celular morrer, alguém vai ser avisado.
Endpoints da API (referência)
Todas requerem header Authorization: Bearer <BOAT_TOKEN> (exceto /api/health).
| Método | Rota | Função |
|---|---|---|
| GET | /api/health |
Status público |
| GET | /api/info |
Canais configurados |
| GET | /api/data |
Baixar todo o estado |
| POST | /api/data |
Enviar todo o estado |
| POST | /api/media |
Upload de arquivo (multipart) |
| GET | /api/media/list |
Lista de mídias |
| GET | /api/media/:id |
Baixar mídia |
| DELETE | /api/media/:id |
Apagar mídia |
| POST | /api/anchor/start |
Iniciar vigia no servidor |
| POST | /api/anchor/heartbeat |
Manter vivo |
| POST | /api/anchor/alarm |
Disparar alarme imediato |
| POST | /api/anchor/stop |
Encerrar vigia |
| GET | /api/anchor/status |
Estado atual |
| POST | /api/test |
Disparar mensagem de teste |
| GET | /api/alarms |
Histórico de alarmes |
| POST | /api/share/create |
Criar link público temporário |
| GET | /api/share/list |
Listar shares ativos |
| DELETE | /api/share/:token |
Revogar share |
| POST | /api/share/position |
Postar posição (boat → server) |
| GET | /share/:token |
Página pública do link (sem auth) |
| GET | /api/share/:token/info |
Info do share (público) |
| GET | /api/share/:token/positions |
Posições do share (público) |
Rodando localmente (dev)
cp .env.example .env
# edite .env
npm install
npm start
Ou com Docker:
docker compose up --build
Acesse http://localhost:3000
Conectando o app
No app (Diário de Bordo), vá em Arquivo → Configurações da Nuvem, preencha:
- Servidor:
https://shivao.seu-dominio.com - Token: o mesmo
BOAT_TOKENque você definiu
Toque em Testar conexão → deve receber a mensagem de teste em todos os canais configurados.
A partir daí o app sincroniza automaticamente.