Caputchin
連携ガイド

モバイルアプリの連携

Caputchin は、ホスト型の埋め込みページを通じてネイティブアプリの中で動きます。WebView をそのページに向けると、訪問者がその中でチャレンジをクリアし、ページが結果のトークン(とエラーがあればそれも)をあなたのネイティブコードへ橋渡しします。検証そのものはウェブと同一で、違うのはホストのシェルだけです。

1. 埋め込みページを開く

WebView を https://caputchin.com/embed に、少なくともサイトキーを付けて向けます:

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

素のチェックボックスにする場合はゲームのパラメータを省きます。games=a,b リストはセッションごとに 1 つをランダムで選びます。

クエリパラメータ

パラメータ必須効果
sitekeyはいあなたの公開鍵(cpt_pub_...)。欠けると、ウィジェットのないエラーシェルがレンダリングされます。
gameいいえ単一のマーケットプレイスのゲーム id(owner/repo、または owner/repo/leaf)。
gamesいいえカンマ区切りのリスト。セッションごとに 1 つがランダムで選ばれます。
game-srcいいえセルフホストのゲーム用の、あなた自身のホスト型ゲームバンドルの URL。
layoutいいえinlinemodalfullscreen、または auto。埋め込みでは inline が既定です。
locale / skin / configいいえ言語、スキン、設定を選ぶためにウィジェットへ転送されます。
no-verifyいいえ検証ゲートなしでゲームを実行します(ゲームのみ、トークンなし)。
postMessageTargetいいえブラウザ iframe 埋め込み側のみ(下記参照)。ネイティブ WebView では無視されます。

素のチェックボックスにする場合は game / games / game-src の 3 つすべてを省きます。mode パラメータはありません。ウィジェット自身がトリガーを駆動します。

2. トークンをあなたのコードへ橋渡しする

訪問者が通ると、埋め込みページはあなたのホストに合うチャネルを通じてトークンを押し出します。合致するハンドラーを登録してください。

iOS(WKWebView、Swift)

トークンは caputchin という名前のメッセージハンドラーに、生の文字列として届きます:

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)

トークンは caputchin という名前の @JavascriptInterface に、生の文字列として届きます:

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)

埋め込みは、単一の React Native チャネルで JSON 文字列をポストします。それをパースして 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)
    }
  }}
/>

ブラウザ iframe(postMessage)

ページをネイティブ WebView ではなくブラウザの <iframe> に埋め込む場合、親への中継は 既定でオフ で、?postMessageTarget=<origin> で正確なターゲットオリジンを指定してオプトインしたときだけ発火します(たとえば postMessageTarget=https://app.example.com)。ワイルドカード(*)、パス、あるいは素のスキーム・ホスト・ポートにパースされない何かは拒否されるので、一度きりでサイトに紐づいたトークンが、検証されていない親へ決して送出されません。親で待ち受け、メッセージを信頼する前に event.origin を確認してください:

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. バックエンドで検証する

これはウェブと同じです。トークンをシークレットとともに /siteverify へ POST します。サーバー側の連携 を参照してください。

エラーを受け取る(任意)

ウィジェットがエラーに当たるたび、埋め込みページは並行するチャネル群を通じてそれをミラーします:iOS の caputchinError メッセージハンドラー、Android の caputchinError インターフェース(onError(json))、React Native チャネルでの { type: "caputchin-error", ... }、そして同じゲートされた iframe 中継。ペイロードは { code, message, originalCode? } を運びます。iOS と Android はそれを JSON 文字列として受け取り、React Native と iframe 中継は型付きのエンベロープを受け取ります。

これは完全に任意です。エラーハンドラーを登録しないアプリは、単にエラーを受け取らないだけで、埋め込みページはいずれにせよ WebView の中ですでに再試行 UI を表示します。

あわせて読む

このページの内容