shivao-projeto/server
PontualTech / Karlão 330d5aaa62
Some checks are pending
Build Android (APK + AAB) / build-android (push) Waiting to run
feat(ble): wake-up Xiaoxiang BMS — read inicial + 5A x4 v1.10.11
Confirmado: BMS responde ao app oficial Xiaoxiang. Problema é técnica
de inicialização não implementada na nossa abordagem.

Adicionado wake-up sequence ANTES do probe de protocolos:
1. ble.read na notify char (acorda stack BLE)
2. delay 300ms
3. write 0x5A x4 (handshake hello observado em alguns Xiaoxiang)
4. delay 1500ms (BMS processa wake)
5. probe normal de protocolos

Cada step protegido por try/catch + timeout 2s — não trava loop.
Logs detalhados pra ver onde falha se acontecer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 08:21:41 -03:00
..
public feat(ble): wake-up Xiaoxiang BMS — read inicial + 5A x4 v1.10.11 2026-04-29 08:21:41 -03:00
src feat(ble): wake-up Xiaoxiang BMS — read inicial + 5A x4 v1.10.11 2026-04-29 08:21:41 -03:00
.gitignore chore: initial commit + security hardening (4 runs squad shivao-melhoria) 2026-04-27 13:24:08 -03:00
docker-compose.yml chore: initial commit + security hardening (4 runs squad shivao-melhoria) 2026-04-27 13:24:08 -03:00
Dockerfile chore: initial commit + security hardening (4 runs squad shivao-melhoria) 2026-04-27 13:24:08 -03:00
package-lock.json feat(sync): WebSocket realtime + auto-push/pull entre PC e celular v1.5.0 2026-04-28 06:51:35 -03:00
package.json feat(sync): WebSocket realtime + auto-push/pull entre PC e celular v1.5.0 2026-04-28 06:51:35 -03:00
README.md chore: initial commit + security hardening (4 runs squad shivao-melhoria) 2026-04-27 13:24:08 -03:00

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 ResourceApplicationPublic/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 StoragesPersistent 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/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<SEU_TOKEN>/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 / iOS)
  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
  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 <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.

  1. Crie conta em 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 <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_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.