Twilio Functionsを使ってTwilio Chat、Video、Voice用のアクセストークンを生成する

August 27, 2021
レビュー担当者

Twilio Functionsを使ってTwilio Chat、Video、Voice用のアクセストークンを生成する

この記事はTwilio Developer VoicesチームのAshley Boucherこちらで公開した記事(英語)を日本語化したものです。

TwilioはProgrammable Video、Programmable Voice、Programmable Chat、Conversations製品のクライアントサイドのソフトウェア開発キット(SDK)を提供しています。

これらのSDKを利用するためには、アクセストークンを生成する必要があります。Twilioのドキュメントで説明されているように、アクセストークンは、VoiceChatVideoなどのTwilioクライアントSDKを認証するための短期のトークンです。クライアントの身元を確認し、クライアントのAPI機能へのアクセスを許可するために、サーバー上で作成します。

本稿では、Twilio Functionsを使ってアクセストークンを生成する方法をご紹介します。ご紹介する方法は今後のプロジェクトで何度も繰り返し使用できるので、時間の節約にもつながります。

必要なもの

依存関係をインストールする

まずはTwilio Functionsの設定をしましょう。Twilio Functionsは、サーバーを設置せずにバックエンドサービスを展開できるサーバーレス環境です。Twilio FunctionsはTwilio CLIのプラグイン、あるいは、Twilio Consoleのユーザーインタフェースで管理できます。本稿ではCLIを使用します。

Twilio CLIを導入していない場合は下記のコマンドを実行し、インストールしてください。

npm install twilio-cli -g

CLIをインストールしたら、Twilio Serverless Toolkitプラグインを追加します。

twilio plugins:install @twilio-labs/plugin-serverless

twilio loginコマンドを実行して、Twilio CLIにログインします。

ログイン時にAccount SIDAuth Tokenを含むアカウント認証情報の入力が求められます。これらの情報は、Twilio Consoleのダッシュボードで確認できます。

これでログイン状態となりました。早速、開発を始めましょう。

TwilioFunctionを作成する

新しいTwilio Functionサービスを初期化します。

twilio serverless:init token-service

このコマンドを実行すると、token-serviceという新しいフォルダが作成されます。このフォルダの中には、いくつかのサブフォルダとCLIで提供されるサンプルファイルがあります。必ずフォルダ自体は残し、assetsfunctions配下に存在するフォルダやファイルをすべて削除してください。

functionsフォルダ内にtoken.jsというファイルを作成します。

このファイルには、アクセストークンを生成するためのコードを記述します。

新しいファイルの中に、Twilio Functionの枠組みを作成します。

exports.handler = function(context, event, callback) {
 
}

認証情報を集める

作成した関数の中から、Twilioアカウントの認証情報を保管する環境変数にアクセスする必要があります。Functionサービスを初期化すると、token-serviceの中に.envファイルが作成され、Account SIDAuth Tokenの変数が自動的に記入されるので、このファイルを使用していきます。

token-serviceフォルダ内の.envファイルを開き、事前に入力されたAccount SIDAuth Tokenが、CLIへのログインに使用した認証情報と一致していることを確認してください。

この2つの認証情報に加えて、APIキーが必要になります。

Twilio ConsoleのAPI Keysにアクセスします。(+)記号のボタンをクリックして、新しいAPIキーを作成します。キーには、作業中のプロジェクトを象徴するようなわかりやすい名前をFriendly Nameテキストフィールドに入力し、Key TypeStandardのままにしておきます。準備ができた段階でCreate API Keyをクリックします。

次の画面では、SIDSECRETを含む情報が表示されます。SIDはあなたのAPIキーです。

SIDをコピーして、新しい環境変数API_KEYの値として.envファイルに貼り付けてください。次に、SECRETの値をコピーして、環境変数API_SECRETの値として、.envファイルに貼り付けてください。

この画面を離れると、SECRETには二度とアクセスできなくなります。そのため、これらの値のバックアップしておくことを推奨します。

環境変数の設定が完了したら、token.jsの新しい関数の中に、以下のハイライトされている行を追加します。

