Pular para o conteúdo principal

Experimente a API de desenvolvedor de extensões.

Use este guia se você quiser criar uma extensão Chastify, hospedar uma página de extensão em iframe ou chamar a API de desenvolvedor a partir do seu próprio backend.

Esta página é o ponto de partida: qual modo escolher, o que chamar primeiro e para onde ir em seguida.

Para comportamentos concretos de extensão, como bloqueadores de desbloqueio, ações regulares necessárias, recompensas e punições, consulte Recursos da API de extensão.

dica

Quer controlar apenas a sua própria fechadura?

Se você não precisa criar uma extensão pública, a página API Externa e Programas é a maneira mais fácil de começar. Basta criar um token DEV e chamar endpoints REST simples — sem necessidade de configuração de extensão, iframe ou gerenciamento de sessão. Ela oferece suporte a adicionar/remover tempo, congelar, executar tarefas, enviar comandos para dispositivos e muito mais.

Para que serve esta API?

A API de desenvolvedor de extensões permite criar experiências de extensão de terceiros que são executadas dentro de sessões de bloqueio Chastify.

Com ele, você pode:

  • Leia a sessão e o contexto de bloqueio (session.get para extensões, /api/apps/v1/session para sua própria automação de bloqueio)
  • Leia os dados pertencentes à extensão por sessão de bloqueio (state.get) e grave-os a partir do seu backend (PUT/PATCH /state)
  • Armazene arquivos de imagem pertencentes à extensão com o armazenamento R2 gerenciado por Chastify (files.*)
  • Adicionar ações de extensão da interface do usuário em cartões de bloqueio (metadata.homeActions)
  • Fluxo de desbloqueio de portão com bloqueadores de desbloqueio pertencentes à extensão (metadata.unlockBlockers)
  • Acione ações de bloqueio a partir de um servidor confiável (adicionar/remover tempo, congelar/descongelar, aplicar patch de configurações)
  • Acione a tarefa e as ações de higiene (task.assign, task.start_timer, task.complete, hygienic_unlock.start)
  • Submeta ações regulares com suporte a contadores/cadência.
  • Enviar comandos de dispositivo compatíveis quando disponíveis
  • Escreva entradas de log de extensão personalizadas para bloquear o histórico.

O que você pode construir

O conjunto ideal de funcionalidades depende de onde reside a confiança.

Extensões de iframe exclusivas para o frontend podem criar experiências com foco na interface do usuário que não precisam de mutação de bloqueio confiável:

  • Configure páginas que coletam configurações de extensão.
  • Painéis que leem o contexto da sessão
  • Interfaces de usuário para quebra-cabeças, listas de tarefas ou jogos que leem o estado da sessão e enviam o progresso verificado por meio de um servidor.
  • Fluxos baseados em mídia que leem arquivos de extensão já armazenados por Chastify
  • Pontos de entrada de ação da página inicial que abrem seu iframe com uma intenção

Extensões com suporte no servidor podem criar recursos que afetam o bloqueio, pois seu backend verifica os resultados antes de chamar APIs privilegiadas:

  • Sistemas de tarefas ou hábitos com requisitos de desbloqueio
  • Requisitos diários ou semanais com punições programadas para o descumprimento do prazo.
  • Jogos que recompensam o sucesso ou penalizam o fracasso com alterações no tempo de bloqueio
  • Fluxos de verificação que removem bloqueadores de desbloqueio após a validação no servidor.
  • Fluxos complementares de controle de dispositivos usando comandos de dispositivo compatíveis
  • Fluxos de trabalho de webhook/banco de dados que mantêm o estado da extensão fora do iframe.

Os programas externos servem para automatizar de forma privada a sua própria fechadura ativa:

  • Scripts locais
  • Painéis pessoais
  • Ferramentas de automação que utilizam uma chave DEV para todo o usuário.

Escolha seu modo

