Twilio Lookup v2 APIを利用し、Rust環境で固定電話へのSMS送信を回避する

April 22, 2026
執筆者
レビュー担当者

Lookup v2 APIとRustを利用し、固定電話へのSMS送信を回避する

Rust環境で開発したWebアプリが大好評で、最近、SMS通知機能を追加したと仮定してみましょう。新機能をユーザーに届け、本番環境にリリースできることに胸を躍らせていましたが、

見栄え良く作成したテキストメッセージの送信を開始すると、以下のようなエラーが断続的に発生するようになりました:

Message Delivery - Landline or unreachable carrier

その直後から、ユーザーから「なぜ通知が届かないのか」という問い合わせが相次ぐようになりました。何が起こったのでしょうか?

SMS通知を送信する前に、アプリケーションが固定電話番号を除外していないことが判明しました。

さあ、どのように対処すればよいでしょうか? 配信不能メッセージを事前に検出するにはどうすればよいでしょうか? メッセージを送信する前に電話番号リストから固定電話を除外しておけば、送信失敗によるSMSコストを削減できます。

このブログ記事では、Twilio Lookup v2 APIを使って、Rust環境で実装する手順を解説します。

前提条件

アプリケーションを使用するには、次のものが必要です:

  • Twilioアカウント(無料または有料)。アカウントをお持ちでない場合は、アカウントを作成してください。
  • RustとCargo。まだインストールしていない場合は、インストールドキュメントに従ってください。
  • 検証したい電話番号を1つ以上用意してください。少なくとも1つは固定電話番号にしてください。できれば、自分や知人の電話番号を使用することをおすすめします
  • neovimやVisual Studio Codeなど、お好みのコードエディターやIDE
  • ターミナルの経験があれば役に立ちますが、必須ではありません

新規のRustプロジェクトを作成

はじめに、以下のコマンドを実行して、Cargoで新しいRustバイナリプロジェクトを作成します:

cargo new filter-landlines-with-rust --bin
cd filter-landlines-with-rust

必要なクレートを追加

「Hello, World!」より少しでも大きなプロジェクトであればそうであるように、このアプリケーションでも開発を簡単にするためにいくつかのクレートを利用します。数はそれほど多くありません。

  • anyhow: 柔軟に扱える具体的なエラータイプを提供するクレート
  • dotenv: .envファイルから環境変数を読み込むためのクレート。開発環境やテスト環境での利用に最適
  • reqwest: 強力なHTTPクライアント機能を提供するクレート
  • rustlio: RustアプリケーションからTwilioのAPIを簡単に利用できるようにするクレート

これらのクレートをプロジェクトに追加するには、以下のコマンドを実行します:

cargo add \
    anyhow \
    dotenvy \
    rustlio \
    reqwest --features reqwest/blocking --features reqwest/json
上記のコマンドは、読みやすくするため、改行して表示しています。Microsoft Windowsをご使用の場合は、行末のバックスラッシュをキャレット(^)に置き換えてください。

必要な環境変数を設定する

次に、Twilio Lookup v2 APIに認証付きリクエストを送信するために必要な2つの環境変数を設定します。

これらの環境変数を.envファイルに設定し、dotenvクレートを使って読み込みます。プロジェクトのルートディレクトリ(最上位階層)に、.envという新しいファイルを作成し、以下の設定内容を貼り付けます。

TWILIO_ACCOUNT_SID=
TWILIO_AUTH_TOKEN=

次に、選択したブラウザーでTwilio Consoleを開き、以下のスクリーンショットを参考に、[Account Info](アカウント情報)から[Account SID](アカウントSID)と[Auth Token](認証トークン)をコピーします。

Screenshot of Twilio console displaying account SID, auth token, and phone number.

次に、コピーした値をそれぞれ.envファイル内のTWILIO_ACCOUNT_SIDとTWILIO_AUTH_TOKENの値として設定してください。

あるいは、コード実行時に環境変数を設定するか、アプリケーションにコマンドライン引数として渡すこともできます。いずれかお好きな方を選択してください。

コアアプリケーションの更新

さて、いよいよコアとなるコードの記述に入りますが、量はそれほど多くありません。src/main.rsの既存のコードを以下のコードブロックの内容に置き換えてください。

次に、上記コードの<YOUR PHONE NUMBERS>を文字列リテラルのカンマ区切りリストに置き換えてください。Lookup v2 APIを使用して確認したい電話番号を、以下のようにE.164形式で指定します(例: "+614912345678"、"+61402987654")。少なくとも1件の固定電話番号を含めてください。