exports.handler = function(context, event, callback) {
  const twilioAccountSid = context.ACCOUNT_SID;
  const twilioApiKey = context.API_KEY;
  const twilioApiSecret = context.API_SECRET;
  const identity = event.identity;
}

.envファイルに保存されている環境変数は、Twilio Functionsが提供するcontextオブジェクトで利用できます。同様に、Twilio FunctionへのAPIコールで渡されたURLパラメータはすべて、eventオブジェクトで利用可能です。

このエンドポイントを呼び出す際には、ユーザーIDを渡す必要があります。このIDはアクセストークンを生成するために必要で、値はevent.identityからアクセスできます。IDはユーザー名のようなものと考え、クライアントにアクセストークンを発行する前に、このIDをどのように検証するかを慎重に検討してください。

トークンを生成する

関数の中で、既存のコードの下に以下のハイライトされている行を追加します。

exports.handler = function(context, event, callback) {
  ...
 
  const AccessToken = Twilio.jwt.AccessToken;

  const token = new AccessToken(
    twilioAccountSid,
    twilioApiKey,
    twilioApiSecret,
    {identity: identity}
  );
}

このコードで、TwilioからAccessTokenオブジェクトを取得します。Twilio Functionの中からTwilioクライアントに自動的にアクセスできます。

そして、アカウントの認証情報とFunctionに渡されたIDで新しいアクセストークンを初期化します。各アクセストークンの最大有効期間は24時間です。それ以降は、トークンの更新や新しいトークンの作成が必要になります。

トークンに認可(Grant)を与える

次に、アクセストークンに認可(Grant)を与えます。Grantは、アクセストークンの保有者が指定されたAPIサービスへのアクセスを許可されていることを示します。Grantがなければ、アクセストークンは無意味になります。

この手順は、Video、Chat、VoiceのいずれのSDKを使用しているかによって若干異なります。お使いのSDKのセクションを参照してください。

トークンに認可(Grant)を与える:Programmable Video

トークン作成後、既存のAccessTokenオブジェクトからVideoGrantオブジェクトを取得する必要があります。

既存のコードの下、関数の中に次のコードを追加してください。

const VideoGrant = AccessToken.VideoGrant;
const videoGrant = new VideoGrant();
token.addGrant(videoGrant);

このコードは、VideoGrantオブジェクトの新しいインスタンスを初期化し、それをアクセストークンに追加します。

これは最もシンプルな実装です。アクセストークンの保有者はクライアントサイドのアプリにあるProgrammable Videoサービスと、サービス上で作成されたすべての部屋にアクセスできます。また、権限付与の際にこれを指定することで、保有者のアクセスを特定の部屋のみに制限したい場合、上記のコードは次のようになります。

const VideoGrant = AccessToken.VideoGrant;
 
const videoGrant = new VideoGrant({
  room: 'cool room' // the specific room's name
});

token.addGrant(videoGrant);

部屋名の値をハードコードすることもできますし、クライアントから渡すこともできます。後者の場合、部屋名はidentityと同様にeventオブジェクトで取得できます。

トークンに認可(Grant)を与える:Programmable ChatとConversations

アクセストークンにChat認可(Chat Grant)を与えるには、TwilioコンソールまたはCLIで新しいChatサービスを作成し、そのService SIDを取得する必要があります。

UIを使ってこれを行うには、Twilio Consoleのチャットサービスエリアで、Chat Servicesの下のプラスボタンをクリックして、新しいチャットサービスを初期化します。次の画面で新しいサービスを設定し、そのService SIDを確認できます。この値をコピーして、新しい環境変数SERVICE_SIDの値として、.envファイルに貼り付けてください。

次に、token.jsに戻って、既存のコードの下の関数内に次のコードを追加します。

const ChatGrant = AccessToken.ChatGrant;
 
const chatGrant = new ChatGrant({
  serviceSid: context.SERVICE_SID,
});

token.addGrant(chatGrant);

このコードは、先ほど取得したService SIDChatGrantオブジェクトの新しいインスタンスを初期化し、トークンにChat認可を追加します。

