AIがクリックできないボタンを作る
今後ブラウザにAIが搭載されるようになると、WebアプリケーションをAIが使う場面がますます増えてくると思います。逆に、AIにWebアプリケーションを自動操作されないようにしたいケースもでてくるでしょう。ここではAIがクリックできないボタンをどうすれば作れるか考えてみます。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
</head>
<body>
<button id="btn">Click!</button>
<p id="message"></p>
<script>
const btn = document.getElementById("btn");
const message = document.getElementById("message");
btn.addEventListener("click", (e) => {
let isBot = false;
if (!e.isTrusted) isBot = true;
if (typeof navigator.webdriver !== "undefined" && navigator.webdriver)
isBot = true;
if (e.detail <= 0) isBot = true;
if (isBot) {
message.textContent =
"Click detected, but it seems to be from a bot.";
return;
}
message.textContent = "Click detected from a human.";
});
</script>
</body>
</html>e.isTrusted
isTrustedはEventインターフェイスの読み取り専用プロパティで、このイベントがユーザー操作によって生成された場合はtrue、このイベントがスクリプトで作成または変更されたり、EventTarget.dispatchEvent()で配信されたりした場合はfalseとなる論理値を返します。
addEventListenerをオーバーライドして判定を突破することは可能らしい。
navigator.webdriver
ブラウザが自動制御されているかどうかを判定する。PuppeteerやPlaywrightなどの検出に使われる。回避する方法はいろいろあると思われる。
webdriverはnavigatorインターフェイスの読み取り専用プロパティで、ユーザーエージェントが自動制御されているかどうかを示します。
e.detail
e.detail > 0を入れることで、マウス由来のクリックかどうかを判定。
clickのイベントハンドラーに渡されるPointerEventオブジェクトのdetailプロパティには、targetがクリックされた回数が設定されています。言い換えれば、ダブルクリックの場合はdetailが 2 になり、トリプルクリックの場合は 3 になります。
ただし、カスタムイベントで回避することは可能。
const event = new MouseEvent("click", {
view: window,
bubbles: true,
cancelable: true,
detail: 1
});
temp1.dispatchEvent(event);まとめ
スクレイピング目的などのボットを回避する技術としてはマウスイベントを監視するとか他にもいろいろあって、ボットを排除したい側と突破したい側とのいたちごっこが続いています。上記の方法でボットを完璧に防ぐことはできません。そもそもクリックが防止できたところでリクエスト生成されたら意味ないですし。
今回はユーザーがClaude in ChromeなどのAIを使う場合を想定しているので、上記の対策でも十分使えるはずです。ただAIからするとボタンは存在するけど押せない不親切なインターフェイスになるので、将来的にはWebMCPのようなAI専用のインターフェイスがあるのと同じように、人間専用のインターフェイスみたいなものも整備されていくのではないかなと思います。