Escolha um destes modos:

  1. Hosted iframe extension: hospede uma interface de usuário iframe estática no Cloudflare Pages ou em um serviço similar. Use a ponte para configuração, contexto de sessão e leituras seguras. Não use este modo sozinho para gravações de estado, recompensas, punições, conclusão de desbloqueio ou progresso de requisitos confiáveis.
  2. Server-backed extension: hospeda a interface do usuário do iframe e executa seu próprio backend. O iframe envia seu código de inicialização mainToken para o seu backend, e o seu backend chama a API de extensão Chastify com uma chave de API de desenvolvedor com escopo de aplicativo, além de x-chastify-main-token. Use este modo para ações privilegiadas, desbloqueio de bloqueadores, progresso confiável, recompensas, punições, webhooks e bancos de dados externos.
  3. External API & Programs: utilize uma chave DEV para todo o usuário, para scripts, programas locais ou automações que controlam sua própria fechadura ativa. Este não é o modo adequado para usuários terceirizados que instalam sua extensão.

Se você estiver realizando testes rapidamente, comece com o modo iframe para a interface do usuário e leituras seguras. Adicione um backend antes de implementar gravações de estado, recompensas confiáveis, alterações de tempo, progresso de requisitos agendados ou conclusão de bloqueadores de desbloqueio.

cuidado

O código do iframe não representa um limite de confiança. Tudo o que estiver visível no iframe, incluindo payloads de hash e tokens de inicialização, pode ser inspecionado e reproduzido pelo usuário.

Primeiros 10 minutos (Modo iframe)

  1. Leia o conteúdo location.hash do iframe Chastify aberto.
  2. Criar uma solicitação de ponte para session.get.
  3. Confirme a resposta com type: "chastify:ext:resp" e ok: true.
  4. O estado de teste é lido com state.get.
  5. Adicionar redimensionamento automático e suporte a temas para que o iframe se comporte corretamente na interface do usuário.

O suporte a temas faz parte de um iframe pronto para produção. Chastify passa valores ui no hash de inicialização e envia atualizações de tema em tempo real enquanto o iframe estiver aberto. Consulte Temas de iframe para exemplos de temas claros/escuros e padrões Tailwind com segurança de contraste.

Valores de carga útil obrigatórios:

  • bridge.nonce
  • bridge.parentOrigin
  • sessionId
  • lockId

Exemplo de solicitação de ponte:

{
"type": "chastify:ext:req",
"v": 1,
"id": "request-id", // unique id per request
"nonce": "nonce-from-hash",
"action": "session.get",
"payload": {}
}

Exemplo de resposta da ponte:

{
"type": "chastify:ext:resp",
"v": 1,
"id": "request-id",
"ok": true,
"data": {}
}

Ações Essenciais para Aprender Primeiro

  • session.get
  • state.get
    Leia o armazenamento JSON pertencente à extensão para a sessão de bloqueio. Grave o estado a partir do seu backend com as credenciais da API de desenvolvedor.
  • files.capabilities, files.list, files.get Utilize leituras de armazenamento de arquivos para mídias binárias, como imagens de quebra-cabeças ou pré-visualizações geradas. Armazene os IDs dos arquivos no estado gravado no backend e, em seguida, atualize os URLs assinados com files.get.
  • metadata.get Leia os bloqueadores de desbloqueio de sessão de bloqueio e as ações/intenções da página inicial do cartão de extensão.
  • regularActions.get

Alterações de sessão, como escritas de estado, envio de ações regulares, upload/exclusão de arquivos em tempo de execução, alterações de horário, atualizações de bloqueadores de desbloqueio, conclusão de tarefas, início de verificações de segurança e comandos de dispositivo, devem ser chamadas a partir do seu backend com uma chave de API de desenvolvedor. O código iframe do navegador não é confiável para essas ações.

URLs completas da API (compatíveis)

Domínio base: https://chastify.net

