https://d226lax1qjow5r.cloudfront.net/blog/blogposts/serverless-sms-nexmo-ibm-dr/sms-fortune-cookie.png

NexmoとIBMによるサーバーレスSMSフォーチュンクッキー

最終更新日 May 3, 2021

所要時間:1 分

SMSを使ったユーザーとのコミュニケーションは、インフォーマルに人々と交流する優れた方法です。よくある質問に対する返答を自動化するにしても、コンペを開催するにしても、全く別のことでユーザーとつながるにしても、SMSは素晴らしい選択です。この投稿では、これらのタスクを達成する方法の詳細を見ていきながら、楽しく些細な例を見ていきます。受信したSMSに「フォーチュン・クッキー」で応答するシステムを構築します。これは古い*nixワークステーションの「今日のメッセージ」機能で使われる挨拶で、Slackで見かける愛らしいローディング・メッセージのギークなバージョンだと思ってほしい。

サーバーレスは、受信する各メッセージが他のすべてのメッセージから独立している、このようなタスクに理想的な選択肢だ。次のようなサーバーレス・プラットフォームがある。 IBM Cloud Functions(この例で使用)、 アマゾンラムダまたは Azure Functionsはすべて、負荷がかかったときに水平方向にスケールする。サーバーレス・プラットフォームは関数の実行時間に対してのみ課金されるため、実行中のサーバーに対して固定料金を支払う必要がない。ボーナスとして、関数をデプロイするために必要なステップは、サーバーをセットアップするよりも少ないので、素早く始めることができます。

始める前に

このチュートリアルに従う前に、いくつかの前提条件があります:

ステップ1:サーバーレス関数の作成とデプロイ

サーバーレス関数は、クラウドにデプロイされた関数(これはJavaScriptだが、IBM Cloudは他の多くのプログラミング言語をサポートしている)である。関数はイベントに応答して実行され、一般的なイベントの1つはウェブ・リクエストだ。1つの関数を作成してデプロイすることで、ユーザーからのSMSを受信する準備をすぐに整えることができる。

この関数は GitHub上の特定のバージョンへのリンクはこちら.この短縮版のようなコンテンツができるはずだ:

function main(params) {
  // pick a random cookie from the data
  var data = getCookies();
  var random = Math.floor(Math.random() * 430);
  var cookie = data[random];

  // log the cookie and then return it as body data
  console.log(cookie);
  return { body: cookie };
}

function getCookies() {
  return [
    "A day for firm decisions!!!!! Or is it? ",
    // ~400 more lines
    "Your talents will be recognized and suitably rewarded. ",
    "Your temporary financial embarrassment will be relieved in a surprising manner. ",
    "Your true value depends entirely on what you are compared with. "
  ];
}

コンテンツを index.jsに保存し main()関数を見てみよう。フォーチュン・クッキーの大きな配列(Ubuntuの Ubuntuの fortune-modパッケージからから)フォーチュン・クッキーの大きな配列を取得し、ログに記録して返す前に、ランダムに1つを選びます。もし getCookies()関数を編集して別のフォーチュン・クッキーを提供したい場合は、どうぞ!

サーバーレス・プログラミングでは、「関数」は通常「アクション」と呼ばれる。

そのアクションをクラウドに取り込むために、まずは パッケージを作る。パッケージはアクションをまとめ、パラメータを共有するのに役立つ。

先ほど設定した bxコマンドを使ってパッケージを作成する:

bx wsk package create sms-fortune

OK "のハッピーな出力が表示されるはずだ。パッケージができたので、関数をデプロイしよう。これがそのコマンドだ:

bx wsk action update sms-fortune/incoming --kind nodejs:8 --web raw index.js

もう一度、コマンドが正常に完了したことを示す "OK "を確認してください。関数をデプロイしました。これは incoming(SMSの着信を処理するため)と呼ばれ、パッケージ内に存在します。 sms-fortuneパッケージ内に存在する。ここでの他の引数は --kind使用するJSのバージョンと --web rawで、このアクションにウェブリクエストを行うことができます。

呼び出す updateがトリガーされる。 createをトリガーするので、このコマンドは現在の状態に関係なく動作します。このコマンドは現在の状態に関係なく動作します。 index.jsを編集して再度デプロイしたい場合にも機能します。

さて、何を待っているのでしょう?アクションのURLを見つけて、リクエストしよう。アクションのURLを見つけるコマンドは次のとおりです:

bx wsk action get --url sms-fortune/incoming

上記コマンドのレスポンスからURLをコピーする。先に進んで cURLやブラウザ、その他のHTTPクライアントを使ってそのURLにリクエストすることができる。すべてが計画通りに進んでいれば、応答には気の利いた言葉が含まれているはずだ。必要であれば、さらに気の利いたことを言うためにリクエストを数回繰り返してください。

ステップ2: SMS受信の処理