use anyhow::Result;
use rustlio::twilio::lookup;
use std::env;

fn main() -> Result<()> {
    dotenvy::dotenv()?;
    let user = env::var("TWILIO_ACCOUNT_SID")?;
    let pass = env::var("TWILIO_AUTH_TOKEN")?;
    let client = reqwest::blocking::Client::new();

    let phone_number_list = vec!["<YOUR PHONE NUMBERS>"];
    let non_landlines: Vec<&str> = phone_number_list
        .into_iter()
        .filter(|number| {
            let data = lookup::lookup_phone_data_with_line_type(
                number, 
                &client, 
                &user, 
                &pass
            );
            let phone_number = data.unwrap_or_default();
            phone_number.get_line_type() != "landline"
        })
        .collect::<Vec<&str>>();

    if non_landlines.is_empty() {
        println!("No non-landlines are available.");
    } else {
        println!("Available phone numbers: {:?}", non_landlines);
    }
    Ok(())
}

このコードは、まず.envファイルからTwilioの認証情報(userとpass)を読み込みます。次に、Lookup APIにリクエストを送信するためにブロック型のReqwestクライアントを生成し、確認する電話番号のVectorを生成します。

このチュートリアルでは、わかりやすくするため、あえてブロック型クライアントを使用しています。本番環境のアプリケーションでは、応答性を高めるために、非同期クライアントの使用が推奨されます。

さて、ここからが面白い部分です。into_iter()を使って、phone_number_listの電話番号からイテレータ(反復子)を作成します。次に、filter関数を使用して、固定電話以外の番号だけに絞り込みます。この関数に馴染みがない方のために説明すると、この関数は次のように動作します:

クロージャを使用して要素を抽出するべきかどうかを判断するイテレータを作成します。クロージャは、各要素についてtrueまたはfalseを返す必要があります。イテレータは、クロージャがtrueを返した要素のみを抽出します。

つまり、電話番号ごとに、指定されたクロージャが次の処理を実行します:

  1. lookup_phone_data_with_line_typeを呼び出し、Lookup v2 APIから電話番号の詳細情報と回線種別情報を取得しようとします
  2. 電話番号の詳細情報を取得できた場合は、データが格納されたPhoneNumber構造体が返され、取得できなかった場合は、空またはデフォルト値の構造体が返されます
  3. 返された電話番号の回線種別が「固定電話」の場合、その番号はイテレータから除外されます

filter()から返されたイテレータは、collect()によって、Vectorに変換されます。最後に、残りの電話番号がターミナルに出力されます。

このチュートリアルでは、電話番号リストから固定電話を抽出する処理に絞って解説しているため、SMS送信用のコードは割愛しています。Twilioを使ってRustでSMSを送信する方法については、Twilioブログのこちらのチュートリアルをご覧ください。

正常に動作するかどうかを確認する

コードの記述が完了したので、意図した通りに動作するかテストしてみましょう。これを行うには、以下のコマンドを実行します。

cargo run

コードのコンパイルと実行が完了すると、ターミナルに次のような出力が表示されるはずです。

Available phone numbers: ["+614912345678", "+61402987654"]

以上が、TwilioのLookup v2 APIとRustを使って、固定電話へのSMS送信を回避する方法です

Rustの標準ライブラリとTwilio Lookup v2 APIを組み合わせることで、Rustアプリケーションから固定電話へのSMS送信を回避できます。これによって、SMSの送信失敗による無駄なコストを抑え、ユーザー体験の向上にもつながります。

さらにその先へ

TwilioとRustを組み合わせる方法については、以下のチュートリアルをご覧ください:

Matthew Setterは、Twilio VoiceチームでPHP、Go、Rustのエディターを務めており、各言語の開発者でもあります。『Mezzio Essentials』と『Deploy with Docker Compose』の著者でもあります。彼の連絡先は、msetter[at]twilio.com、LinkedIn、GitHubです。

電話のアイコンはFlaticonのFreepikが作成したもので、とびきりキュートなフェリスはrustacean.netからのものです。

AI生成による要約
  • SMSを送信する前に固定電話番号を除外して、エラーを回避します。
  • Rustプロジェクトをセットアップし、Twilio Lookup v2 APIを使用して電話番号の種類を検証します。
  • Twilioの認証情報を使用して、配信不能なメッセージの送信を防止します。

この要約は、AIにより生成されました。