API em Flask para integrar interacao do chat com a stream, com suporte a comandos, eventos da Twitch, feedback sonoro no OBS e consultas de progresso da Steam.
Esta aplicacao foi pensada para rodar no host do Render.
- Em producao, o Render define automaticamente a porta via variavel
PORT. - O endpoint publico esperado e o do proprio servico Render.
- Mantem dados por jogo em
dados.json, usando chave normalizada do nome do jogo (ex:torchlight-infinite). - Recebe comandos do chat via endpoints expostos para integrarem com Nightbot ou automacoes similares.
- Recebe eventos da Twitch via listener/webhook e dispara feedback sonoro na stream.
- Retorna informacoes de progresso de conquistas da Steam para o jogo atual da live.
- Expoe rotas de health check para manter o servico online no Render.
A API fica ociosa boa parte do tempo (sem live no ar), entao existe um ActivityManager central (py/activity_manager.py) que decide quando vale a pena rodar trabalho de fundo, para economizar CPU/requisicoes no Cloud Run.
A aplicacao fica em um de dois estados:
- ACTIVE: live da Twitch online e o Browser Source do OBS mandando heartbeat recente (menos de 60s).
- IDLE: qualquer uma das duas condicoes acima deixa de ser verdadeira.
Como cada sinal chega:
- Live online/offline: via Twitch EventSub (
stream.online/stream.offline), sem nenhum polling continuo na Twitch so para checar se a live esta no ar. No boot da instancia, a API faz uma unica checagem na Helix (GET /helix/streams) para descobrir se a live ja estava online antes da instancia subir (necessario porque o Cloud Run escala a zero e perderia o evento disparado antes de existir). - Browser Source conectado: a pagina
/obs/powerupmanda umPOST /heartbeata cada 30 segundos. Se o heartbeat parar de chegar por mais de 60s, o estado volta praIDLEautomaticamente (sem loop continuo rodando em segundo plano pra checar isso).
O que hoje depende do estado ACTIVE:
- Inicializacao do worker pool de sintese TTS e do monitor de cache TTS (
enqueue_tts_synthesis). Se um reward TTS for resgatado com a API emIDLE, a sintese e ignorada (ninguem estaria ouvindo mesmo, ja que o Browser Source nao esta conectado).
Endpoints:
-
POST /heartbeat- Chamado pelo overlay do OBS para sinalizar presenca. Retorna o estado atual do ActivityManager.
-
GET /debug/activity- Retorna o estado atual (
state,twitch_live,heartbeat_recent,last_heartbeat_at) para depuracao.
- Retorna o estado atual (
Como o EventSub agora tambem assina stream.online/stream.offline (alem do reward de channel points), rode POST /twitch/eventsub/subscribe novamente apos o deploy para registrar as novas assinaturas.
Integracao finalizada com resgate de power-up na Twitch e feedback sonoro na stream.
Fluxo geral:
- A Twitch envia o evento para o webhook da API.
- O listener processa o payload e atualiza o estado em memoria.
- A webpage do OBS consulta esse estado via JavaScript.
- O JavaScript reage ao novo evento e toca o audio configurado.
- O mesmo padrao permite acionar a API por comandos do chat, por exemplo via Nightbot, usando os endpoints HTTP expostos.
Esse fluxo permite unir comandos do chat, eventos da Twitch e resposta visual/sonora na stream sem depender de extensoes pesadas no OBS.
Twitch
TWITCH_CHANNEL_IDTWITCH_DEV_IDTWITCH_SECRETTWITCH_TOKENTWITCH_TTS_REWARD_IDS(IDs dos rewards que acionam TTS)TWITCH_TTS_REWARD_ID(fallback para um ID unico de reward TTS)TWITCH_TTS_LANG(idioma TTS, padrao:pt-BR)
Steam
STEAM_WEB_API_KEY(ouSTEAM_API_KEY)STEAM_TARGET_STEAMID64
PIPER TTS (sintese de fala local)
PIPER_TTS_MODEL_PATH(caminho para o arquivo.onnx, ex:/tts-model/pt_BR-cadu-medium.onnx)PIPER_TTS_CONFIG_PATH(caminho para o arquivo.jsondo modelo)
GitHub (publicacao de dados)
PUBLIC_BASE_URL(exemplo:https://seu-servico.onrender.com)GITHUB_TOKEN,GITHUB_OWNER,GITHUB_REPOGITHUB_FILE_PATHpara publicardados.jsonGITHUB_STEAM_GAMES_FILE_PATHpara publicarsteam_games.json
Para fazer um reward da Twitch falar no overlay do OBS, configure:
TWITCH_TTS_REWARD_IDSTWITCH_TTS_REWARD_ID(single reward ID fallback)TWITCH_TTS_LANG(opcional, padraopt-BR)PIPER_TTS_MODEL_PATHePIPER_TTS_CONFIG_PATHpara apontar para o modelopt_BR-cadu-medium
Quando um reward configurado e resgatado:
- O backend gera um arquivo de audio WAV usando Piper TTS com a voz
pt_BR-cadu-medium. - O payload enviado para o overlay inclui
tts_audio_url. - O JavaScript do OBS toca esse arquivo (em vez de depender apenas do
speechSynthesislocal).
O texto falado vem de user_input. Se vier vazio, o backend monta uma frase curta com user_name + reward title.
Teste rapido sem Twitch:
/twitch/powerup/test?text=Mensagem+de+testeSe text for omitido, o teste segue o caminho legado de audio (nossa.ogg).
Observacoes:
- Os arquivos TTS gerados ficam em
/mp3/tts-generated/. - O backend remove arquivos antigos automaticamente para evitar crescimento infinito.
- Se a geracao de audio falhar, o overlay ainda tenta o fallback via
speechSynthesis. - Piper trabalha com modelo local; se o modelo nao estiver disponivel, o backend pode cair no fallback legacy.
A velocidade da fala sintetizada pode ser configurada dinamicamente atraves do arquivo json/tts_config.json, sem necessidade de reiniciar o servico.
O arquivo tts_config.json segue este padrao:
Configuracao global (aplica a todos os modelos):
{
"tts_speed": 1.0
}Configuracao por modelo (sobrescreve global):
{
"pt_BR-cadu-medium": {
"tts_speed": 0.9
},
"pt_BR-jeff-medium": {
"tts_speed": 1.1
},
"tts_speed": 1.0
}- Intervalo valido:
0.5a2.0 - Padrao:
1.0(velocidade normal) - Minimo:
0.5(mais lento, 50% da velocidade original) - Maximo:
2.0(mais rapido, 200% da velocidade original) - Fora do intervalo: valores invalidos sao automaticamente ajustados para o limite mais proximo
Internamente, o PIPER usa o parametro length_scale para ajustar a velocidade:
- Velocidade
< 1.0→length_scalemaior → fala mais lenta - Velocidade
1.0→length_scale = 1.0→ fala normal - Velocidade
> 1.0→length_scalemenor → fala mais rapida
A relacao matematica: length_scale = 1.0 / velocity
Para fazer a voz pt_BR-cadu-medium falar 20% mais rapido:
{
"pt_BR-cadu-medium": {
"tts_speed": 1.2
}
}O backend valida a configuracao a cada geracao de audio. Se houver erro na leitura do arquivo ou valor invalido, o sistema usa o padrao 1.0.
PIPER é um sintetizador de fala de texto local de codigo aberto sob a licenca MIT.
Copyright (c) 2023 Rhasspy Project
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
- Os modelos de voz (ONNX) estao sob licencas especificas por voz, incluindo licencas CC0 1.0 Universal.
Para mais informacoes, consulte: https://github.com/rhasspy/piper
Quando um reward TTS é resgatado na Twitch:
- O backend le
tts_config.jsonpara obter a velocidade configurada. - A velocidade é aplicada ao modelo PIPER especificado (ex:
pt_BR-cadu-medium). - O audio sintetizado é gerado com a velocidade definida.
- O arquivo WAV é salvo em
/mp3/tts-generated/com um hash unique. - A URL do audio é enviada ao overlay para reproducao.
O fluxo foi desenhado para ser simples de operar na live:
- O chat dispara um comando do Nightbot.
- O Nightbot chama um endpoint da API.
- A API atualiza o estado interno ou os dados do jogo.
- O listener JavaScript da pagina do OBS observa o estado ou consome o endpoint.
- A stream recebe o feedback sonoro ou a atualizacao visual.
-
POST /twitch/eventsub- Callback da Twitch EventSub
-
GET|POST /twitch/eventsub/subscribe- Cria assinatura EventSub para
channel.channel_points_custom_reward_redemption.add
- Cria assinatura EventSub para
-
GET /twitch/powerup/state- Estado simples (seq/ultimo reward) para polling da webpage
-
GET /obs/powerup- Webpage blank para Browser Source do OBS
-
GET /obs/nossa.mp3- Audio tocado quando houver novo trigger do power-up na stream
-
GET /mp3/<arquivo>.mp3- Arquivos MP3 estaticos e TTS gerado (
/mp3/tts-generated/...)
- Arquivos MP3 estaticos e TTS gerado (
-
GET|POST /twitch/powerup/test- Endpoint de teste manual para disparar power-up
- Com
?text=...gera TTS em arquivo e envia para o overlay
Novo overlay para Torchlight com roleta interativa que gira quando um reward específico é resgatado na Twitch.
- Usuario resgata o reward "Roleta de FE (Torchlight)" na Twitch.
- A Twitch envia o evento para o webhook em
/twitch/eventsub. - O backend atualiza
POWERUP_EVENT_STATEcomseq,last_rewardelast_event. - A pagina OBS em
/torchlight/roleta/obsfaz polling a cada 1 segundo em/twitch/powerup/state. - Ao detectar mudanca no
seq, a pagina identifica que é um novo evento. - A roleta gira por 4 segundos com animacao suave (cubic easeOut).
- Ao final da animacao, o centro exibe o valor sorteado (50, 75, 100, 125, 200 ou 300).
- A roleta fica visivel por 30 segundos e desaparece automaticamente.
No painel de Creator Dashboard da Twitch, crie um reward customizado com:
- Titulo:
Roleta de FE (Torchlight) - ID do reward:
28bce937-6821-426c-a186-713398767e9c(ou outro, configuravel) - Custo: à sua escolha (recomendado 1000-5000 pontos)
- Imagem: opcional, logo de Torchlight
-
GET /torchlight/roleta/obs- Retorna a pagina HTML com estrutura da roleta (pointer, wheel, labels, center display)
-
GET /torchlight/roleta/obs.js- JavaScript com logica de polling, animacao, som e matching de valores
-
GET /torchlight/roleta/obs.css- CSS com estilo do wheel (conic-gradient), labels posicionadas via trigonometria, pointer (triangulo vermelho no topo)
-
GET /twitch/powerup/state- Retorna JSON com
seq(contador de atualizacoes),last_reward(ID do ultimo reward) elast_event(timestamp) - Exemplo:
{"seq": 42, "last_reward": "28bce937...", "last_event": 1704067200}
- Retorna JSON com
-
GET|POST /twitch/powerup/test- Testa manualmente o trigger da roleta sem precisar resgatar o reward na Twitch
- Parametros opcionais:
?label=Roleta%20de%20FE%20%28Torchlight%29- filtra por titulo do reward (case-insensitive)?id=28bce937-6821-426c-a186-713398767e9c- filtra por ID do reward
- Exemplo:
http://localhost:5000/twitch/powerup/test?label=Roleta%20de%20FE
- Valores: 6 fatias com numeros [50, 75, 100, 125, 200, 300]
- Peso: Distribuicao em porcentagem 22% / 22% / 22% / 22% / 8% / 4%, mantendo a fatia de 300 menor
- Cores: Cada fatia tem cor distinta (vermelho, azul, verde, amarelo, roxo, laranja)
- Animacao: Gira 6+ voltas completas + angulo aleatorio extra, desacelerando suavemente
- Som: Tom de 1kHz tocado durante a rotacao a cada 10 graus
Esta secao explica como criar os valores sensiveis sem salvar segredos no repositorio.
O TWITCH_CLIENT_SECRET nao e gerado pelo projeto nem pelo Cloud Run. Ele e criado no painel da Twitch.
Passo a passo:
- Acesse o portal de desenvolvedor da Twitch.
- Abra a aplicacao usada por este projeto.
- Entre em
Settings. - Clique em
New SecretouRegenerate Secret. - Copie o novo valor imediatamente, porque a Twitch nao mostra esse segredo de novo.
- Guarde esse valor apenas no Cloud Run ou no Secret Manager, nunca no Git.
O TWITCH_WEBHOOK_SECRET e um valor definido por voce para assinar as notificacoes do EventSub.
Passo a passo recomendado:
- Gere uma string longa e aleatoria, por exemplo com um gerador de senhas.
- Nao reutilize o
TWITCH_CLIENT_SECRETcomo webhook secret. - Salve esse valor apenas como variavel segura no Cloud Run ou no Secret Manager.
No Cloud Run, configure as variaveis assim:
TWITCH_DEV_IDouTWITCH_CLIENT_ID: o client id da aplicacao TwitchTWITCH_CLIENT_SECRET: o client secret novo da TwitchTWITCH_WEBHOOK_SECRET: o segredo do webhook EventSubTWITCH_SECRET: mantenha apenas se precisar de compatibilidade temporaria
Exemplo via gcloud:
gcloud run services update streambadmystake --region southamerica-east1 --set-env-vars TWITCH_CLIENT_SECRET=NOVA_SECRET_AQUI,TWITCH_WEBHOOK_SECRET=SEGREDO_WEBHOOK_AQUIDepois de atualizar as variaveis:
- Chame
GET /debug/envpara confirmar se as variaveis chegaram ao ambiente. - Chame
POST /twitch/eventsub/subscribepara validar se a Twitch aceita o client secret. - Se a resposta continuar com
invalid client secret, gere um novo secret no painel da Twitch e atualize o Cloud Run novamente.
Nunca salve no Git:
- tokens
- secrets
- chaves de API
- credenciais do Cloud Run
Use apenas o Cloud Run, Secret Manager ou variaveis de ambiente fora do repositorio para esses valores.
- Precision: O valor exato apontado pelo triangulo vermelho (topo) e calculado usando trigonometria e conic-gradient com
from -90deg
- Crie uma Browser Source e aponte para
https://seu-servico.onrender.com/torchlight/roleta/obs. - Configure as dimensoes: largura e altura
420px(quadrado para o wheel). - Habilite
Atualizar pagina quando cena fica inativapara evitar cache. - Coloque a source em uma cena dedicada ou sobreposição da cena de Torchlight.
- A roleta ficara invisivel ate que o reward seja resgatado.
- Para testar sem resgatar, chame:
curl http://localhost:5000/twitch/powerup/test?label=Roleta%20de%20FE%20%28Torchlight%29
Dentro da pagina HTML (/torchlight/roleta/obs), o atributo data-default-reward define qual reward ativa a roleta:
<div id="wrapper" data-default-reward="28bce937-6821-426c-a186-713398767e9c,Roleta de FE (Torchlight)">Pode-se filtrar por ID, titulo ou ambos (separados por virgula). A filtragem e case-insensitive.
Se necessario, pode-se passar ?reward=ID ou ?label=TITULO como query string na URL da Browser Source para sobrescrever.
Novo overlay para exibir um cronômetro que começa em 03:00:00 e realiza contagem regressiva até 00:00:00.
- A pagina OBS em
/obs/cronometroé carregada inicialmente invisível. - Ao fazer um GET para
/obs/cronometro?action=start, o cronômetro fica visível e inicia a contagem regressiva de 3 horas. - O cronômetro decrementa 1 segundo a cada intervalo até chegar a 00:00:00.
- Após 3 segundos de finalização (00:00:00), o cronômetro desaparece automaticamente e reseta para 03:00:00.
- A formatação segue o mesmo padrão do death counter OBS (Arial Black, branca, 72px, efeito glow).
-
GET /obs/cronometro- Retorna a página HTML com o cronômetro (inicialmente invisível)
- Query parameters:
?action=start- inicia a contagem regressiva automaticamente ao carregar a página?time=SEGUNDOS- define um tempo inicial diferente de 10800 segundos (ex:?time=600começa em 00:10:00)
- Exemplo:
https://seu-servico.onrender.com/obs/cronometro?action=start
-
GET /obs/cronometro.js- JavaScript com lógica de contagem regressiva, formatação HH:MM:SS e visibilidade
-
GET /obs/cronometro.css- CSS com estilo idêntico ao death counter (fonte, sombra, alinhamento)
- Duração: Começa em 03:00:00 (10800 segundos / 3 horas)
- Formato: HH:MM:SS (ex: 03:00:00, 02:45:30, 00:00:01, 00:00:00)
- Visibilidade inicial: Invisível até acionado
- Estilo: Arial Black, branca, 72px, text-shadow com efeito de glow
- Auto-reset: Após atingir 00:00:00, aguarda 3 segundos e desaparece, reseta para 03:00:00
- API JavaScript: Expõe
window.cronometroAPIpara controle manual
O cronômetro expõe as seguintes funções via window.cronometroAPI:
window.cronometroAPI.start() // Inicia a contagem regressiva
window.cronometroAPI.pause() // Pausa a contagem
window.cronometroAPI.resume() // Retoma a contagem a partir do ponto pausado
window.cronometroAPI.reset() // Para e reseta para 03:00:00
window.cronometroAPI.setTime(segundos) // Define novo tempo (ex: 120 para 02:00:00)
window.cronometroAPI.getTime() // Retorna tempo restante em segundos- Crie uma Browser Source e aponte para
https://seu-servico.onrender.com/obs/cronometro. - Configure as dimensões desejadas (sugerido: 800x200 ou similar, com a fonte em 72px o cronômetro fica grande).
- Adicione a Browser Source em uma cena ou sobreposição dedicada.
- Para iniciar o cronômetro automaticamente ao carregar a cena, altere a URL para:
https://seu-servico.onrender.com/obs/cronometro?action=start
- Alternativamente, pode-se chamar via comando do Nightbot:
curl https://seu-servico.onrender.com/obs/cronometro?action=start- Ou usar o console do navegador (F12) para chamar
window.cronometroAPI.start()
Iniciar com tempo customizado:
Use o parâmetro ?time=SEGUNDOS para começar com um tempo diferente:
https://seu-servico.onrender.com/obs/cronometro?action=start&time=60
Isso iniciará com 00:01:00 (1 minuto) em vez de 03:00:00.
Controle via OBS Lua Script ou Comando:
Se integrado com automações externas, pode-se fazer GET para:
# Iniciar
curl "http://localhost:5000/obs/cronometro?action=start"
# Com tempo customizado
curl "http://localhost:5000/obs/cronometro?action=start&time=300"E no console JS da página (F12):
// Iniciar
window.cronometroAPI.start()
// Pausar
window.cronometroAPI.pause()
// Retomar
window.cronometroAPI.resume()
// Resetar
window.cronometroAPI.reset()
// Definir tempo (em segundos)
window.cronometroAPI.setTime(120) // 2 minutosGET /steam/achievements/-
Retorna as conquistas desbloqueadas e o total de conquistas do jogo da stream usando o SteamID64 configurado no Render.
-
Se
?game=nao for enviado, usa o jogo atual da live vindo da Twitch. -
Resposta em texto puro no formato:
Outer Wilds: 2 de 31 (6,45% concluído) -
Atualmente o mapping inclui:
Outer Wilds -> 753640 -
Quando um jogo novo precisa ser resolvido, o mapa local
steam_games.jsone atualizado e pode ser publicado automaticamente no GitHub se as variaveis de publish estiverem configuradas. -
Requer as variaveis de ambiente
STEAM_WEB_API_KEY(ouSTEAM_API_KEY) eSTEAM_TARGET_STEAMID64.
-
O arquivo dados.json guarda os contadores por jogo. Exemplo:
{
"outer-wilds": {
"mortes": 20
}
}Isso permite manter o historico por jogo e usar a mesma base para futuras expansoes.
- Adicione uma Browser Source apontando para
https://seu-servico.onrender.com/obs/powerup. - Habilite
Control audio via OBSna Browser Source para garantir saida no mixer. - Dispare a criacao da assinatura em
/twitch/eventsub/subscribe. - Teste manual com
/twitch/powerup/test?text=Mensagem+de+teste. - Ao ocorrer um novo resgate na Twitch, a pagina deve tocar o audio gerado para TTS (ou audio mapeado quando nao for TTS).
Dashboard web para visualizar os subscribers do canal na Twitch, sem precisar de Postman ou consultar JSON na mao.
Diferente do resto da API, esse dashboard nao guarda nada em memoria nem em disco: a cada acesso, a pagina refaz o fluxo completo de autorizacao da Twitch, busca os subscribers, monta as estatisticas e descarta tudo assim que a resposta e enviada. Isso porque o endpoint GET /helix/subscriptions da Twitch exige um user access token do proprio broadcaster (diferente do app token ja usado pra EventSub), e o projeto optou por nunca persistir esse token.
Fluxo ao acessar /twitch/subscribers:
- Redireciona para a tela de autorizacao da Twitch (
/twitch/subscribers/authorize), pedindo o escopochannel:read:subscriptions. - Se a conta que autoriza ja aprovou o app antes, a Twitch redireciona de volta sem precisar mostrar a tela de novo (silencioso).
- O callback (
/twitch/subscribers/callback) troca ocodepor umaccess_token, pagina todos os subscribers na Helix, calcula as estatisticas e renderiza o dashboard — token e dados descartados ao fim da requisicao. - Se qualquer etapa falhar (autorizacao negada, token invalido, canal sem Afiliado/Parceiro, variavel faltando), uma pagina de erro amigavel e exibida.
Recursos do dashboard:
- Cards com Total de Subscribers, Tier 1/2/3, Gift Subs, Regular Subs e Gifters Unicos.
- Tabela com usuario, login, tier, plano, gift/regular, gifter, broadcaster e user ID.
- Busca instantanea, ordenacao por coluna, filtros por tier e por tipo (gift/regular), paginacao.
- Exportacao para CSV e para Excel (
.xlsx, via SheetJS carregado por CDN).
Configuracao necessaria (alem das variaveis Twitch ja usadas em EventSub):
- Registrar
{PUBLIC_BASE_URL}/twitch/subscribers/callbackcomo Redirect URI no painel de desenvolvedor da Twitch, na mesma aplicacao deTWITCH_DEV_ID. - Quem autorizar precisa estar logado na propria conta do canal (a mesma do
TWITCH_CHANNEL_ID), senao a Twitch nega acesso aos subscribers dessebroadcaster_id.
Endpoints:
-
GET /twitch/subscribers- Ponto de entrada do dashboard, redireciona para o fluxo de autorizacao.
-
GET /twitch/subscribers/authorize- Monta a URL de autorizacao da Twitch e redireciona.
-
GET /twitch/subscribers/callback- Recebe o retorno da Twitch, troca o codigo por token, busca os subscribers e renderiza o dashboard (ou a pagina de erro).
app.py: API principal.dados.json: arquivo com os dados por jogo.py/activity_manager.py: estado ACTIVE/IDLE que controla quando trabalho de fundo pode rodar.py/twitch_oauth.py: fluxo de Authorization Code da Twitch (usado pelo dashboard de subscribers).py/twitch_subscribers_service.py: consulta paginada aos subscribers na Helix.py/subscribers_stats.py: calculo das estatisticas exibidas no dashboard.py/templates/: templates Jinja2 usados pelo dashboard de subscribers.obs_browser_refresh.lua: script para ser adicionado dentro do proprio OBS (Tools > Scripts) e forcar o refresh da Browser Source.obs_powerup.html: webpage para Browser Source que escuta trigger de power-up e toca audio.
O arquivo obs_browser_refresh.lua existe para atualizar o Browser Source diretamente dentro do OBS, evitando dependencia do plugin/WebSocket para esse refresh.
- Instale dependencias:
pip install -r requirements.txt- Execute a API:
python app.py-
GET /death/get -
GET /death/read- Retorno: apenas o numero de mortes (exemplo:
16)
- Retorno: apenas o numero de mortes (exemplo:
-
GET /death/read/obs- Retorno: texto para overlay (exemplo:
16 mortes)
- Retorno: texto para overlay (exemplo:
-
GET /death/current-game- Retorno JSON com
game_name,game_keyemortesdo jogo atual
- Retorno JSON com
-
GET /death/all- Retorno JSON com total geral e todos os jogos no formato salvo em
dados.json
- Retorno JSON com total geral e todos os jogos no formato salvo em
-
GET /stream/current-game- Retorno: apenas o
game_nameatual da stream em texto puro (ex:Outer Wilds)
- Retorno: apenas o
-
GET|POST /death/increment- Soma 1 no contador do jogo atual da stream
-
GET|POST /death/decrement- Subtrai 1 no contador do jogo atual da stream
-
GET /death/clear- Limpa os dados e volta para o estado padrao
-
GET|POST /death/save- Salva o contador por jogo no mesmo formato dos demais endpoints de mortes
- Parametros aceitos (prioridade):
jogo(ougame)mortes
- Compatibilidade legada mantida:
keyevalue
- Exemplo de body JSON recomendado:
{
"jogo": "torchlight infinite",
"mortes": 860
}- Exemplo de persistencia em `dados.json`:
{
"torchlight-infinite": {
"mortes": 860
}
}- Retorno: numero salvo em texto puro (ex: `860`)
GET /GET /healthz
Todas retornam status 200 quando o servico esta saudavel.