トークンに認可(Grant)を与える: Programmable Voice

クライアントサイドのアプリでProgrammable Voice APIを使用する場合、クライアントサイドのTwilio Deviceとアクセストークンを含むサーバーサイドのコードの間の橋渡しをするTwiML Appを作成する必要があります。

TwiML Appを作成するには、TwilioコンソールのProgrammable VoiceダッシュボードのTwiML Appsに移動します。

(+)記号のボタンをクリックして、新しいTwiML Appを作成します。識別しやすい名前を付け、必要に応じて他のフィールドに記入し、Createボタンをクリックてください。

Createボタンをクリックすると、TwiML Appsのダッシュボードに戻ります。作成したばかりのアプリをクリックすると、アプリ名のすぐ下にアプリのSIDが表示されます。この値をコピーして、新しい環境変数OUTGOING_SIDの値として、.envファイルに貼り付けてください。

token.jsに戻って、関数内の既存のコードの下に次のコードを追加します。

const VoiceGrant = AccessToken.VoiceGrant;
 
const voiceGrant = new VoiceGrant({
  outgoingApplicationSid: context.OUTGOING_SID,
  incomingAllow: true // allows your client-side device to receive calls as well as make them
});

token.addGrant(voiceGrant);

このコードはVoiceGrantオブジェクトの新しいインスタンスを、あなたのTwiML AppのSIDと、incomingAllowキーで初期化し、クライアント側のTwilioデバイスが電話を受ける、またかけることができるかを指定するパーミッションを設定します。このキーは任意です。

レスポンスを送信する

アクセストークンの準備ができたら、新しいResponseオブジェクトを作成して、呼び出し元であるクライアントサイドのアプリケーションに送り返します。

exports.handler = function(context, event, callback) {
  ...

  const response = new Twilio.Response();
  const headers = {
    "Access-Control-Allow-Origin": "*", // change this to your client-side URL
    "Access-Control-Allow-Methods": "GET,PUT,POST,DELETE,OPTIONS",
    "Access-Control-Allow-Headers": "Content-Type",
    "Content-Type": "application/json"
  };
       
  response.setHeaders(headers);
  response.setBody({
    accessToken: token.toJwt()
  });

  return callback(null, response);
}

このコードでは、クライアント側がレスポンスを受信できるように、CORSヘッダーを設定します。

上記コードの6行目では、Access-Control-Allow-Originキーの値を、クライアントサイドアプリのルートURLに変更することを強く推奨します。コードサンプルのまま使用すると、クライアント側のコードが複製され、あなたのアクセストークンのコードに簡単に接続できる未承認のアプリを構築するために使用される可能性があります。

作成したtoken.jsファイルを保存して閉じます。これで、トークン機能の導入が完了しました。

次のコマンドを実行してください。

twilio serverless:deploy

デプロイが成功すると、Twilio Functionサービスに含まれるすべてのAssetとFunctionのURLリストが表示されます。

Twilio Functionサービスに含まれるAssetとFunction URLのリスト

Functionsのヘッダーの下に、https://token-service-XXXX-dev.twil.io/tokenのようなURLが表示されているはずです。 これは、クライアントサイドのアプリケーションでアクセストークンを取得する際のエンドポイントとなりますので、大切に保管してください。

ターミナルでcurlを使用してレスポンスを確認できます(以下のプレースホルダーURLではなく、特定のURLを使用してください)。

curl token-service-XXXX-dev.twil.io/token

これで、クライアントサイドのTwilioアプリのためのアクセストークンを生成するコードをデプロイできました。

今回作ったものを実際のプロジェクトで試してみたいという方は、「Build a Browser-Based Walkie Talkie」のような、クライアントサイドSDKを使った他のチュートリアルを参照してください。

Ashleyは、TwilioブログのJavaScriptエディターです。Ashleyと協力し、Twilioにテクニカルストーリーを紹介するには、Twitterで@ahl38までご連絡ください。TwitterでAshleyが見つからない場合は、どこかのパティオでコーヒーを飲んでいることでしょう(ワインの時間かも)。