🥉

メールで送られる認証コードを半自動的にクリップボードにコピーする

2024/12/25に公開

これは GENDA Advent Calendar 2024 の25日目の記事です。

https://qiita.com/advent-calendar/2024/genda

はじめに

GENDAが提供する各アプリでは、GENDA IDでログインできるように対応が進んでいます。GENDA IDではセキュリティを高めるために2段階認証を採用しており、ログイン時には登録メールアドレスに届いた認証コードの入力を求められます。

私は今年の11月にリリースしたカラオケBanBan新アプリ開発にFlutterエンジニアとして携わりました。このアプリにもGENDA IDによる認証が採用されています。2段階認証は前述のとおりセキュリティ向上のために必要ですが、アプリ開発時には動作確認のためにログイン操作をする場面が何度もあるため、正直に言って非常に煩わしいです。ログインするたびに「メール画面を開く → 認証コードをコピー → 入力フォームにペースト」という作業が発生します。ID/パスワード管理ツールを使ってもこれはスキップできません。

そこで「メール画面を開く → 認証コードをコピー → 入力フォームにペースト」の操作を自動化する方法がないか探りました。

やりたかったこと

前提として、Mac上のAndroidエミュレーターおよびiOSシミュレーターでのアプリ動作確認を想定しています。

  1. アプリでログイン操作を進める
  2. 認証コードを伝えるメールが届く
  3. 認証コードがクリップボードにコピーされる

となるのが理想だと考えました。あとは認証コードを入力欄にペーストするだけです。

できたこと

あまり開発の手間や運用費用をかけないでできることを考えた結果、以下の手順に落ち着きました:

  1. アプリでログイン操作を進める
  2. 認証コードを伝えるメールが届く
  3. Googleスプレッドシートを開く
  4. Googleスプレッドシート上のボタンをクリックする
  5. 認証コードがダイアログ表示される
  6. もう一度画面をクリックする
  7. 認証コードがクリップボードにコピーされる

理想像と比べると「Googleスプレッドシートを開く」「ボタンをクリック」「画面をクリック」の操作の手間が増えてますが、それでも3回ほどクリックするだけですので「メール画面を開く→最新メッセージを探す→認証コードを選択してコピー」よりはかなり認知機能の負荷が下がっています。

利用例GIF動画
利用例。最後のペースト以外はマウスクリックするだけ。

どうやったか

前提

今回考えた手法を実現するには以下を前提とします。

  1. 認証コードメールはGmailに送られるようにする
  2. Chromeブラウザを使い、Chrome拡張機能のScriptAutoRunnerを利用する

2.についてはブラウザ上でユーザースクリプトを実行できればScriptAutoRunner以外のツールでも実現可能と思います。

Google Apps ScriptでGmailに送られた認証コードメールから認証コードを抜き出す

Google Apps Scriptを使うと比較的簡単にGmailのメールを取得できます。Apps Scriptを使うために、まず空のGoogleスプレッドシートを作り、メニューの「拡張機能」→「Apps Script」から新規Apps Scriptプロジェクトを開きます。

新規Apps Scriptプロジェクト

以下のコードで最新の認証コードメールから認証コードのみ抜き出してダイアログ表示まで行います。Google Apps ScriptはほぼJavaScriptですがサーバーサイドのスクリプトであり、クライアントのクリップボードを操作するのは不可能なので、ここまでです。

function retrieveAuthCode() {
    var threads = GmailApp.search('from:認証コードを送信するメールアドレス');
    // 最新のスレッドからメッセージ一覧を取得
    const messages = threads[0].getMessages();
    // メッセージ一覧の最後尾=最新メッセージを取得
    const message = messages[messages.length - 1];
    // メッセージ本文から正規表現で認証コードを抜き取る
    const pattern = /\d{6}/; // ※ GENDA IDの認証コードは6桁の数値
    const code = message.getBody().match(pattern);
    Browser.msgBox(code);
}

Googleスプレッドシートからスクリプトを使えるようにする

上記スクリプトをボタンクリックで実行できるように、Googleスプレッドシートに戻ってボタンを作ります。

ボタンを作成

メニューから「挿入」→「図形描画」を選んでボタンとなる図形を作ります。

図形描画

ボタンにスクリプトを割り当てる

図形をクリックして表示されるメニューからスクリプトを割り当てます。

スクリプトの割り当て

メソッド名の入力

ScriptAutoRunnerのスクリプトでダイアログ上の認証コードをクリップボードにコピー

クライアント(ブラウザ)上でのユーザースクリプトを使って、ダイアログに表示された認証コードをクリック一発でコピーされるようにします。ダイアログが表示された状態でHTMLソースを調べてみると、メッセージ部はid=“docs-maestro-prompt-dialog-message”divだとわかりました(2024年12月25日現在)のでこれを利用して抜き出します。もちろん、これはいずれ変更されて使えなくなるかもしれません

document.addEventListener('click', onClick);

function onClick(e) {
  const code = document.getElementById("docs-maestro-prompt-dialog-message").textContent;
  navigator.clipboard.writeText(code);
}

ScriptAutoRunnerの設定画面では、Googleドキュメントのみで実行できるようにドメインを設定します。

ScriptAutoRunner設定画面
下端の行がドメイン設定欄

どう考え出したか

本記事の自動化手法を考案するにあたり、以下のプロンプトでChatGPTに相談しました。

Gmailにて自分に送られたメールの内容をクリップボードにコピーするツールを作りたいと思っています。Gmail APIを使うのは環境作りなどなかなか大変そうです。なんらか簡易に作れる方法はないでしょうか?Gmailのフィルター機能を使ってなんらか別のサービスにメールを転送したりすれば良さそうですが…IFTTTとか…?

ChatGPTの答えはこんな感じ:

(前略)
おすすめの選択肢

  • 手軽さ優先: IFTTTやZapierを使う方法。
  • 柔軟性重視: Google Apps Scriptでカスタムスクリプトを作成。
  • 完全な自動化: Gmail APIを使用(初期設定に時間はかかるが柔軟性は最高)。

具体的な実装が必要であれば、さらに詳細をお手伝いします!

この提案から「Google Apps Scriptでカスタムスクリプトを作成」を採用し、ScriptAutoRunnerの利用はなんとか自力で思いついて付け足しました。

さいごに

苦し紛れの妥協案ではありますが、「メール画面を開く→最新メッセージを探す→認証コードを選択してコピー」よりはかなり手間を省けるようになりました。より良い案を考えついた方はぜひ共有お願いします。

Discussion