Caputchin
Integrationsanleitungen

Integration in Mobile-Apps

Caputchin läuft in einer nativen App über eine gehostete Embed-Seite. Du richtest eine WebView auf diese Seite, der Besucher löst die Aufgabe darin, und die Seite brückt das resultierende Token (und jeden Fehler) zurück in deinen nativen Code. Die Verifizierung selbst ist identisch mit dem Web; nur die Host-Hülle unterscheidet sich.

1. Die Embed-Seite öffnen

Richte eine WebView auf https://caputchin.com/embed mit mindestens einem Site-Key:

https://caputchin.com/embed?sitekey=cpt_pub_...&game=caputchin/games/leaf-memory

Lass die Spiel-Parameter weg für die schlichte Checkbox. Eine games=a,b-Liste wählt eines pro Session zufällig aus.

Query-Parameter

ParameterPflichtWirkung
sitekeyjaDein Public Key (cpt_pub_...). Fehlt er, rendert eine Fehlerhülle ohne Widget.
gameneinEine einzelne Marketplace-Spiel-id (owner/repo, oder owner/repo/leaf).
gamesneinEine kommagetrennte Liste; eines wird pro Session zufällig gewählt.
game-srcneinURL deines eigenen gehosteten Spiel-Bundles, für ein selbst gehostetes Spiel.
layoutneininline, modal, fullscreen oder auto. Standard ist inline auf dem Embed.
locale / skin / configneinAn das Widget weitergereicht, um Sprache, Skin oder Konfiguration zu wählen.
no-verifyneinFührt das Spiel ohne Verifizierungs-Gate aus (nur Spiel, kein Token).
postMessageTargetneinNur für Browser-Iframe-Einbetter (siehe unten). In einer nativen WebView ignoriert.

Lass alle drei von game / games / game-src weg für die schlichte Checkbox. Es gibt keinen mode-Parameter; das Widget steuert den Auslöser selbst.

2. Das Token in deinen Code brücken

Wenn der Besucher besteht, schiebt die Embed-Seite das Token durch den Kanal, der zu deinem Host passt. Registrier den passenden Handler.

iOS (WKWebView, Swift)

Das Token kommt als roher String auf einem Message-Handler namens caputchin an:

class TokenHandler: NSObject, WKScriptMessageHandler {
  func userContentController(_ controller: WKUserContentController,
                             didReceive message: WKScriptMessage) {
    guard let token = message.body as? String else { return }
    // send `token` to your backend
  }
}

let config = WKWebViewConfiguration()
config.userContentController.add(TokenHandler(), name: "caputchin")
let webView = WKWebView(frame: .zero, configuration: config)
webView.load(URLRequest(url: URL(string: "https://caputchin.com/embed?sitekey=cpt_pub_...&game=caputchin/games/leaf-memory")!))

Android (WebView, Kotlin)

Das Token kommt als roher String auf einem @JavascriptInterface namens caputchin an:

class TokenBridge {
  @JavascriptInterface
  fun onToken(token: String) {
    // send `token` to your backend
  }
}

webView.settings.javaScriptEnabled = true
webView.addJavascriptInterface(TokenBridge(), "caputchin")
webView.loadUrl("https://caputchin.com/embed?sitekey=cpt_pub_...&game=caputchin/games/leaf-memory")

React Native (react-native-webview)

Das Embed postet einen JSON-String auf dem einen React-Native-Kanal. Parse ihn und verzweig auf type:

<WebView
  source={{ uri: "https://caputchin.com/embed?sitekey=cpt_pub_...&game=caputchin/games/leaf-memory" }}
  onMessage={(e) => {
    const msg = JSON.parse(e.nativeEvent.data);
    if (msg.type === "caputchin-token") {
      // send msg.token to your backend
    } else if (msg.type === "caputchin-error") {
      // msg.code, msg.message, msg.originalCode (optional)
    }
  }}
/>

Browser-Iframe (postMessage)

Bettest du die Seite in ein Browser-<iframe> statt in eine native WebView ein, ist das Eltern-Relay standardmäßig aus und feuert nur, wenn du dich über einen exakten Ziel-Origin mit ?postMessageTarget=<origin> einklinkst (zum Beispiel postMessageTarget=https://app.example.com). Ein Wildcard (*), ein Pfad oder alles, was nicht zu einem nackten Schema, Host und Port parst, wird abgelehnt, sodass das einmalige, site-gebundene Token nie an ein unverifiziertes Eltern-Fenster gesendet wird. Lausch im Eltern-Fenster und prüf event.origin, bevor du der Nachricht traust:

window.addEventListener("message", (event) => {
  if (event.origin !== "https://embed-host.example.com") return;
  const msg = event.data;
  if (msg.type === "caputchin-token") {
    // msg.token
  } else if (msg.type === "caputchin-error") {
    // msg.code, msg.message
  }
});

3. Auf deinem Backend verifizieren

Das ist dasselbe wie im Web: POSTe das Token an /siteverify mit deinem Secret. Sieh dir Serverseitige Integration an.

Fehler empfangen (optional)

Wann immer das Widget auf einen Fehler trifft, spiegelt die Embed-Seite ihn über einen parallelen Satz Kanäle: iOS-caputchinError-Message-Handler, Android-caputchinError-Interface (onError(json)), den React-Native-Kanal als { type: "caputchin-error", ... } und dasselbe gegatete Iframe-Relay. Die Payload trägt { code, message, originalCode? }. iOS und Android empfangen sie als JSON-String; React Native und das Iframe-Relay empfangen den typisierten Umschlag.

Das ist vollkommen optional. Eine App, die keinen Fehler-Handler registriert, empfängt einfach keine Fehler, und die Embed-Seite zeigt ohnehin eine Retry-UI in der WebView, egal was.

Siehe auch

Auf dieser Seite