11
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

金を使った実感を高めるChrome拡張

Last updated at Posted at 2023-12-22

皆さん、インターネットでお買い物してますか?

ECサイトでの購買体験について

電子マネーやオンライン決済での購買は、現金と比べると支払い意識が薄くなり財布の紐が緩くなるという説がかねてより囁かれています。
いくつかの論文やメディアを見るに、要するに「現金を物理的に支払うとお金を使ったと感じるが、クレジットカードや電子マネーなどの電子決済ではその感覚が薄れる」ということらしいです(※1)。
実際、自分はよく電子書籍や服などをバリバリとカードで決済してしまいます。今月は本当にお金を使いすぎてしまい正直クソアプリとか言ってる場合じゃないぐらいになってきてます。クソなのは出費額だよ。

※1 この言説が本当に信頼に足る確実なものなのかどうかについては、参考にした論文は調査対象のN数が少なかったりメディアの記事はエビデンスが不明瞭なものもあったため、とりあえず「そういう説がある」という程度で認識してください。

ちゃんと「お金使った」ということを感じる体験設計にする

ついついECサイトでお金を使いすぎてしまうのは "消費した" という体験設計が弱いからではないでしょうか。
そんな人間心理脆弱性を突かれて財布の紐がガバガバになってしまうことを防ぐためにある効果を取り入れられるものを作りました。

成果物

以下の埋め込み動画を再生してください

実装内容

コードはこちらに記載します
(function () {
  // audio要素を作成(先に入れておかないとロードが間に合わない)
  var audioElement = document.createElement("audio");
  audioElement.src = chrome.runtime.getURL("sounds/register.mp3");
  // audio要素をDOMに追加
  document.body.appendChild(audioElement);

  function playSound(form) {
    // 音声を再生
    audioElement.play();
    // 再生後にaudio要素を削除
    audioElement.onended = function () {
      document.body.removeChild(audioElement);
    };
  }

  // 通常のそれぞれ販売している商品のレジ決済
  var placeYourOrderButton = document.querySelector("#submitOrderButtonId");
  if (placeYourOrderButton) {
    placeYourOrderButton.addEventListener("click", playSound);
  }

  // Kindleの注文確定
  var kindleCheckoutButton = document.querySelector("#checkoutButtonId");
  if (kindleCheckoutButton) {
    kindleCheckoutButton.addEventListener("click", playSound);
  }

  // すべての要素を取得
  var allElements = document.getElementsByTagName("*");
  for (var i = 0; i < allElements.length; i++) {
    var element = allElements[i];

    // 要素が直接持つテキストを取得
    var text =
      element.childNodes.length === 1 &&
      element.childNodes[0].nodeType === Node.TEXT_NODE
        ? element.textContent.trim()
        : "";

    // テキストに「今すぐ買う」が含まれているかチェック(網羅しきれてない)
    if (text.includes("今すぐ買う") || text.includes("注文を確定する")) {
      // イベントを追加
      element.addEventListener("click", playSound);
    }
  }
})();

言い訳:Amazonの決済ボタンのイベントをどうこうするのは意外と大変

作成したものですが、要するにレジ画面で「注文を確定」のボタンを押した瞬間に決済音が鳴る、ただそれだけのChrome拡張です。あとはKindleの書籍を単品購入したときにも決済音が鳴ります。
正直本当にただそれだけ、という感じなのですが、これが意外と大変で色々と諦めた経緯があるのでその内容についてすこし書いていきます。

大変ポイント1 決済ボタンのイベント、どうなってるのかわからん問題

クリックされたとき、というかサブミットされる前のタイミングでappendしたaudioを再生したかったので、formのsubmitイベントをキャンセルして、音の再生が終わったあとに再度submitイベントを発火させようと思っていました。
しかし、そのようなことが簡単にできる単純な構造をしているとこのようなジョークアプリのChrome拡張ならいざしらずガチの悪意のあるChrome拡張等による悪意の操作が実行されるおそれがあるためか、Amazonの決済トリガーは想定していたよりも複雑な構造になっており、結局どこのformのsubmitを停止させればいいのかを特定しきれませんでした。なぜならクリックするとマジの決済が実行されてしまうからです。(※2)
そこで、submit要素をラップしているspanのclickイベントにaudioを再生するイベントをリスナーとして設定し、画面が送信されきる前に音が再生されるという力技の実装でなんとかしています。クソアプリだからまあいいかという甘えです。

※2 デバッグするためにボタンを押すときだけマシンのWi-Fi切ればいいんじゃね?ってあとから友達に指摘されて気づきました。天才じゃん。

大変ポイント2 決済導線、めっちゃ多様

