# 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 1. **+ New Resource** → **Application** → **Public/Private Repository** 2. Cole a URL do seu repositório 3. **Build Pack**: `Dockerfile` 4. **Port**: `3000` 5. **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) 1. No Telegram, fale com [@BotFather](https://t.me/BotFather) → `/newbot` 2. Escolha um nome e username → ele dá um **token** 3. Inicie uma conversa com o bot que você criou (mande qualquer mensagem) 4. Acesse `https://api.telegram.org/bot/getUpdates` no navegador 5. No JSON, procure `"chat":{"id":123456789...}` — esse é seu `TELEGRAM_CHAT_IDS` 6. 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) 1. Instale o app **ntfy** ([Android](https://play.google.com/store/apps/details?id=io.heckel.ntfy) / [iOS](https://apps.apple.com/us/app/ntfy/id1625396347)) 2. No app, **Subscribe** → invente um tópico **único e secreto** (ex: `shivao-aljg29x71kqp`) 3. Coloque esse mesmo nome em `NTFY_TOPIC` no 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)**: 1. Ative **verificação em 2 etapas** na conta Google 2. Vá em [Senhas de app](https://myaccount.google.com/apppasswords) 3. Gere uma senha → use ela em `SMTP_PASS` 4. 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 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. 1. Crie conta em [twilio.com](https://www.twilio.com) 2. Para SMS: compre um número (Brasil custa ~$1/mês + $0.05 por SMS) 3. 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 1. Quando você toca em **"Fundear"** no app, ele avisa o servidor 2. Enquanto a vigia está ativa, o app envia um **heartbeat** a cada 30 segundos: "estou vivo, GPS aqui" 3. Se o servidor não receber heartbeat por 5 minutos (`HEARTBEAT_TIMEOUT_SEC` configurável), ele assume que algo deu errado (celular morreu, perdeu sinal, app fechou) e **dispara o alarme remoto** automaticamente para todos os contatos 4. 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 ` (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) ```bash cp .env.example .env # edite .env npm install npm start ``` Ou com Docker: ```bash 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_TOKEN` que 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.