Webhookが指し示すべきエンドポイントはすべてセットアップされているので、それを配線しよう。SMSを受信するための SMSを受信するためのビルディングブロックを参照してください。

まず第一に、Nexmoが私たちの関数を呼び出したことを確認する方法が必要です。今のところ、直接リクエストしているが、SMSを受信した場合、私たちが見ることができる応答はない。その代わりに、新しいターミナル・ウィンドウを開き、次のコマンドで自分のアクションのログを見始める:

bx wsk activation poll

この関数を実行したときに何が起こるかを見ることができるように、この関数を実行したままにしておき(2つ目のモニターがあれば、そこに表示させたい)、先ほどと同じcurl/browserリクエストを使用する。お気づきかもしれませんが、リアルタイムではないので、ログが表示されるまで数秒待つ必要があることもあります。

この関数が正常に実行されていることを確認できたので、これをSMSのエンドポイントにしてみよう。あなたの Numbersページにアクセスし、使用する番号の "編集 "をクリックし、"SMS "の下の "Webhook URL "フィールドにアクションURLを貼り付けます。更新」をクリックするのを忘れないでください。

着信番号にSMSを送信し、そのログを見て、アクションが実行されるのを確認する!

ステップ3:応答すべき番号を見つける

この時点で、サーバーレス・アクションをデプロイし、SMS受信ウェブフックのエンドポイントとして設定した。SMSを送信したユーザーに返信できるようにするには、誰が送信したかを確認するために、Webhookで送られてくるデータを検査する必要があります。

IBM Cloud Functions (および Apache OpenWhisk 全般) のアクションは、1 つのパラメータを受け入れます。 params.コードに console.log(params)をコードに追加すると、関数が実行されたときに受け取るすべてを見ることができます。をチェックする SMS着信のAPIドキュメントを確認する。と呼ばれるクエリ・パラメータとして、返信したい電話番号が送られてくることがわかります。 msisdn.

電話番号を取得するには、関数にセクションを追加します。 main()という配列に取り込むセクションを追加すればよい。 query_dataという配列に取り込みます:

// who are we texting? Get phone number
var query_pieces = params.__ow_query.split("&");
var query_data = [];
query_pieces.forEach(function(item) {
  item_pieces = item.split("=");
  query_data[item_pieces[0]] = item_pieces[1];
});
console.log("Destination: " + query_data["msisdn"]);

上記のコードはきれいではないし、これらの変数が存在しない場合に何が起こるかについては細心の注意を払うべきだが、このセクションを index.jsに追加し、前と同じコマンドを使って再デプロイする:

bx wsk action update sms-fortune/incoming --kind nodejs:8 --web raw index.js

そのログを見ながら、もう一度着信番号にSMSを送信する。今度は、ログに行 Destination:と送信元の電話番号がログに表示されるはずです。これでSMSを送り返すのに必要な情報が手に入った。

ステップ4:秘密を設定する

アカウントにログインしてデータを送信するURLを設定する必要があったので、Webhookで受信SMSを受け取ることができる。しかし、返信SMSを送信する前に、認証が必要です。

このセクションでは、APIキーとAPIシークレットが必要です。 ダッシュボード.このようなシークレットを扱うベストプラクティスに従うため、これらの値をファイルに書き込むことは避け、代わりに 環境変数.新しいターミナル・ウィンドウを開いたり、コンピュータを再起動したりしても、変数は持続しないので、再度設定する必要があります。

設定する変数は NEXMO_API_KEYNEXMO_API_SECRETで、コマンドは次のようになる(記号の後は値を置き換える)。 =記号の後に値を置き換える);

export NEXMO_API_KEY=awesomeKey
export NEXMO_API_SECRET=awesomeSecret

現在の環境は秘密を知っているので、それをコマンドに使うことができる。

次に、これらの秘密を先ほど作成したパッケージに教える。パッケージを更新し、パラメータを設定することでこれを行う。これがそのコマンドだ:

bx wsk package update sms-fortune -p apikey $NEXMO_API_KEY -p apisecret $NEXMO_API_SECRET

これらのパラメータはコードの中にはありませんが、パッケージの中にあるので、同じパッケージの中にあるアクションで使用できます。アクションに console.log(params)コマンドをアクションに追加し、デプロイしてログを見ながら実行すると、これらの値が表示されます。

これで、返信SMSを送信するのに必要なすべての情報が揃いました。クッキー、電話番号、そしてAPIの認証情報です。

ステップ 5: SMSでフォーチュンクッキーを送る

最初にメッセージを送ってきたのと同じ番号にSMSを返すには、APIコールが必要です。このセクションでは、パズルの最後のピースを扱います。このセクションでは、この最後のパズルを扱います。 SMS送信のためのビルディングブロックのビルディングブロックも参考になるでしょう。

