Caputchin
Разработка пользовательской игры

Управляй проверкой сам через ручной режим

К концу этого руководства ты будешь управлять жизненным циклом проверки Caputchin из своего собственного кода вместо встроенного UI, на том из двух элементов, что подходит твоему случаю. Ручной режим (trigger="manual") существует на двух разных элементах, и они делают по-настоящему разные задачи:

ЭлементЧто даёт ручной режимЧем ты управляешь
<caputchin-widget>Встроенная галочка скрыта; ты запускаешь решение proof-of-work от своего собственного триггера (отправка формы, своя кнопка). Без игры.start() (затем решение обычно разрешается само)
<caputchin-game>Без iframe; ты вставляешь свою собственную игровую разметку в оболочку раскладки виджета и решаешь исход по игре.pass() / fail() (без start(); раунд живой при монтировании)

Выбирай по вопросу, на который ты отвечаешь:

  • «Я хочу обычную невидимую/галочную проверку, но запускаемую моим собственным жестом и без галочки по умолчанию.»галочный виджет, ниже.
  • «Я хочу своё собственное интерактивное испытание, отрендеренное в моём собственном DOM, а не игру в iframe, и я решаю прошёл/не прошёл.»игровой хост, ниже.

Прочитай запусти свою собственную игру о том, куда вписывается игровой путь. Тебе уже нужен виджет на твоей странице; если нет, сначала добавь виджет.

Один предел, общий для обоих: раунд ручного режима не может удовлетворить игровые ворота. Галочный элемент вообще никогда не ставит ворота на ключе (только <caputchin-game> может), а у ручного раунда <caputchin-game> нет воспроизводимой трассы, так что ключ с воротами его отвергает. Ручной режим для ключей без ворот (проверка proof-of-work) или только-игрового использования.

Путь A: галочный виджет, твой собственный триггер

Используй это, когда хочешь стандартную проверку, но хочешь запустить её сам, например чтобы запускать решение только когда посетитель отправляет форму, или за своей собственной кнопкой вместо встроенной галочки.

1. Пометь элемент ручным

<caputchin-widget id="cap" sitekey="cpt_pub_..." trigger="manual"></caputchin-widget>
<button id="go" type="button">Verify and continue</button>

С trigger="manual" встроенный UI галочки скрыт; элемент ждёт, пока ты начнёшь решение.

2. Начни решение от своего жеста

Галочный элемент в ручном режиме выставляет единственный метод, start():

  • start() запускает решение proof-of-work, заменяя клик по галочке. Валиден с trigger="manual".

У галочного виджета нет pass() / fail(); как только ты вызываешь start(), решение разрешается само и испускает событие pass. (Ручки release/abort живут на игровом хосте, покрыты в Пути B.)

const widget = document.getElementById("cap");

document.getElementById("go").addEventListener("click", () => {
  widget.start(); // begin verification now
});

widget.addEventListener("pass", () => {
  // token issued; submit your form / continue
});

Когда решение разрешается, элемент завершает проверку и (в форме) вставляет поле caputchin-token, как любой другой виджет. Твой бэкенд проверяет этот токен ровно как обычно; ручной режим ничего не меняет на сервере.

Путь B: игровой хост, твой собственный DOM

Используй это, когда хочешь отрендерить своё собственное интерактивное испытание в своей собственной разметке вместо загрузки игры в iframe и решить исход сам.

1. Пометь элемент ручным и вставь свою разметку

Поставь trigger="manual" на <caputchin-game> и помести свою собственную разметку внутрь. В любом другом режиме виджет игнорирует детей light-DOM; ручной режим это единственный режим, где он проецирует их в свою оболочку раскладки через <slot>.

<caputchin-game id="cap" sitekey="cpt_pub_..." trigger="manual">
  <!-- Your own markup. The widget renders it inside its shell. -->
  <div id="my-game">
    <p>Tap the banana three times.</p>
    <button id="banana" type="button">🍌</button>
  </div>
</caputchin-game>

С присутствующим sitekey и ключом без ворот виджет запускает свою проверку proof-of-work в фоне; твоё взаимодействие это видимая часть. Без sitekey (или с no-verify) это только-игра: твоё взаимодействие работает, и проверять нечего.

2. Управляй исходом из своего кода

Игровой хост в ручном режиме выставляет pass() и fail(). start() нет: раунд живой, как только элемент монтируется (смонтированная фабрика и есть сигнал старта).

  • pass(payload?) отпускает проверку: посетитель успел. Вызови один раз; поздние вызовы игнорируются (вердикт заблокирован).
  • fail(payload?) прерывает раунд. Опционально; незавершённый раунд всё равно трактуется как непрохождение.

Нагрузки:

  • pass({ trace }): trace это непрозрачная запись раунда, которую производит твоё взаимодействие. На раунде с воротами сервер реплеит её для вердикта; на ключе без ворот или только-игровом она принимается как есть, так что передавай пустую строку (или простой маркер), когда реплеить нечего. Здесь нет счёта, поставляемого клиентом.
  • fail({ code?, message? }): опциональные диагностические code и message, оба клиентские метаданные, никогда не сигнал доверия.
const widget = document.getElementById("cap");
let taps = 0;

document.getElementById("banana").addEventListener("click", () => {
  taps += 1;
  if (taps >= 3) {
    widget.pass({ trace: `banana:${taps}` }); // visitor won
  }
});

// Optional: give up explicitly.
// widget.fail({ code: "gave-up", message: "closed the prompt" });

Как и в галочном пути, pass() завершает проверку и вставляет токен; твой бэкенд проверяет его тем же способом.

Реагируй на исход (оба пути)

Слушай события виджета, чтобы обновить свой собственный UI:

widget.addEventListener("pass", () => {
  // verification released
});
widget.addEventListener("error", (e) => {
  console.warn("verification error", e.detail);
});

Решение о доверии это всегда твой бэкенд, подтверждающий токен, а не событие; событие для UX.

Чего ручной режим не может

  • Ставить ворота на ключе сайта. Ключ с включённым требованием игры вообще не может быть удовлетворён галочным элементом и отвергает ручной <caputchin-game> (он поднимает ошибку конфигурации при настройке), потому что нет воспроизводимой трассы. Ручной режим для ключей без ворот или только-игровых.
  • Реплеить раунд пользовательской игры. Если тебе нужна игра, ставящая ворота, отрисуй её как самостоятельно размещённую игру в iframe и производи трассу, а не ручной режим.

См. также

На этой странице