APIs de sessão de extensão (/api/extensions/*)

Essas rotas possuem diferentes modos de acesso. Não considere toda a superfície /api/extensions/* como segura para iframes.

As rotas seguras de ponte iframe são roteadas através do pai Chastify após solicitações de ponte postMessage:

  • GET https://chastify.net/api/extensions/sessions/:sessionId
  • GET https://chastify.net/api/extensions/sessions/:sessionId/state
  • GET https://chastify.net/api/extensions/sessions/:sessionId/metadata
  • GET https://chastify.net/api/extensions/sessions/:sessionId/regular-actions
  • GET https://chastify.net/api/extensions/sessions/:sessionId/files/capabilities
  • GET https://chastify.net/api/extensions/sessions/:sessionId/files
  • GET https://chastify.net/api/extensions/sessions/:sessionId/files/:fileId

Rotas de extensão instaladas somente no backend exigem uma chave de API de desenvolvedor com escopo de aplicativo e o token de inicialização do iframe:

Authorization: Bearer YOUR_APP_SCOPED_DEVELOPER_KEY
x-chastify-main-token: MAIN_TOKEN_FROM_IFRAME_HASH
informação

Este modelo de dois tokens vincula uma solicitação de backend tanto ao desenvolvedor da extensão (Authorization) quanto à sessão de extensão atualmente aberta (x-chastify-main-token).

  • PATCH https://chastify.net/api/extensions/sessions/:sessionId/metadata
  • PUT https://chastify.net/api/extensions/sessions/:sessionId/state
  • PATCH https://chastify.net/api/extensions/sessions/:sessionId/state
  • PATCH https://chastify.net/api/extensions/sessions/:sessionId/regular-actions/config
  • POST https://chastify.net/api/extensions/sessions/:sessionId/regular-actions
  • POST https://chastify.net/api/extensions/sessions/:sessionId/files
  • DELETE https://chastify.net/api/extensions/sessions/:sessionId/files/:fileId
  • POST https://chastify.net/api/extensions/sessions/:sessionId/logs/custom
  • POST https://chastify.net/api/extensions/sessions/:sessionId/notifications/custom
  • POST https://chastify.net/api/extensions/sessions/:sessionId/device-command
  • POST https://chastify.net/api/extensions/sessions/:sessionId/action
  • POST https://chastify.net/api/extensions/sessions/:sessionId/requirements/progress

APIs de token de backend (/api/apps/v1/*)

Use Authorization: Bearer <user-wide DEV token>. Esses endpoints gerenciam as sessões de bloqueio ativas do proprietário do token e são destinados a scripts/programas de API externa, não a sessões de extensões de terceiros instaladas.

  • GET https://chastify.net/api/apps/v1/session
  • GET https://chastify.net/api/apps/v1/state
  • PUT https://chastify.net/api/apps/v1/state
  • PATCH https://chastify.net/api/apps/v1/state
  • GET https://chastify.net/api/apps/v1/metadata
  • PATCH https://chastify.net/api/apps/v1/metadata
  • POST https://chastify.net/api/apps/v1/action
  • POST https://chastify.net/api/apps/v1/lock/apply-time
  • POST https://chastify.net/api/apps/v1/lock/freeze
  • POST https://chastify.net/api/apps/v1/lock/unfreeze
  • POST https://chastify.net/api/apps/v1/logs/custom

Comandos de ponte Iframe

Os comandos da ponte são enviados por iframe (chastify:ext:req) e roteados pelo iframe pai Chastify. A ponte é intencionalmente limitada a operações de interface do usuário seguras/de sessão.

  • session.get -> GET https://chastify.net/api/extensions/sessions/:sessionId
  • state.get -> GET https://chastify.net/api/extensions/sessions/:sessionId/state
  • files.capabilities -> GET https://chastify.net/api/extensions/sessions/:sessionId/files/capabilities
  • files.list -> GET https://chastify.net/api/extensions/sessions/:sessionId/files
  • files.get -> GET https://chastify.net/api/extensions/sessions/:sessionId/files/:fileId com { "fileId": "file_record_id" }
  • metadata.get -> GET https://chastify.net/api/extensions/sessions/:sessionId/metadata
  • regularActions.get -> GET https://chastify.net/api/extensions/sessions/:sessionId/regular-actions

Os endpoints de mutação de sessão são chamadas diretas à API do backend, não comandos de ponte iframe. Isso inclui gravações de estado, envio de ações regulares e upload/exclusão de arquivos em tempo de execução, pois o código do iframe pode ser controlado pelo usuário.

Exemplos de API de sessão de backend

Seu servidor deve enviar ambos os cabeçalhos para chamadas privilegiadas de extensões instaladas:

Authorization: Bearer YOUR_APP_SCOPED_DEVELOPER_KEY
x-chastify-main-token: MAIN_TOKEN_FROM_IFRAME_HASH

Exemplos de ações de backend:

  • metadata.patch -> PATCH /api/extensions/sessions/:sessionId/metadata
  • regularActions.submit -> POST /api/extensions/sessions/:sessionId/regular-actions
  • files.upload -> POST /api/extensions/sessions/:sessionId/files
  • files.delete -> DELETE /api/extensions/sessions/:sessionId/files/:fileId
  • lock.applyTime -> POST /api/extensions/sessions/:sessionId/action com { "name": "add_time", "params": <deltaSeconds> }
  • lock.freeze -> POST /api/extensions/sessions/:sessionId/action com { "name": "freeze", "params": { "durationSeconds": 900 } }
  • lock.unfreeze -> POST /api/extensions/sessions/:sessionId/action com { "name": "unfreeze", "params": {} }
  • lock.settings.patch -> POST /api/extensions/sessions/:sessionId/action com { "name": "settings.patch", "params": { ... } }
  • task.assign -> POST /api/extensions/sessions/:sessionId/action
  • task.start_timer -> POST /api/extensions/sessions/:sessionId/action com { "name": "task.start_timer", "params": {} }
  • task.complete -> POST /api/extensions/sessions/:sessionId/action com { "name": "task.complete", "params": { "successful": true } }
  • hygienic_unlock.start -> POST /api/extensions/sessions/:sessionId/action com { "name": "hygienic_unlock.start", "params": { "durationSeconds": 900 } }
  • pillory.end -> POST /api/extensions/sessions/:sessionId/action com { "name": "pillory.end", "params": {} }
  • device.command -> POST /api/extensions/sessions/:sessionId/device-command
  • logs.custom -> POST /api/extensions/sessions/:sessionId/logs/custom
  • notifications.custom -> POST /api/extensions/sessions/:sessionId/notifications/custom
  • requirements.progress -> POST /api/extensions/sessions/:sessionId/requirements/progress

Comportamento de token, escopo, revogação e auditoria

Use o token correto para o limite de confiança correto.

aviso

As chaves de API de desenvolvedor são confidenciais. Se alguma delas for exposta ao código do navegador, revogue-a imediatamente e altere a variável de ambiente do backend.

Token de inicialização do iframe (mainToken)

  • Entregue no hash do iframe quando um usuário abre a página da extensão instalada.
  • Visível no navegador por padrão. Identifica a sessão da extensão aberta, mas não é um segredo do servidor.
  • Duração limitada. Os tokens de lançamento atuais expiram após 10 horas; atualize-os reabrindo a página da extensão.
  • Necessário como x-chastify-main-token quando seu backend chama rotas de sessão de extensão instalada, para que Chastify possa vincular a solicitação do backend ao usuário/sessão que abriu a extensão.
  • Não deve ser usado isoladamente para autorizar alterações de horário, desbloqueio de bloqueadores, conclusão de tarefas, comandos de dispositivos, uploads/exclusões em tempo de execução, registros personalizados ou notificações personalizadas.

Chave de API de desenvolvedor com escopo de aplicativo

  • Criado a partir da interface de desenvolvedor para um aplicativo de extensão.
  • Segredo exclusivo do backend. Nunca o inclua em JavaScript de iframe, pacotes de aplicativos móveis, configurações de hospedagem estática ou logs legíveis pelo navegador.
  • Utilizado com Authorization: Bearer YOUR_APP_SCOPED_DEVELOPER_KEY e x-chastify-main-token.
  • Só é possível chamar as APIs de sessão da extensão instalada para sessões que correspondam ao aplicativo de extensão e ao token de inicialização.
  • Não expira automaticamente. Revogue-a imediatamente se estiver exposta e alterne a variável de ambiente do seu servidor.

Chave de API de desenvolvedor para todo o usuário

  • Criado a partir da interface do desenvolvedor sem selecionar um aplicativo de extensão.
  • Segredo exclusivo do backend para /api/apps/v1/*.
  • Controla as sessões de bloqueio ativas atuais e futuras do proprietário da chave.
  • Não pode ser usado como credencial de backend para uma extensão de terceiros instalada.

Revogação

  • Chaves de API de desenvolvedor revogadas impedem a autorização de novas solicitações.
  • As chaves revogadas podem ser excluídas permanentemente da interface do desenvolvedor.
  • Novos lançamentos de iframe recebem tokens de lançamento novos. Não armazene mainToken como credencial de longo prazo.

Âmbito de aplicação e funções

  • Os escopos dos aplicativos de extensão descrevem o que o aplicativo tem permissão para solicitar.
  • As chamadas seguras de ponte iframe são limitadas à inicialização da interface do usuário, leituras de sessão, estado pertencente à extensão, leituras de metadados, leituras de ações regulares e leituras de arquivos.
  • As mutações de sessão instalada com privilégios exigem credenciais de backend, mesmo quando a extensão possui um escopo correspondente.
  • Ações sensíveis à função ainda podem ser rejeitadas dependendo se o lançamento pertence a um usuário ou a um detentor da chave.

Auditoria e Limites

  • Os metadados da última utilização da chave da API do desenvolvedor são atualizados quando as chaves são utilizadas.
  • As rotas de ação privilegiadas têm sua taxa de requisições limitada e retornam erros explícitos, como server_credentials_required ou user_wide_dev_key_required, quando o tipo de credencial utilizado está incorreto.
  • Os registros personalizados gravam entradas visíveis no histórico de bloqueios.
  • As notificações personalizadas criam notificações Chastify para o destino solicitado.
  • A cobertura completa de auditoria para cada mutação de extensão privilegiada é rastreada como um item de segurança de produção.

Valores de comando suportados

/api/extensions/sessions/:sessionId/action e /api/apps/v1/action

name suporta:

  • add_time
  • remove_time
  • freeze
  • pillory
  • unfreeze
  • toggle_freeze
  • settings.patch
  • task.assign
  • task.start_timer
  • task.complete
  • hygienic_unlock.start
  • pillory.end

Restrições de ação:

  • As ações da tarefa exigem que a extensão/módulo Tarefas esteja habilitado na fechadura.
  • hygienic_unlock.start requer a Abertura Higiênica ativada e nenhuma sessão de higiene ativa.

Auxiliares de dados de bloqueio session.get

session.get / GET /api/apps/v1/session também inclui lockData com valores booleanos, números e strings compatíveis com o tempo de execução para mecanismos de regras.

Exemplos:

  • Valores booleanos: frozen, unlockable, trusted, taskAssigned (true quando um TaskRun estiver aberto)
  • Números: timeLockedSeconds, timeRemainingSeconds, maxTimeRemainingSeconds, taskPoints
  • strings: lockTitle, campos de perfil do usuário/portador da chave

Privacidade:

  • wearerLastSeenTimestamp e keyholderLastSeenTimestamp são null quando esse usuário desativou o status online (showOnlineStatus === false).

Comandos do dispositivo

As sessões de extensão podem usar o endpoint baseado em sessão:

POST /api/extensions/sessions/:sessionId/device-command

Programas externos com um token DEV podem usar o endpoint v1 mais simples (sem necessidade de ID de sessão):

POST /api/apps/v1/device-command

Ambos aceitam o mesmo corpo de requisição e retornam a mesma resposta. Consulte API externa e programas para obter detalhes completos.

Se a sua extensão tiver uma interface de instalação/configuração:

  1. O pai envia chastify:ext:setup:init (configuração salva + contexto).
  2. Seu iframe de configuração retorna atualizações com chastify:ext:setup:config.
  3. O usuário "parent" pode solicitar a configuração atual com o código chastify:ext:setup:get_config.

Fluxo de tokens de backend (quando você precisa de chamadas do lado do servidor)

Para scripts simples e programas externos, use um token DEV válido para todo o usuário, obtido na página da API do desenvolvedor. Consulte API externa e programas.

Fluxo padrão no modo iframe de extensão:

  1. Chastify emite um token de inicialização de curta duração, visível no navegador, para a sessão de extensão ativa.
  2. O token de inicialização está incorporado no payload do hash do iframe como mainToken.
  3. Seu iframe encaminha mainToken para seu servidor.
  4. Seu backend chama https://chastify.net/api/extensions/sessions/:sessionId/* com Authorization: Bearer <app-scoped Developer API key> e x-chastify-main-token: <mainToken>.

Não envie chaves de API de desenvolvedor para código iframe/navegador. mainToken identifica a sessão de extensão aberta; não é um segredo de backend e não pode ser usado isoladamente para ações privilegiadas.

Recurso manual:

  • Se você precisar buscar/rotacionar o token de inicialização do iframe explicitamente da interface do usuário de terceiros, chame GET https://chastify.net/api/extensions/sessions/:sessionId/auth.

Use o modo de backend se precisar de tarefas agendadas, webhooks ou automação enquanto a página Chastify não estiver aberta. As mutações de sessão da extensão instalada atualmente ainda exigem um token de inicialização de iframe válido por 10 horas; portanto, as tarefas não assistidas devem armazenar a prova pendente e enviá-la na próxima inicialização válida, a menos que você esteja usando um fluxo de servidor nativo/integrado projetado para execução em segundo plano.

informação

Para um comportamento de produção totalmente automatizado, prefira um fluxo de servidor integrado/de primeira parte ou aguarde concessões explícitas de extensão em segundo plano. As APIs de sessão com escopo de aplicativo estão atualmente vinculadas a tokens de inicialização.

Backend vs Cloudflare Pages (Sem servidor)

Use o Cloudflare Pages (sem servidor de backend) quando:

  • Você quer a configuração mais fácil e barata (que possa ser hospedada gratuitamente).
  • Você só precisa de ações controladas pela interface do usuário enquanto o usuário estiver ativamente na página da sua extensão.
  • Você não precisa de gravações de estado de extensão persistidas no servidor.
  • Você está criando protótipos ou desenvolvendo extensões leves rapidamente.

Exemplo de teste local (PowerShell):

cloudflared tunnel --url http://localhost:5174

Utilize o URL público gerado como URL do seu iframe durante os testes.

Utilize um servidor backend quando:

  • Você precisa de tarefas agendadas (comportamento semelhante ao cron).
  • Você precisa de webhooks ou integrações externas.
  • Você precisa de automação/processamento em segundo plano quando ninguém estiver na página da extensão.
  • Você precisa de fluxos de trabalho controlados pelo servidor que devem ser executados continuamente.

Limitação importante na ausência de um backend:

  • Sem execução em segundo plano. Sua extensão só pode executar ações enquanto o usuário tiver o iframe da extensão aberto e estiver interagindo com ele.

Problemas comuns

  • 403 extension_not_enabled: a extensão não está habilitada para esta fechadura.
  • 409 lock_ended: o bloqueio não está mais ativo.
  • 429: limite de taxa atingido.
  • Nenhuma resposta no iframe: verifique nonce, targetOrigin (parentOrigin) e origens permitidas.

Próximos guias