Amazonを使っていて気づいたんですが、ちゃんとカートからレジに遷移して決済する、というフローを踏むことって案外少ないんですよね。
動的に出現するものをMutationObserverで監視してイベント付与しようと頑張ってみたりしたのですが、iframeの中にいたり、名前がバラバラだったりとイベントを付与するのとデバッグが大変だったので今回は諦めてしまいました。

実際にいくつかのAmazonの商品購入導線を見てみましょう。

レジ

もっともオーソドックスなカートに入れた商品を決済確定する画面です。
スクリーンショット 2023-11-23 17.29.19.png

Kindle本単体

Kindle本は住所確認や品数の選択などがないからか、商品画面から「注文を確定する」のボタンをクリックすると即時に決済されます。
正直このクソアプリを開発する前は全部この形だと思いこんでいました。
スクリーンショット 2023-12-22 23.20.14.png

決済音対応できたのはここまで。

Kindle本複数

購入導線は似て非なるものになっています。購入トグルを替えたときにイベントを再付与してやらなくてはいけません。あとこの導線って出たり出なかったりします。
スクリーンショット 2023-11-23 16.29.24.png

あとこういう形で出るときもある。
スクリーンショット 2023-12-06 22.10.23.png

そして商品を見たときに出てくるオファー。これも出たり出なかったりします。 。もう分かんねーんだわ。
スクリーンショット 2023-12-22 23.29.58.png

Kindle本のコミックスのシリーズ

Kindleで漫画・コミックを購入したさい、そのシリーズが購入レコメンドとして表示されます。この1Clickで今すぐ買うボタンはそれぞれIDに名称と連番が付番されています。ただこれも書籍によって出るやつと出ないやつがあって表示される定量的な条件が正直わかりませんでした。ジャンプコミックスなら出るのか?

スクリーンショット 2023-11-23 16.29.17.png

今すぐ買うボタンは数種類の挙動があるっぽい

ひとつは今すぐ買う、をクリックしたあと 当該商品がカートに1つ入った状態でレジ画面に移動する挙動、そして確認した限りもうひとつある挙動は画面内にiframeでダイアログが展開され、レジ画面と同様の内容を確認し、決済を確定するというものです。
どういう基準でこの挙動の分岐が起こるのかはよくわかりませんが、その商品の購入歴があるかどうかで動作が分かれているのかもしれません。
スクリーンショット 2023-12-22 22.57.34.png

このとき出てくるダイアログがiframeで実装されているというのが厄介で、展開時に対象の商品の情報を非同期でロードするためiframeの中身が動的に変化するのですが、動的に出現したiframeの中の変化をさらにMutationObserverで変更監視してイベントを付与するというのがうまく行かず諦めました。

購入履歴の一覧から生えてくる購入導線

スクリーンショット 2023-11-23 16.28.59.png

これは再び購入の画面で商品のサムネをクリックすると表示されます。なお、今すぐ購入ボタンをクリックしても即時に決済はされず前項のようにiframeでの決済確認画面が出てきます。

定期オトク便

いろいろあるね〜〜〜〜(諦めの顔)
スクリーンショット 2023-11-24 17.44.06.png

そもそも論

このクソアプリはクソアプリハッカソンというイベントで作成したのですが、そのさいに「ボタンのクリックイベントではなくて、決済完了画面表示されたときに音を鳴らせば良いのでは?」という意見を頂戴し(天才かよ…)と感嘆したのですが、ボタンを押した瞬間に鳴らしたいという絵面への固執を捨てきれませんでした。

クソアプリ作成の感想

正直MutationObserverのことを知らなくて、成果物には含めませんでしたがこれを機に知ることができたので学びになりました。悪ふざけだろうがなんだろうがやっぱり実際にやってみるというのは大事なことだと毎年感じます。

あと正直思った以上に「金使った」感が得られました。この記事を書いてるときにまた本を買いましてその感想なので間違いないです。

余談ですが、PayPayはアプリでの決済音が鳴るようになってるので偉いなと思っています。ただ音は任意で消させてほしいとも同時に思います。列車の中とかでおうちに着く前にUberEATSを先行して頼んだりしたいんですよね。
音というのは扱い方が難しいインタフェースのひとつだなと思います。

また、Amazonについて改めてしげしげと眺める機会になったのですが 買いたいと思ったらすぐに変える導線設計 が作り込まれているなと感じます。前項でいくつかの決済導線を紹介しましたがおそらくまだまだたくさんあると思いますし、商品の特性によって変えられているものなどもまだまだあるんじゃないかと思います。
真理を求めてAmazonの奥地へ行く財布の余力はないので、探索は他の誰かに任せようと思います。

音楽素材

こちらのサウンドエフェクト レジスターで精算 を使用させていただきました。

11
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?