PIPELINE COMPLETO QUE RODOU: 1. JDK 17 instalado em ~/jdk17 (portátil, sem admin) 2. Android SDK cmdline-tools + platform-34 + build-tools-34 + platform-tools instalados em ~/android-sdk 3. JAVA_HOME e ANDROID_HOME setados no PATH user 4. npm install + npx cap add android (estrutura Android gerada) 5. AndroidManifest.xml com 10 permissions (location background, vibrate, wake_lock, foreground service, post_notifications) 6. Keystore PERMANENTE shivao-release.keystore gerado via keytool (validade 10000d, RSA 2048) 7. build.gradle: signingConfigs.release + applicationId br.com.pontualtech.shivao + versionCode 2 + versionName 1.2.0 8. local.properties: sdk.dir=C:/Users/pontu/android-sdk (forward slashes — Java properties NÃO aceitam \) 9. ./gradlew bundleRelease assembleRelease — primeira build em 1m39s 10. APK 3.4MB + AAB 3.1MB — ambos signed com keystore permanente ARTEFATOS: - C:/Users/pontu/Downloads/Shivao-v1.2.0-capacitor.apk (3.4MB) - C:/Users/pontu/Downloads/Shivao-v1.2.0-capacitor.aab (3.1MB) — pronto pra Play Store - mobile/android/app/shivao-release.keystore (NÃO commitado, .gitignore protege) - C:/Users/pontu/Downloads/Shivao-keystore-backup/shivao-release-CAPACITOR.keystore (BACKUP) Release Forgejo v1.2.0 publicada com APK + AAB anexados. Próximo: criar conta Google Play ($25 1×) e submeter o AAB. 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.