前書き
- LINEのchatbot基盤を作ります
- LINE Messaging APIとAWSの各種マネージドサービスとの連携方法についてまとめます
- セキュリティ設定については別記事にまとめます(一旦ゆるゆるに設定)
- Lambdaで使用する言語はGoを採用します
構成
作成するchatbotの流れは以下の通りです。最終的には送信したメッセージをDynamoDBに保存してLINE Messaging APIを呼び出しますが、本記事では対象外とします。
- LINE公式アカウントを友達登録する
- 公式アカウントにメッセージを送る
- LINE ServerからAPI Gatewayにリクエストが送信される(webhook URL)
- API GatewayはSQSにメッセージを保存して、LINE Serverにレスポンスを返す
- SQSにメッセージが保存されたタイミングでLambdaが起動する
環境
Name | Version |
---|---|
Go | 1.12.1 |
LINE chatbotの設定
- 必要な登録を行い、LINE developer console にアクセスする。
-
Provider
を作成する(Provider
とはアプリケーションを管理する組織のこと)。 -
Channel
を作成する。Channel TypeはMessaging APIを選択する。
SQSの作成
- 新しいキューを作成する。
- 「キュー名」は
line-message
を入力 - 「キューの種類」は
標準キュー
を選ぶ
- 「キュー名」は
- 「アクセス許可」タブを選択する。
-
アクセス許可の追加
ボタンを押す - 「効果」は
許可
を選ぶ - 「プリンシパル」は
全員(*)
にチェックを付ける - 「アクション」は
すべてのSQSアクション(SQS:*)
にチェックを付ける
-
API Gateway用のIAMロールの作成
- 新しいIAMロールを作成する。
- 「エンティティの種類」は
AWSサービス
を選ぶ - 「使用するサービス」は
API Gateway
を選ぶ - 「ポリシー」と「タグ」設定は飛ばす
- 「ロール名」は
APIGatewayTestRole
と入力
- 「エンティティの種類」は
-
ポリシーをアタッチします
ボタンを押す- 「ポリシーのフィルタ」で
AmazonSQSFullAccess
を検索して、アタッチする
- 「ポリシーのフィルタ」で
API Gatewayの作成
- 新しいAPI Gatewayを作成する。
-
REST API
を選ぶ - 「API名」は任意の名前を入力(今回は
TestAPI
とする) - 「エンドポイントタイプ」は
リージョン
を選ぶ
-
-
linemessage
という名前の新しいリソースを作成する。 - 作成した
linemessage
リソースにPOSTメソッドを追加する。- 「統合タイプ」は
AWSサービス
を選ぶ - 「AWSリージョン」は使用中のエリアを選ぶ
- 「AWSサービス」は
Simple Queue Service(SQS)
を選ぶ - 「HTTPメソッド」は
POST
を選ぶ - 「アクションの種類」は
パス上書きの使用
を選ぶ - 「パス上書き (省略可能)」は作成したSQSのURLのうち
{account_id}/line-message
を入力 - 「実行ロール」は作成したIAMロールのARNを入力
- 「統合タイプ」は
- 作成したPOSTメソッドの「統合リクエスト」をクリックする
- 「HTTP ヘッダー」から
ヘッダーの追加
ボタンを押す - 「名前」は
Content-Type
を入力 - 「マッピング元」は
'application/x-www-form-urlencoded'
を入力
- 「HTTP ヘッダー」から
- 作成したPOSTメソッドの「マッピングテンプレート」をクリックする
- 「リクエスト本文のパススルー」は
テンプレートが定義されていない場合 (推奨)
を選ぶ -
マッピングテンプレートの追加
リンクを押してapplication/json
を入力 - 下のコード入力欄に
Action=SendMessage&MessageBody=$util.urlEncode($input.body)
を入力して保存
- 「リクエスト本文のパススルー」は
- 作成したPOSTメソッドのアクションから
APIのデプロイ
を押す- 「デプロイされるステージ」は
[新しいステージ]
を選ぶ - 「ステージ名*」は
prod
を入力して、デプロイ
ボタンを押す
- 「デプロイされるステージ」は
LINE Messaging API の webhook設定
- API GatewayのURLを確認する
- 先ほど作成したAPI Gatewayの「ステージ」を押す
- 「prod」の左側にある矢印をクリックして展開して、「POST」を押す
- 右側の「URL の呼び出し:」にURLが表示されるのでコピーしておく(形式:
https://{api_id}.execute-api.{region_name}.amazonaws.com/prod/linemessage
)
- 最初に作成したLINE chatbotのchannelの設定画面を開く
-
Messaging API
タブを開く - 「Webhook URL」にコピーしたURLを入力して、
Verify
ボタンを押す
以上でLINEからメッセージを送るとSQSにキューイングされるところまでが完成したので、一度動作チェックしてみるとよいと思います。次はLambdaを作成してSQSにメッセージが入ってきたら自動的に動くように連携します。
Lambda実行ファイルの用意
- Lambdaの公式ドキュメントにあるgoのサンプルコードを
main.go
として保存する
package main
import (
"context"
"fmt"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
func handler(ctx context.Context, sqsEvent events.SQSEvent) error {
for _, message := range sqsEvent.Records {
fmt.Printf("The message %s for event source %s = %s \n", message.MessageId, message.EventSource, message.Body)
}
return nil
}
func main() {
lambda.Start(handler)
}
-
GOOS=linux GOARCH=amd64 go build -o main
コマンドでビルドする - ビルドした実行ファイル
main
をzip圧縮する
Lambda用のIAMロールの作成
- 新しいIAMロールを作成する。
- 「エンティティの種類」は
AWSサービス
を選ぶ - 「使用するサービス」は
Lambda
を選ぶ - 「ポリシー」は
AdministratorAccess
を選ぶ - 「タグ」設定は飛ばす
- 「ロール名」は
LambdaLineMessageTestRole
と入力
- 「エンティティの種類」は
Lambdaの作成
- 新しいLambdaを作成する。
-
一から作成
を選ぶ - 「関数名」は
testLineMessage
を入力 - 「ランタイム」は
Go 1.x
を選ぶ - 「実行ロールの選択または作成」の矢印を押して展開する
- 「実行ロール」は
既存のロールを使用する
を選ぶ - 「既存のロール」は先ほど作成した
LambdaLineMessageTestRole
を選ぶ
-
- SQSと連携する。
- 「Designer」の
トリガーを追加
ボタンを押す - トリガーの種類は
SQS
を選ぶ - 「SQSキュー」は作成した
line-message
を選び、追加
ボタンを押す
- 「Designer」の
- サンプルコードをアップロードする。
- 「関数コード」の「関数パッケージ」の「アップロード」ボタンを押して、作成した
main.zip
を選び、右上の「保存」ボタンを押す
- 「関数コード」の「関数パッケージ」の「アップロード」ボタンを押して、作成した
以上でSQSにメッセージが入ったタイミングでLambdaが動くようになりました。試しにLINEでメッセージを送ってみるとSQSにキューイング、即座にLambdaが起動したことがCloud Watchで確認できると思います。(Lambdaのモニタリングタブを開いて、一番下のCloudWatch Logs Insights
をみると簡単に確認できます)
あとがき
本記事の内容は以上になりますが、もちろん本番運用させるには他にも考慮しなくてはいけない点は沢山あると思います。ざっと記載すると、
- セキュリティの考慮
- API GatewayのAKIキー設定(LINE Messaging APIで生成)
- API Gatewayのリソースポリシー設定
- API GatewayのprodステージのWAF設定
- API Gatewayの適切なロール設定
- Lambdaの適切なロール設定
- SQSキューの種類選定(標準キューでよいのか?)
- SQSエラーキュー発生時の考慮(再処理ポリシー含む)
- Lambdaの同時実行数の設定
- Lambda実装時の冪等性の考慮(標準キュー使用時)
といったところでしょうか。しかし、LambdaでSQSから取得したメッセージをパースしてデータベース保存、LINE Messaging APIをコールしてユーザーに対してメッセージを送り返すなど、実際のアプリケーション要件に沿って実装するためのベースは一応構築できたのかなと思います。