HTML/JavaScriptで国際電話番号入力を作成する方法

February 01, 2021
執筆者
レビュー担当者
Liz Moy
Twilion
Diane Phan
Twilion

電話番号は国際的な番号体系として知られるE.164により標準化され、国コードと加入者番号を組み合わせた+14155552671のようなフォーマットがとられます。このフォーマットは(Twilioをはじめ)多くのAPIで必須とされており、国コードと電話番号を2つの別々のデータベース列に格納する必要はありません。

しかし、次のようなケースの電話番号入力でユーザーに+記号と国コードを入力してもらうのは避けたいところです。

  • 新規アカウントの登録
  • SMS 2FAの有効化
  • カスタマーサービスからの返信のリクエスト
  • マーケティング関連通知の登録

この記事では、基本的なHTMLとJavaScript、intl-tel-inputプラグインを使用して電話番号入力フィールドを作成し、電話番号を処理・解析する方法を説明します。電話認証と不正防止のためのヒントも紹介します。

完成したコードをGitHubで参照できます。

intl-tel-inputプラグインの機能

このプロジェクトで大いに使用するintl-tel-inputは、「国際電話番号の入力と確認に使用するJavaScriptプラグイン」です。このプラグインについて、自分がいつも使用しているセットアップを紹介しますが、その他にも多くの設定オプションがあります。こちらのドキュメントでご覧いただけます。

このプラグインは、国コードのドロップダウンを表示し、各国の国旗も表すことができます。加入者番号、つまり「各国フォーマット」の番号を処理し、スペース、括弧、ダッシュなどを含むユーザー入力を正規化することも可能です。

 

電話番号入力フィールドに表示されたE.164フォーマットの番号

intl-tel-inputプラグインをコードに埋め込む

作成するコードはごくシンプルなものとし、一般的なHTMLとJavaScriptを使用して始めます。新規ファイルindex.htmlを作成し、次のコードを追加します。

<!DOCTYPE html>
<html lang="en">
 <head>
   <title>International telephone input</title>
   <meta name="viewport" content="width=device-width, initial-scale=1" />
   <link rel="stylesheet" href="styles.css" />
   <link
     rel="stylesheet"
     href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/css/intlTelInput.css"
   />
   <script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/intlTelInput.min.js"></script>
 </head>
 <body>
 </body>
</html>

これによりプラグインのCSSとJSがCDNバージョンで取り込まれ、国コードのドロップダウンを表示して電話番号の処理が行えます。使用バージョンはv17.0.8ですが、最新バージョンをこちらのtagsで確認できます。プラグインはbundlerを使用したインストールもでき、ソースコードをダウンロードして独自にホストすることも可能です。

スタイル改善のため、同じフォルダーに新しいstyles.cssファイルを作成し、こちらのCSSを追加します。

次に、電話番号入力用のフォームを追加します。index.htmlファイルのbodyタグ内に、次のHTMLを追加します。

<div class="container">
 <form id="login" onsubmit="process(event)">
   <p>Enter your phone number:</p>
   <input id="phone" type="tel" name="phone" />
   <input type="submit" class="btn" value="Verify" />
 </form>
</div>

ここでこのファイルをブラウザに読み込むと、フォームフィールドが表示されますが、フォーマットされていない状態のため、プラグインの初期化が必要です。

特別なフォーマットなしの電話番号入力フィールド

intl-tel-inputプラグインの初期化

本文の下で、HTMLセクション内に次のscriptタグを追加し、次の初期化コードを追加します。

 <!-- ^^  form code  ^^ -->
 </body>
 <script>
   const phoneInputField = document.querySelector("#phone");
   const phoneInput = window.intlTelInput(phoneInputField, {
     utilsScript:
       "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/utils.js",
   });
 </script>
</html>

utilsScriptはオプション扱いですが、国固有のプレースホルダーや後で使用するE.164フォーマットなど、多くの便利な機能が使用できます。

ページをリロードすると、国ピッカーとプレースホルダーが表示されます。