サーバーレスJavaScriptで気をつけなければならないことのひとつは、サーバーレスJavaScriptには イベントループがないことだ。その結果、データベースクエリやコード内でこれから行うAPIリクエストのようなすべての非同期操作は、promisifiedかasync/awaitを使って処理する必要がある。この例では request-promiseライブラリを使用して、このプロミス化されたAPIコールを有効にしている。

ライブラリを追加すると、すべてを1つの index.jsしかし、対処できないことはない。

手始めに package.jsonファイルが必要だ。私のはこんな感じだ:

{
  "name": "sms-fortunes",
  "description": "Simple demo for getting a fortune cookie by SMS",
  "dependencies": {
    "request": "^2.85.0",
    "request-promise": "^4.2.2"
  }
}

このファイルを をコピーすることができます。.必要であれば編集し(おそらく編集する必要はない)、以下のようにしてこれらの依存関係をインストールする。 npm:

npm install

アクションをデプロイするとき、ライブラリだけでなく index.jsファイルも含める必要があります。これを実現するには、必要なものすべてを1つのファイルに圧縮して、代わりにそれをデプロイすればいい。これは複数ステップのプロセスなので(まあ、2ステップですが)、私はこれを処理するスクリプトを作成するのが好きです。こうすれば、zipファイルを再作成するのを忘れたり、クラウドにプッシュするのを忘れたりすることがなくなる!

これが私の deploy.shファイルです。 はGitHub:

#!/bin/bash

rm -f sms-fortune.zip
zip -rq sms-fortune.zip index.js node_modules

bx wsk action update sms-fortune/incoming --kind nodejs:8 --web raw sms-fortune.zip

このスクリプトは、古いzipファイルを削除し、新しいzipファイルにファイルと要件を追加し、先ほどと同じアクション更新コードを実行しますが、代わりにzipファイルを提供します。では index.jsを更新し、このスクリプトか上記のコマンドを使ってアクションをデプロイします。

使用するには deploy.shユーザが実行できるようにする必要があります。

のアップデート版を手に入れよう。 index.js更新版を の更新版をGitHubから最新版を入手し、あなたのプロジェクトに入れてください。このコードの短縮版を以下に掲載する:

const rp = require("request-promise");

exports.main = function(params) {
  // choose a fortune cookie for this user
  var data = getCookies();
  var random = Math.floor(Math.random() * 430);
  var cookie = data[random];
  console.log("Fortune: " + cookie);

  // who are we texting? Get phone number
  // WARNING fails horribly if this data isn't present
  var query_pieces = params.__ow_query.split("&");
  var query_data = [];
  query_pieces.forEach(function(item) {
    item_pieces = item.split("=");
    query_data[item_pieces[0]] = item_pieces[1];
  });
  console.log("Destination: " + query_data["msisdn"]);

  // text the cookie to the user who texted us
  var options = {
    method: "POST",
    uri: "https://rest.nexmo.com/sms/json",
    body: {
      from: "SMS Fortunes Demo",
      text: cookie,
      to: query_data["msisdn"],
      api_key: params.apikey,
      api_secret: params.apisecret
    },
    json: true
  };

  return rp(options).then(function(response) {
    // response has info from Nexmo SMS service
    return Promise.resolved({ statusCode: 200, body: cookie });
  });
};

function getCookies() {
  return [
    "A day for firm decisions!!!!! Or is it? ",
    // ~400 more lines
    "Your talents will be recognized and suitably rewarded. ",
    "Your temporary financial embarrassment will be relieved in a surprising manner. ",
    "Your true value depends entirely on what you are compared with. "
  ];
}

これをすべてまとめ、ジッパーに入れ、配備し、予期せぬことが起きたときのためにログを見続け、着信番号にSMSを送る。タダ!おみくじクッキーのお返事です。)

結論

SMSはユーザーにとって簡単ですが、この例から、開発者にとってもかなり実現可能であることがお分かりいただけたと思います。このコードはSMSを受信してユーザーを特定し、同じユーザーにSMSを送り返す。サーバーレス・バックエンドを使っているのは、実行コストが安く、簡単に始められるからだ。この例では些細な内容を返したが、きっとあなたのアプリケーションのアイデアをかき立てるだろう。例えば、受信したメッセージを解析し、それに基づいて異なるレスポンスを返したり、シンプルにするためにこの記事のようにハードコードするのではなく、APIを呼び出してコンテンツを取得することもできる。空は無限であり、我々はあなたが何を作るか知りたい!

次のステップ

SMSをもっと使いこなしたいと思われたなら、次のアイデアをご覧ください:

シェア:

https://a.storyblok.com/f/270183/250x250/e3d3b71060/lornajane.png
Lorna Mitchellヴォネージの卒業生

ローナはブログ癖のあるソフトウェア・エンジニアだ。彼女は言葉とコードを同等に扱おうとしている。