
GolangとAWS Lambdaを使ってNexmoでメッセージを送る
所要時間:1 分
私は最近、トム・モリスのチュートリアルを見た。 トム・モリスというタイトルのチュートリアルを見た。 Google Cloud Functionsを使ってPythonからSMSを送るPythonとGoogle Cloud Functionsは私の専門ではありませんが、SMSメッセージングの興味深い例と使い方だと思いました。
ブログを読んで、AWS Lambdaをファンクション・プロバイダとして拡張し、言語をGolangに変えたら面白いと思いました。
このチュートリアルでは、AWS LambdaとAWS API Gatewayを使用して、Nexmo Messaging APIでSMSメッセージを送信するAPIを、Goプログラミング言語で作成します。
必要条件
このチュートリアルを進める前に、いくつか満たしておかなければならない条件があります:
Goをインストールし、少なくとも多少は言語に慣れている必要がある。
Nexmo開発者アカウントが必要です。
Amazon Web Servicesのアカウントが必要です。
Goはコンパイル言語なので、ローカルで開発とビルドができる必要がある。私たちのビルドはAWSにアップロードされるので、AWSアカウントが必要です。これらのアプリケーションはNexmo Messages APIを利用する。
GoとAWS Lambda SDKによるメッセージング関数の構築
囲碁アプリケーションの開発に関しては、あまり多くのことは行われていない。イベントの流れとしては、以下のようになる:
ユーザーはこの関数にリクエストを出す。
この関数は、Nexmo Messages APIにHTTPリクエストを送信します。
この関数は、APIからのエラーまたはメッセージIDで応答します。
コア・ロジックはHTTPリクエストの周りにあるが、リクエストとレスポンスのデータ・モデルに関して少しセットアップが必要になる。
を指定します。 GOPATH内に main.goファイルを持つ新しいプロジェクトを作成する:
package main
var NEXMO_API_KEY string = "API_KEY_HERE"
var NEXMO_API_SECRET string = "API_SECRET_HERE"
func main() {}APIキーとAPIシークレットは、Nexmo開発者ポータルから取得できます。
AWS Lambdaプロジェクトになるので、Go SDK for Lambdaをインストールする必要があります。コマンドラインから以下を実行する:
go get github.com/aws/aws-lambda-go/lambdaGoパッケージ・マネージャーを通してSDKをインストールすれば、プロジェクト内で使用することができる。プロジェクト内で使用するには、以下のように変更します:
package main
import "github.com/aws/aws-lambda-go/lambda"
var NEXMO_API_KEY string = "API_KEY_HERE"
var NEXMO_API_SECRET string = "API_SECRET_HERE"
func Handler() {}
func main() {
lambda.Start(Handler)
}お察しの通り、メッセージングロジックはすべて HandlerクライアントがLambdaリクエストをしたときに実行されるからだ。
ロジックに入る前に、さまざまなリクエストとレスポンスのデータモデルを定義する必要があります。Goでは、データモデルを変数で明示的に定義する必要がある。 struct変数を使ってデータモデルを明示的に定義する必要があります。
以下を main.goファイルに追加する:
type NexmoMessageContent struct {
Type string `json:"type"`
Text string `json:"text"`
}
type NexmoMessage struct {
Content NexmoMessageContent `json:"content"`
}
type NexmoMessageService struct {
Type string `json:"type"`
Number string `json:"number"`
}
type NexmoMessagesRequest struct {
From NexmoMessageService `json:"from"`
To NexmoMessageService `json:"to"`
Message NexmoMessage `json:"message"`
}
type NexmoMessagesResponse struct {
Id string `json:"message_uuid"`
}Nexmo Messages APIを使用したことがある方なら、APIへのリクエストごとに送信されるJSONをご存知でしょう。上記のデータ構造は、送信されるデータを表しています。JSONアノテーションを使用すると、JSONは以下のようになります:
{
"from": { "type": "sms", "number": "SENDER_NUMBER_HERE" },
"to": { "type": "sms", "number": "RECIPIENT_NUMBER_HERE" },
"message": {
"content": {
"type": "text",
"text": "Hello World"
}
}
}Nexmo Messages APIにリクエストを送信すると、成功した場合はUUID付きのレスポンスが返されます。このデータを保持する NexmoMessagesResponse構造体を書いて、このデータをクライアントに送り返す予定です。
今足りないのは、クライアントがLambda関数に行うリクエストだけだ。この例がGoogle Cloud Functionsの例を模倣しようとしているのであれば、受信者の電話番号と使用しているモバイル・プラットフォームを期待している。
この情報を頭に入れれば、次のようなデータ構造を作ることができる:
type LambdaRequest struct {
Platform string `json:"platform"`
Recipient string `json:"recipient"`
}すべてのデータモデルが出来上がったので、残りの労力はメッセージングリクエストの作成に集中できる。
GoでHTTPリクエストを行うのは難しいことではない。以前書いたチュートリアルで、いくつかのアプローチについて詳しく説明しました。 GolangアプリケーションでRESTful APIエンドポイントを利用するというタイトルで書いたチュートリアルで、いくつかのアプローチについて詳しく説明しました。 http.Client構造を使うことです。この例では、Nexmoのドキュメントで説明されているようにPOSTリクエストを行う必要があります。 Nexmoのドキュメント.
まずは SendMessage関数を作りましょう。この関数は基本的に、Nexmoの多くのcURL例のようなリクエストを作ります:
func SendMessage(body map[string]string) (NexmoMessagesResponse, error) {
nexmoMessagesRequest := &NexmoMessagesRequest{
From: NexmoMessageService{
Type: "sms",
Number: body["from"],
},
To: NexmoMessageService{
Type: "sms",
Number: body["to"],
},
Message: NexmoMessage{
Content: NexmoMessageContent{
Type: "text",
Text: body["message"],
},
},
}
bodyData, _ := json.Marshal(nexmoMessagesRequest)
request, _ := http.NewRequest("POST", "https://api.nexmo.com/v0.1/messages", bytes.NewBuffer(bodyData))
request.Header.Set("Content-Type", "application/json")
request.Header.Set("Accept", "application/json")
request.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(NEXMO_API_KEY+":"+NEXMO_API_SECRET)))
client := &http.Client{}
response, err := client.Do(request)
if err != nil {
return NexmoMessagesResponse{}, err
} else {
data, _ := ioutil.ReadAll(response.Body)
var result NexmoMessagesResponse
json.Unmarshal(data, &result)
return result, nil
}
}
上記の関数は map[string]stringを受け取り NexmoMessagesResponseまたはエラーを返す。関数の最初の部分では、マップからデータを受け取り、JSONにマーシャリングされるオブジェクトを構築する。HTTPリクエストを構築する際には、このオブジェクトがボディとして使用され、さまざまなヘッダーが定義される。
Nexmoでは、JSON Web Token(JWT)を使用するか、APIキーとAPIシークレットを使用することができます。この例では、APIキーとAPIシークレットを使用します。
その SendMessage関数は、ほとんどの仕事をこなしている。
ここではAWS Lambda SDK for Goを使用しており、次のステップとして Handler関数があるので、次のステップは Handler関数の中身を定義します。以下のようになるはずだ:
func Handler(request LambdaRequest) (NexmoMessagesResponse, error) {
return SendMessage(
map[string]string{
"from": "15404161937",
"to": request.Recipient,
"message": request.Platform,
},
)
}当社のAPIにアクセスするクライアントは、プラットフォームと受信者の情報を提供する必要があることを忘れないでください。クライアントが使用しているモバイルプラットフォームと、SMSメッセージの送信先の電話番号を定義する必要があることを忘れないでください。
信じられるなら、AWS Lambda関数は完成している。適切な受信者とプラットフォーム情報をトリガーすると、SMSメッセージが送信され、メッセージのIDが返される。
次に、この関数をAWS Lambdaに取り込み、標準的なHTTPリクエストの一部としてアクセスできるようにする必要がある。
AWS LambdaとAWS API GatewayをスケーラブルなWeb APIとして設定する
AWSポータルに入る前に、Goプロジェクトをビルドしておこう。コマンドラインから、プロジェクトのパスにいる間に以下を実行する:
GOOS=linux go buildAWSは、我々のアプリケーションがLinuxと互換性があることを要求している。幸運なことに、Goにはクロスコンパイルするための正しいツールチェーンがすべて同梱されている。Goでのクロスコンパイルの詳細については、私の以前のチュートリアル 以前のチュートリアルを参照してください。
ラムダ要件の一部として、バイナリはZIP圧縮する必要がある。ファイル名をメモし、ZIPアーカイブのルートに追加する。バイナリのファイル名はハンドラの名前を表します。
次に AWSデベロッパーコンソールにアクセスし、新しいLambda関数を作成する。名前はあまり重要ではなく、Goランタイムを使用していることを確認してほしい。
AWS Developer Console
特定の関数のダッシュボードで、作成したばかりのZIPアーカイブをアップロードすることを選択します。ハンドラ情報の正しいファイル名を指定することを忘れないでください。
また、関数のトリガーとしてAPI Gatewayを追加したい。
AWS Developer Console の API Gateway 部分に入ります。ここで、関数を指すパブリックエンドポイントが作成されます。API Gateway のダッシュボードで メソッドの作成を選択します。 リソースタブを選択します。
Create Method
作成したメソッドはPOSTリクエストとし、リクエスト時にAWS Lambda関数のARN値を参照するようにします。完了したら、新しいメソッドを作成するのと同じメニューからAPIをデプロイするのを忘れないでください。
この時点で、Lambda関数は設定したAPI Gatewayからアクセスできるようになっているはずだ。URLは ステージタブからURLを取得できる。
結論
先ほど、AWS LambdaとGoプログラミング言語を使ってモバイルデバイスにメッセージを送信する方法を見た。要約すると、ユーザーがAPI Gatewayで管理されているAPIにリクエストをした場合、リクエストはAWS Lambdaに流れ、Nexmoに送られ、ユーザーのデバイスに送信される。ユースケースとしては、前述したように、Google PlayであれiTunesであれ、アプリストアのリンクをSMSでユーザーの携帯電話に送信することが考えられる。
この例では検討されていないが、RESTfulなAPIだけでなく、ユーザーが利用できるフロントエンドを作成することで、このプロジェクトに簡単に追加することができる。