Twilio Functionsを使ったサーバーレス開発のはじめ方

February 01, 2022
執筆者
レビュー担当者

Twilio Functionsを使ったサーバーレス開発のはじめ方

背景

「サーバーレス(Serverless)」というキーワードは近年脚光を浴び、さまざまな分野でサーバーレスを用いたソリューションが構築されています。本稿では、サーバーレス開発の概念と、Twilioが提供するサーバーレス環境である、Twilio Functionsを使った開発方法をご紹介します。

サーバーレスとは?

サーバーレスは、開発者がサーバーの構築や管理をすることなくアプリケーションを開発および実行できるクラウドを中心とした開発メソッドです。

サーバーレスアーキテクチャが誕生する前は、小さなプログラムであっても、そのプログラムを実行するサーバーを用意しなければなりませんでした。それだけでなく、用意したサーバーを運用し、常にリソースの使用状況を監視したり、脆弱性に対してパッチ適用をしたりと、維持管理が必要でした。

しかし、サーバーレスアーキテクチャでは、プログラムさえ構築してしまえば、利用者がサーバーの維持管理を行う必要がありません。デプロイされたアプリケーションは需要に応じて自動的に拡張・縮小し、セキュリティなどの管理もサーバーレス環境の提供側が行います。これにより、運用コストの低減やリソースの最適化が期待できます。

「サーバーレス」と言いますが、「サーバーが物理的に存在しない」という意味ではありません。サーバーが抽象化されていて、開発者が設計および運営上サーバーの管理を意識しなくてもいい、ということです。

Twilio Functionsとは?

Twilio Functionsは、Twilioが提供するサーバーレス環境です。TwilioアカウントとNode.jsだけで、サーバーを意識せずに簡単にSMS送信や電話の発信などを行うコミュニケーションアプリを本番環境でデプロイできます。

サーバーレス環境であることから、プラグインやソフトウェアなどをインストールしなくてもデフォルトでセキュリティ機能やアプリケーションの要件に合わせた自動拡張機能が提供されています。

SMSの受信などのイベントに対するTwilioのREST APIの呼び出しだけでなく、音声電話の操作、モバイルSDKトークンの処理や、サードパーティサービスとの連携など、可能性は無限大です。

目標

このチュートリアルを最後まで進めると、Twilio Functionsを使ったサーバーレス開発の方法を学べるとともに、SMSを自動送信するサーバーレスアプリケーションを開発できます。

必要なツール

このチュートリアルでは、以下の項目が必要です。

Twilio Functionsの仕組み

Twilio Functionsは、以下のように動作します。

Twilio Functionの概要
  1. クライアントがTwilio FunctionsのゲートウェイにHTTPリクエストを送信する。
  2. Twilio Functionsゲートウェイが該当するFunctionを呼び出す。
  3. Functions内で環境変数やアセットなどのリソースが自動実行される。
  4. Functionsで定義されているexports.handler()メソッドが実行される。このexports.handler()メソッドに、実際にプログラムで実行する処理(SMS送信、電話の発信など)のコードを格納します。
  5. callback()メソッドが実行される。 callback()メソッドにはクライアントに送信するレスポンスを定義します。
  6. Functionの処理が完了し、レスポンスがゲートウェイに送信される。
  7. ゲートウェイがクライアントにHTTPレスポンスを送信する。

Functionの仕組みが理解できたところで、実際にアプリケーションを構築しましょう。

サービスを作成する

まずは、サービスを作成します。サービスは、Twilioでアプリケーションを開発する際に、Function、AssetEnvironmentなど、開発で使用するリソースや機能などをアプリケーションごとにまとめるためのコンテナです。

サービスの概要

新しいサービスを作成するには、TwilioコンソールのServicesページを開きます。Create Serviceをクリックします。

Name your Serviceというポップアップが表示されます。Service Nameにサービスの名前を入力します。50文字以内の文字、数字、ハイフン(-)のみを入力してください。https://www.twilio.com/try-twilio?promo=iJb01Phttps://www.twilio.com/try-twilio?promo=iJb01Phttps://www.twilio.com/try-twilio?promo=iJb01P

