TypeScriptとDenoを使用してCLIを構築する方法
読む所要時間: 20 分
Twilio Programmable SMSには、SMS APIとのやりとりを容易にするHTTP REST APIが含まれます。REST APIを使用してSMSメッセージのリクエストを作成すると、そのステータスは他のエンドポイントを使用して取得できます。REST APIを組み込むことにより、メッセージと配信についてのレポートを送信するDeno CLIアプリケーションを構築できます。
DenoはJavaScript用の新しいランタイム環境です。この環境ではNode.jsの機能を提供しますが、Node.jsアプリケーションで必要な重いパッケージの展開や、複雑なパッケージ管理は不要です。
Denoが提供する新たな機能は、JavaScriptを使用して開発されている現代のサーバー側アプリケーションをサポートします。そのアプリケーションの幅広さは、Node.jsが開発されたときには想定されていなかったものです。
DenoはTypeScriptをネイティブでサポートするため、追加のコンポーネントは必要ありません。Denoを使用して書かれたアプリケーションは「リモート」でも起動できます。つまり、ユーザーが実行するスクリプトは、URIで指定され、そのURIはWeb上にホストされているファイルを示しているということです。Denoがスクリプトやその他の必要な依存関係を自動的にダウンロードしプログラムを実行します。
Denoはモジュール性に優れています。既存のコードを活用したプログラムの構築が可能であり、SMSメッセージのリクエストを作成してステータスを監視します。また、他のプログラミング言語と同様にコマンドライン引数をサポートしているため、CLIプログラムを作成してあらゆるユースケースに対応できます。
コンプライアンスに関する重要なお知らせ: SMSメッセージの利用については、国によりルールが異なります。メッセージ送信先国のルールについては、Twilio利用規定のSMS向けガイドラインをご確認ください。
チュートリアルのプロジェクトについて
このチュートリアルでは、Denoを使用してCLIプログラムを作成する方法について説明します。Denoの機能を試すため、電話番号にSMSメッセージを送信し、メッセージの配信ステータスをレポートするCLIプログラムを記述します。Twilio CLIと異なる点として、このプログラムはメッセージの配信ステータスをレポートする際に他のコマンドを実行する必要がない点が挙げることができます。チュートリアルで使用するものはTwilioSMSHelperです。このヘルパーはTwilio Programmable SMSを利用してTwilioのREST API経由でメッセージを送信します。
さらにyargsライブラリを利用し、Denoでコマンドライン引数を読み込む方法を学習します。引数エイリアスのショートカットを登録する方法(--argument, -a)についても理解しましょう。また、ユーザーが引数の一部を指定しない場合に、環境変数にフォールバックする方法も学習します(ここでlodashを利用します)。さらに、lodashのdifference()
メソッドを利用して2つのオブジェクトキーを比較し、入力値が不足していないことを確認する方法も学習します。
前提条件
このチュートリアルで説明するプロジェクトを完成させるには、次のツールとリソースが必要です。
- Deno – インストール手順に則りパッケージをインストール。さまざまなオペレーティングシステムとパッケージ管理ツールに対応
- Twilioアカウント – このリンクから無料でサインアップすると、通常版アカウントにアップグレードする際に利用できる10ドルのクレジットを進呈
- Twilio電話番号 - Twilio CLIを使用して電話番号を登録する方法を確認
- Git – コンパニオンリポジトリのクローン作成、またはソースコードをGit repoとして管理する際に
Visual Studio Codeを利用している場合は、次のdenoland.vscode-deno拡張機能がインストールされていることを確認してください。
Deno拡張機能はインテリジェントモジュールインポートをはじめとする多数の機能を提供し、IntelliSenseを完全サポートしています。
また、TypeScript、非同期JavaScriptのメカニズム、ReactiveXプログラミングのコア要素に関する実践的知識やDenoの要点に関する知識も有益です。はじめてDenoを利用する場合は、Twilioブログのこちらの投稿「Hello Deno」で基礎を学習できます。
さらに、この投稿に関するコンパニオンリポジトリがGitHubで提供されています。このチュートリアルで説明するプロジェクトに使用できる完全なソースコードを含み、MITライセンスで利用できます。ご自身のプロジェクトでご使用ください。
Twilioアカウントの資格情報の取得
Twilio CLIを使用し、Twilio APIで情報をやりとりするには、3つの重要な情報が必要です。このアカウントSID、APIキー 、APIシークレットの情報はTwilioコンソールのダッシュボードで確認できます。[Account ID](アカウントSID)は、ダッシュボードの右上にあります。APIキーとAPIシークレットを生成するには、[Settings](設定)の[API Keys](APIキー)に移動します。ここで赤い[+]ボタンをクリックすると新しいキーが生成されます。
以上の情報を手元にご用意ください。次のステップでご自身のCLIアプリをテストする際に必要です。
Deno CLIの構築
Denoプロジェクトの初期化
電話番号の登録とテストが済むと、一連のコマンドラインの命令によりプロジェクトとGitリポジトリを初期化できます。
コンソール画面を開き、プロジェクトディレクトリを作成するディレクトリで次の命令を実行します。
このコマンドでプロジェクトディレクトリと最初のコードファイルを作成しプロジェクトのGitリポジトリを初期化します。
Visual Studio Code用のDeno拡張機能の有効化
「前提条件」のセクションで述べたVisual Studio CodeとDeno拡張機能を使用している場合は、このプロジェクト用に拡張機能を初期化する必要があります。
プロジェクトフォルダで.vscode/settings.jsonファイルを作成し、次のJSONコードを追加します。
VS Codeのユーザーインターフェイスを使用し、ワークスペースの設定を変更することもできます。Deno拡張機能は、ユーザーに対して有効にはしないでください。
コマンドライン引数の読み込み
ユーザーが指定した引数を読み込むには、yargsライブラリを使用します。Denoの性質上、依存関係をインストールする必要はありません。import文を追加するだけで十分です。
twilioSMSCLI.tsファイルを開き、次のコードをコピーします。
yargs
ライブラリをインポートする場合を除き、上記のコードはArguments
インターフェイスを取り込みます。このインターフェイスは、プログラムが受け付けた引数のリストです。リストには次の引数が含まれます。
from
- Twilio番号。メッセージの送信に使用to
- 受信者の電話番号body
- メッセージ本文sid
- TwilioのアカウントSIDapikey
- Twilio APIキー(API SID)secret
- 指定されたAPIキーに対応するシークレット
後ほど、Deno.args
下に保存されているコマンドライン引数を、yargs
ライブラリを使用して解析し、inputArgs
変数に割り当てます。なお、各パラメーターのショートカットを定義することにより、完全なパラメーター名または1文字の短縮形を使用できます。
--from
=>-f
--to
=>-t
--body
=>-b
--sid
=>-i
--apikey
=>-k
--secret
=>-s
最後に、受け取った入力値をコンソールに表示します。
次のコマンドを使用してプログラムのテストを実行します。
次のように表示されます。
このようにフルネームと短縮形のいずれを使用しても、引数を渡すことができます。
残念ながらこのプログラムはユーザーが必要な情報をすべて入力したかどうかを検証していません。この点については、エラー処理によるプログラムの機能強化で改善するとよいでしょう。
最初に、lodash
ライブラリを取り込むために次のimport文をtwilioSMSCLI.tsファイルの最上部に入力します。
続けて次のコードを追加します。追加する場所は、最下行のconsole.log(inputArgs);
文のすぐ上です。
errorMessages
マップオブジェクトの取り込みが終わりました。このオブジェクトは、引数の一部が不足している場合に表示されるメッセージを保持しています。
オブジェクト宣言の:{[k:string]: string}
型は、このオブジェクトが、string
型プロパティをstring
キーの下に保持しているという情報を、TypeScriptコンパイラに伝えます。そのおかげで、stringリテラルの代わりにエントリーキーを表す変数を使用しこれらのオブジェクトのプロパティに動的にアクセスできます。
次にerrors
配列を取り込みました。この配列には、不足しているユーザー入力値に関する情報が保持されています。この配列を完成するために、difference()
メソッド(lodashライブラリ)を使用しました。このメソッドは2つの配列(A and B)をパラメーターとして受け取り、3つ目の配列を返します。3つ目の配列に含まれる要素は、A配列にあり、B配列にはない要素です(A minus B: A\B)。この配列(A + B)は、オブジェクトerrorMessages
とinputArgs
のキーセットです。
つまり、inputArgs
に含まれないすべてのキーを、errorMessages
から探していることになります。
最後に、errors
の配列長を確認します。0より大きい場合は一部の入力が不足していることを意味し、エラーメッセージが表示されます。if
文の中では、errors
配列を用いて反復処理を行い、対応するエラーメッセージをerrorMessages
から出力します。次に、ユーザーにサンプルプログラムを提供し、Deno.exit(1)
文を用いてDenoのプロセスを終了します。
プログラムに戻り、入力値が不足値に対して検証されているかどうかを確認します。
次のように出力されます。
この時点ですべての引数が指定されていることを検証しています。
フォールバック: 引数が指定されていない場合に環境変数を参照
指定されるはずの多くの引数を、省略したがるユーザーもいます。そこで多くの場合、アカウントSID、APIキー、APIシークレット、Twilioの電話番号などの値を、環境変数に保管する方法がとられます。この手法では保管されている引数を必須のものとして扱い、値が提供されない場合には環境変数の値にフォールバックします。
この環境変数フォールバック機能を導入するには、lodashライブラリを使用します。
defaults()
メソッド(lodashライブラリから)と環境変数の値を使用して不足している値をinputArgs
に渡すことができます(例: Deno.env.get('VARIABLE_NAME')
)。
errorMessages
宣言の前に次のコードを入れてください。次のコードを、errorMessages
オブジェクトとinputArgs
オブジェクトのキーの違いを調べる行の前に挿入します: let errors: string[] = _.difference(_.keys(errorMessages), _.keys(inputArgs));
この段階で、完成したコードは次の内容となります。
フォールバックの機能をテストするには、アカウントの資格情報とTwilio電話番号を環境変数に保存します。
LinuxやmacOSなどのUnixベースのオペレーティングシステムを使用している場合は、次のコマンドで環境変数を設定します。
Windowsを使用している場合は次のコマンドを使用します。
プログラムを実行し、環境変数へのフォールバックが正しく動作することを確認します。
次のような出力が表示されます。
Twilio APIを使用してSMSを送信する
いよいよプログラムの本質について説明します。Denoの再利用可能性と、「Sending SMS Messages with Deno, TypeScript, and Twilio Messaging(Deno,TypeScript、Twilio Messagingを利用したSMSメッセージの送信)」の投稿で紹介されているコードを活用します。
次の文をtwilioSMSCLI.tsファイルの最初に追加し、TwilioSMSオブジェクトとSMSRequestオブジェクトをインポートします。
twilioSMSCLI.tsファイルの末尾のconsole.log()
の前に、inputArgs
オブジェクトの値に基づきSMSRequest
オブジェクトを作成します。そしてTwilioSMS
ヘルパーメソッドを初期化します。次に、sendSms()
メソッドをhelper
オブジェクトで呼び出します。
最終的に、console.log()
の呼び出しを含むこの行は、不要になれば削除できます。
SMS対応の電話番号を使用してプログラムを実行します(<phone_number>
を、このSMS対応の電話番号に置き換えます)。
携帯端末にSMSが送信されます。
コードの完成
これでプログラムの準備ができました。次の内容であることを確認してください。
これまでの手順を実行してきてはいないが、このチュートリアルのプログラムを実行したい場合は、コンパニオンリポジトリに完全なコードがありますのでご利用ください。このリポジトリをクローニングするには、プロジェクトのルートディレクトリを作成するディレクトリで、次のコマンドラインの手順を実行します(<phone_number>
をSMS対応の電話番号に置き換えてください)。
この記事では、yargsライブラリを使用してDenoにコマンドライン引数を読み込む方法について学びました。引数エイリアスのショートカットの登録方法も習得しました(--argument -a)。さらに、ユーザーから引数の一部が提供されない場合に、lodashを利用して環境変数へフォールバックする方法も分かりました。
Denoエコシステムの設計は、コードの再利用性に優れています。オンラインで公開されているコードは、他のDenoプログラムの中でも、スタンドアロンでも使用できます。次のコマンドを実行し、ぜひお試しください(<phone_number>
をSMS対応の電話番号に置き換えてください)。
その他のリソース
この投稿で紹介した内容について詳しくは、次のリソースを参照してください。
Hello Deno - Denoの基本について学習できます。
Asynchronous JavaScript: Introducing ReactiveX and RxJS Observables(非同期JavaScript: ReactiveXとRxJS Observablesの紹介) – ReactiveX Observablesを使用するプログラム方法を学びます。
Confirming SMS Message Delivery with RxJS Observables, Node.js, and Twilio Programmable SMS(RxJS Observables、Node.js、Twilio Programmable SMSを使用するSMSメッセージ配信の確認) - Node.jsでTwilioを使用してSMSメッセージを送信する方法について学びます。
TwilioQuest – 16ビットスタイルのアドベンチャーゲームでレガシーシステムの呪縛から解放されます。
Maciej Trederは、Akamai TechnologiesのSenior Software Development Engineerです。国際会議のスピーカーを務め、@ng-toolkitの作者でもあります。詳しくは、https://www.maciejtreder.comをご覧ください。ご連絡をいただく際は、contact@maciejtreder.com、@maciejtreder(GitHub)、Twitter、StackOverflow、LinkedInからお願いいたします。
この投稿はGabriela Rogowskaの協力によるものです。