モバイルアプリの連携
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 | いいえ | inline、modal、fullscreen、または 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 を表示します。
あわせて読む
- トークンの確認については サーバー側の連携。
- ウェブ版については クライアント側の連携。