ここで入力するサービス名は、作成するサーバーレスアプリケーションのドメインの一部となります。一度命名すると変更できません。

本稿では「my-first-twilio-function」と命名します。Nextボタンをクリックし、次に進みます。

サービスを命名

画面がFunctionサービスのエディタに切り替わります。これでサービスが作成できました。

ハンドラを追加する

SMS送信処理を行うハンドラ、exports.handler()を定義します。

サービスのエディタ画面の、Add+をクリックし、Add Functionをクリックします。

Functionを追加

/path_1と自動入力されたフィールドが表示されます。

このフィールドに、Functionのパスを入力します。このパスに対してクライアントがHTTPリクエストを送信することにより、Functionが実行されます。

/path_1を任意のパスに変更します。本稿では/smsと入力します。

パスを追加

エンターキーを押すと、画面右側にサンプルコードが表示されます。

コードサンプル

サンプルコードを、以下に変更します。

exports.handler = function (context, event, callback) {
  // Twilio REST APIクライアントを呼び出す
  const twilioClient = context.getTwilioClient();

  // HTTPリクエストに含まれる情報をもとにメッセージを形成
  // HTTPリクエストに情報がない場合のためにフォールバック値を設定
  const from = event.From || context.FROM_PHONE_NUMBER;
  const to = event.To || context.TO_PHONE_NUMBER;
  const body = event.Body || 'こんにちは!';

  // メッセージを送信
  twilioClient.messages
    .create({ to, from, body })
    .then((result) => {
      console.log('SMSを送信しました。');
      console.log(result.sid);
      // コールバック関数でレスポンスを送信
      return callback();
    })
    .catch((error) => {
      console.error(error);
      return callback(error);
    });
};

Saveをクリックします。

このコードでは、ハンドラにcontexteventcallbackをパラメーターとして渡しています。

  • contextオブジェクトはFunctionの実行環境とハンドラの間のインターフェースです。contextからヘルパーメソッド環境変数を取得します。
  • eventオブジェクトはクライアントからFunctionへのHTTPリクエストのパラメータとヘッダを含みます。
  • callback()はFunctionの処理の完了後に、クライアントに対してレスポンスを送信するためのコールバック関数です。

Function処理後は必ずcallback()を実行してください。callback()を実行しないと、10秒の実行時間制限までFunctionが実行され、時間制限に達するとFunctionが終了し、504 Gateway Timeoutがクライアントに返されます。

上記のコードでは、context.getTwilioClient()getTwilioClient()ヘルパーメソッドを呼び出しています。getTwilioClient()は初期化済みのTwilioクライアントを返すメソッドです。このメソッドを呼び出すことにより、TwilioのAPIをFunctionで使えるようになります。

from(SMSの送信元の電話番号)to(SMSの送信先の電話番号)body(SMSのメッセージ)を定義し、SMSの送信に必要な情報を設定します。fromtobodyにはそれぞれクライアントからリクエストに含まれる情報をeventオブジェクトから取得し、設定しています。

これらの情報がクライアントからのリクエストに含まれなかった場合のために、フォールバック値も設定しています。電話番号フォールバック値は、contextオブジェクトを通して、環境変数で設定しています。環境変数の値は、後ほど設定します。

最後に、twilioClient.messagescreateメソッドでfromtobodyをもとにSMSを作成し、送信します。.thenでSMSの送信完了後に、callback()関数を呼び出します。SMSの送信に失敗した場合は、エラーメッセージをcallback()に渡します。

これで、ハンドラの準備ができました。

環境変数を設定する

次に、環境変数を設定します。環境変数でfromtoのフォールバック値を設定します。

サービスエディタ画面のSettingsタブ配下のEnvironment Variablesをクリックします。

環境変数

 

環境変数の設定画面が表示されます。

KEYと、VALUEフィールドにそれぞれ、値を以下のとおり入力し、Addボタンで追加してください。

