Métodos e eventos do widget
O widget Caputchin envia dois elementos personalizados, e sua página interage com eles em duas direções: você chama métodos no elemento para conduzi-lo, e você escuta eventos que ele emite para reagir. Esta página é a referência exaustiva das duas superfícies.
Todo evento é um CustomEvent despachado com bubbles: true e composed: true, então ele escapa do shadow DOM do widget e você pode escutá-lo diretamente no elemento (ou em qualquer ancestral). O dado está sempre em event.detail.
Os dois elementos de relance
| Elemento | Propósito | Métodos |
|---|---|---|
<caputchin-widget> | Só verificação (proof-of-work / checkbox). | start() |
<caputchin-game> | Anfitrião de jogo, com verificação opcional. | pass(), fail() |
A checkbox do widget tem só start(); ela não expõe pass() / fail(). O anfitrião de jogo não tem start() (sua rodada fica ativa na montagem para inline, ou na primeira abertura de diálogo para modal / fullscreen). Os dois elementos emitem start, pass, error e degraded; o anfitrião de jogo adicionalmente emite dialog-shown e dialog-hidden. A cobertura está na tabela de eventos abaixo.
Métodos
start(), só <caputchin-widget>
Começa a verificação imediatamente. Seu propósito é o gatilho manual: quando o elemento tem trigger="manual", você chama start() para disparar a resolução de proof-of-work do seu próprio gesto (por exemplo, no submit do seu formulário) em vez da checkbox embutida. Com os gatilhos padrão auto / click o elemento conecta sua própria ativação, então você não chama isto.
const widget = document.querySelector("caputchin-widget");
widget.start();O anfitrião de jogo não tem start(). Veja modo manual para o passo a passo completo de conduzi-lo você mesmo.
pass(payload), só <caputchin-game>
Libera o portão de verificação: o visitante teve sucesso. Válido só quando trigger="manual"; chamá-lo em um jogo não manual emite um error com código invalid-call. O primeiro pass() resgata e trava o veredito; chamadas posteriores são silenciosamente ignoradas (uma rodada por sessão).
const widget = document.querySelector("caputchin-game");
widget.pass({ trace: roundRecord });Campo de payload | Tipo | Significado |
|---|---|---|
trace | string | O registro opaco da rodada que seu jogo produz. Numa rodada com portão o servidor o reexecuta para derivar o veredito autoritativo; numa chave sem portão ou só-jogo ele é aceito como está. Passe uma string vazia se a sua interação não tem registro para reexecutar. |
Não há campo score neste método, o portão é o replay do trace pelo servidor, não uma pontuação alegada pelo cliente. (Um score aparece no evento pass, que é o widget reportando de volta a você, não você ao widget.)
Chamar pass() antes de a rodada ter começado (modal / fullscreen, diálogo ainda não aberto) emite um error com código invalid-call. Numa chave só-jogo (sem sitekey) não há portão para liberar, então pass() simplesmente emite o evento pass com token: null.
fail(payload?), só <caputchin-game>
Aborta a rodada: uma derrota definitiva. Válido só quando trigger="manual" (senão invalid-call). Opcional, uma rodada inacabada é tratada como uma não-aprovação de qualquer forma. Ele aborta a verificação em andamento (as checagens de proof-of-work e instrumentação) e expõe um evento error com código game-error-relayed.
widget.fail({ code: "out-of-moves", message: "no moves left" });Campo de payload | Tipo | Significado |
|---|---|---|
code | string (opcional) | Seu código de diagnóstico; exposto como o originalCode do evento error. O padrão é game-failed. |
message | string (opcional) | Motivo legível por humanos. |
Eventos
Escute com addEventListener(type, handler). Todo payload vive em event.detail.
| Evento | Emitido por | event.detail | Dispara quando |
|---|---|---|---|
start | ambos | { gameId: string | null } | A verificação começa (auto na montagem, na ativação, ou via start()). gameId é definido para uma rodada de jogo, null para o widget simples. |
pass | ambos | { token: string | null, score: number | null, durationMs: number | null } | A verificação é liberada. token é o token envolvido para enviar ao seu backend; null numa chave só-jogo (sem sitekey). |
error | ambos | { code, message, severity, originalCode? } | Qualquer coisa de um aviso de config benigno a uma falha grave. Veja o evento error. |
degraded | ambos | { reason: "timeout" | "network" | "http" | "malformed" } | O widget não conseguiu resolver a tempo o tamanho / skin / locale que você configurou, então renderizou com seus valores padrão empacotados. Não é um erro. Veja o evento degraded. |
dialog-shown | <caputchin-game> | { layout: "modal" | "fullscreen" } | Um diálogo de jogo em sobreposição abre (programático ou primeiro clique). |
dialog-hidden | <caputchin-game> | { layout: "modal" | "fullscreen" } | Um diálogo de jogo em sobreposição fecha (programático, Escape, ou clique no fundo). |
O evento pass e o token
O evento pass é a sua deixa de que a verificação teve sucesso, mas ele não é a decisão de confiança. A decisão de confiança é o seu backend confirmando detail.token. Sempre verifique o token no seu backend; nunca conceda acesso só pelo evento de front-end. Em um formulário, o widget também injeta o token como um campo caputchin-token para que um POST de formulário normal o carregue. O score e o durationMs neste evento são análises reportadas pelo cliente e podem ser null; nunca os trate como um sinal de confiança.
O evento error
O evento error carrega um code estável, uma message humana, uma severity, e às vezes um originalCode. Cada código tem uma severidade padrão fixa para que você possa filtrar avisos de "continuou rodando" das falhas de "de fato quebrou" sem codificar à mão uma tabela de código-para-severidade, só leia detail.severity. O conjunto completo de códigos:
code | severity | Significado |
|---|---|---|
invalid-config | warn | Um atributo ou combinação que o widget rejeitou; ele degrada graciosamente e continua rodando. |
invalid-call | warn | Um método chamado quando não era válido (ex.: pass() em um jogo não manual, ou antes de a rodada começar). |
verification-failed | error | A checagem de proof-of-work ou instrumentação (ou o resgate do token) falhou; nenhum token emitido. |
game-load-failed | error | O bundle do jogo não pôde ser resolvido, carregado ou registrado. |
gate-unavailable | error | O servidor retornou uma recusa autoritativa no bootstrap (uma chave com portão não conseguiu fornecer um jogo válido). |
game-error-relayed | error | Um erro surgiu de dentro do jogo (repassado do iframe, ou de um fail() manual). |
detail.originalCode está presente quando o code público é uma generalização de um motivo interno mais específico (por exemplo, uma falha de carregamento de iframe repassada como game-load-failed carrega o iframe-load-failed / iframe-script-blocked / game-not-registered cru em originalCode). Use code para ramificar e originalCode só para diagnósticos.
O evento degraded
Na montagem, o widget faz uma chamada curta ao Caputchin para resolver o tamanho, skin e locale que você configurou (e, para um jogo do marketplace, sua pegada preferida). Se essa chamada falhar ou for lenta demais, o widget não bloqueia nem quebra: ele renderiza com os valores assados no bundle e emite degraded, para que o fallback nunca seja silencioso. O widget continua plenamente funcional após um evento degraded, só a apresentação resolvida pode diferir do que você configurou (um jogo pode aparecer no seu tamanho padrão, ou a checkbox no seu tema padrão). O widget retenta uma resolução lenta antes de cair para o fallback, então degraded significa que as tentativas se esgotaram, não que uma única tentativa foi lenta.
detail.reason diz a você por que a resolução caiu para o fallback, para que você possa exibi-lo na sua própria telemetria:
reason | Significado |
|---|---|
timeout | A resolução não respondeu dentro do seu orçamento de tempo (serviço lento ou inalcançável). |
network | A própria requisição falhou (offline, DNS, bloqueada, ou conexão reiniciada). |
http | O serviço respondeu com um status de erro. |
malformed | O serviço respondeu, mas o corpo não era válido. |
degraded é um aviso, não uma falha, então é deliberadamente não um evento error: uma resolução lenta não deveria disparar os handlers que você liga para falhas reais. Escute-o só se você quiser observar os renders degradados, por exemplo para alertar quando seus visitantes estão vendo a apresentação de fallback.
Escutando, na prática
const widget = document.querySelector("caputchin-game");
const onPass = (e) => {
// send e.detail.token to your backend to verify
};
const onError = (e) => {
if (e.detail.severity === "error") {
console.error(e.detail.code, e.detail.message);
}
};
widget.addEventListener("pass", onPass);
widget.addEventListener("error", onError);
// Clean up when you tear down your view:
widget.removeEventListener("pass", onPass);
widget.removeEventListener("error", onError);Estes são CustomEvents nativos do DOM, então no React você os anexa com um ref e addEventListener (não props JSX onPass); os exemplos de frontend mostram a conexão específica de cada framework. Como todo evento borbulha e é composto, você também pode delegar de um elemento contêiner em vez de vincular cada widget individualmente.
Veja também
- Adicionar o widget: os atributos de configuração que você define no markup (o lado de entrada para este lado de saída).
- Conduza a verificação você mesmo com o modo manual: o tutorial que usa
start()/pass()/fail(). - Verificar no seu backend: o que fazer com o token do evento
pass. - Exemplos de frontend: conectar estes eventos em React, Vue e JS puro.