電話番号入力フィールドの米国旗、国コードのドロップダウンと電話番号のプレースホルダーテキスト

電話番号入力を処理して国際フォーマットにする

フォームの下にアラートバナーを追加します。これにより結果を確認できます。

 </form>
 <!-- ^^  form code  ^^ -->
 <div class="alert alert-info" style="display: none;"></div>

次に、フォーム送信を処理する関数を追加します。<script>タグ内のプラグイン初期化のセクションに続けて、次を追加します。

const info = document.querySelector(".alert-info");

function process(event) {
 event.preventDefault();

 const phoneNumber = phoneInput.getNumber();

 info.style.display = "";
 info.innerHTML = `Phone number in E.164 format: <strong>${phoneNumber}</strong>`;
}

ここで最も重要なのがphoneInput.getNumber()です。このプラグインコードにより、選択した国コードとユーザー入力を国際フォーマットに変換します。

ページをリロードし、電話番号を入力すると国際フォーマットが表示されます。

電話番号入力と正しくE.164でフォーマットされた結果

さらに役立つ条件: プラグインのロケーション対応

プラグインのデフォルトロケーションは米国に設定されているため、世界各国のユーザーを対象とするにはこの機能が必要です。IPアドレスに基づくユーザーのロケーションをデフォルト設定に更新することが可能です。

IPinfoの無料アカウントにサインアップし、アクセストークンを入手してください。別のIPアドレスAPIを使用しても構いません。次の関数を<script>タグの先頭、phoneInputFieldオブジェクト定義の前に追加します。

function getIp(callback) {
 fetch('https://ipinfo.io/json?token=<your token>', { headers: { 'Accept': 'application/json' }})
   .then((resp) => resp.json())
   .catch(() => {
     return {
       country: 'us',
     };
   })
   .then((resp) => callback(resp.country));
}

intl-tel-inputの初期化を更新し、initialCountry: "auto"geoIpLookup: getIpの2つのパラメーターを含めます。

const phoneInput = window.intlTelInput(phoneInputField, {
 initialCountry: "auto",
 geoIpLookup: getIp,
 utilsScript:
   "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/utils.js",
});

これで、VPNをオーストリアに設定すると、プラグインにより、デフォルトの国が更新されます。

電話番号入力とオーストリア国旗

さらに役立つ条件: 優先国の追加

便利な機能の1つに、「優先国」の設定があります。これにより、指定した国をリストの先頭に表示できます。今回の例では、米国、コロンビア、インド、ドイツのユーザーが大多数であるため、これらの国を優先します。

電話番号入力ドロップダウンリストと先頭に表示された4つの優先国

 

プラグインを初期化してこの設定を更新するために、preferredCountriesの配列をISO 3166-1 alpha-2コードフォーマットで追加します。

const phoneInput = window.intlTelInput(phoneInputField, {
  preferredCountries: ["us", "co", "in", "de"],
  utilsScript:
    "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/utils.js",
});

電話番号入力の確認

このフォームでは、無効な電話番号の入力を防止できないことにお気づきでしょう。電話番号入力の確認方法の説明に従い、無効な番号の入力を防止することができます。

 

無効な電話番号の入力

 

電話認証のベストプラクティス

電話番号をE.164フォーマットで正規化したいわけですが、これらの番号を保存するのであれば電話認証も必要になります。電話認証により番号入力の誤りを防ぎ、ユーザーがアカウントに関連付けている番号がユーザーの管理している番号であることを確認し、間違った相手に迷惑メールを送信していないことを確認できます。お分かりですね。便利なことに、Twilio Verify APIを使えば、SMSや音声通話により電話認証が簡単に行えます。こちらのコード交換プロジェクトでワンタイムパスコードの実装方法を紹介しています(前半の電話番号入力までは以上で完了しています)。

次の記事も役に立つでしょう。

電話番号の入力と認証についてご不明な点は、Twitter @kelleyrobinsonでお問い合わせください。何を構築されるか、とても楽しみです。