KEY

VALUE

FROM_PHONE_NUMBER

SMSの送信元の電話番号。

Twilioで取得した電話番号を指定します。E.164形式で入力してください。

TO_PHONE_NUMBER

SMSの送信先の電話番号。E.164形式で入力してください。

無料トライアルアカウントをお使いの場合は、認証済みの番号である必要があります。

最後に、Add my Twilio Credentials (ACCOUNT_SID) and (AUTH_TOKEN) to ENVがチェックされていることを確認してください。このオプションがチェックされていないと、Twilioの認証情報が環境変数として登録されず、Functionが実行されません。

環境変数の設定

Functionを公開する

FunctionにはPublicProtectedPrivateの3つの閲覧モードがあります。デフォルトのモードはProtectedです。FunctionのURLを通して外部からアクセスできますが、X-Twilio-Signature headerをリクエストに設定する必要があります。

これを回避するために、FunctionをPublicに変更します。

サービスエディタのFunctions配下の/smsの右側の、Protectedをクリックします。Publicをクリックします。

Publicに設定

これでFunctionをデプロイする準備ができました。

Functionをデプロイする

サービスエディタの画面下にあるDeploy Allをクリックします。

デプロイに関するログがコンソール部分に表示されます。

サービスをデプロイする

Deployed to environment: my-first-twilio-function-XXXX.twil.ioというログメッセージが表示されるとデプロイは成功です。

Functionをテストする

デプロイしたFunctionに、リクエストを送信して動作をテストします。まずは、FunctionのURLを取得します。

サービスエディタで、Copy URLをクリックします。

URLをコピーする

本稿で作成したFunctionのURLは以下の形式になります。

https://my-first-twilio-function-XXXX.twil.io/sms

XXXXはFunctionのURLごとに発行されるハッシュ値です。

ターミナルまたはPostman等のAPIテストツールで、以下のcURLコマンドを実行します。https://my-first-twilio-function-XXXX.twil.io/smsに、先ほどコピーしたURLを貼り付けます。

curl -XPOST https://my-first-twilio-function-XXXX.twil.io/sms

Functionが正しく実行していると、設定した電話番号に「こんにちは!」のSMSが届きます。

SMS

FunctionへのリクエストにSMSの設定情報を追加して送信する場合は、以下のコマンドを実行します。

curl -XPOST -d 'From={SMSの送信元の電話番号}&From={SMSの送信先の電話番号}&Body={SMSのメッセージ}' https://my-first-twilio-function-XXXX.twil.io/sms

Functionをデバッグする

Twilio Functionsのデバッグは、サービスエディタからできます。

サービスエディタでEnable live logsボタンをクリックします。

デバッグをしたい部分にconsole.log()を配置します。

Saveをクリックし、Deploy Allをクリックしてコードをデプロイします。

Functionのデバッグ

Functionにリクエストを送ると、以下のようなログが出力されます。

出力されたログ

CLIでFunctionをデプロイする

本稿ではTwilioコンソールのUI上でFunctionをデプロイする方法をご紹介しました。アプリケーションをローカル環境で作成・テストしたい場合は、Twilio Serverless Toolkitをご使用ください。Twilio Serverless Toolkitは、アプリケーションをCLIを通して開発およびデプロイするためのツールです。

Serverless Toolkitを使ってFunctionを開発する方法について詳しくは、Twilioドキュメントを参照してください。

最後に

Twilio Functionsは、簡単に短時間でサーバーレス開発ができるツールです。このチュートリアルをもとに、Twilio Chat、Video、Voice用のアクセストークンを生成したり、音声メッセージの自動書き起こしシステムを構築してみてはいかがでしょうか?デジタル化が進むにつれ、サーバーレスは着実に標準化した技術となってきています。これを機に、サーバーレス開発をぜひお試しください。

フィードバック、登壇、勉強会のお誘いなど気軽にsnakajima[at]twilio.comまでご連絡ください。開発中のプロジェクトに関してはGithub(smwilk)を覗いてみて下さい。