Help us understand the problem. What is going on with this article?

LINE Messaging API 〜 API Gateway 〜 SQS 〜 Lambda を連携する

前書き

  • LINEのchatbot基盤を作ります
  • LINE Messaging APIとAWSの各種マネージドサービスとの連携方法についてまとめます
  • セキュリティ設定については別記事にまとめます(一旦ゆるゆるに設定)
  • Lambdaで使用する言語はGoを採用します

構成

architecture-3.png

作成するchatbotの流れは以下の通りです。最終的には送信したメッセージをDynamoDBに保存してLINE Messaging APIを呼び出しますが、本記事では対象外とします。

  1. LINE公式アカウントを友達登録する
  2. 公式アカウントにメッセージを送る
  3. LINE ServerからAPI Gatewayにリクエストが送信される(webhook URL)
  4. API GatewayはSQSにメッセージを保存して、LINE Serverにレスポンスを返す
  5. 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'を入力
  • 作成した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として保存する
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を選び、追加ボタンを押す
  • サンプルコードをアップロードする。
    • 「関数コード」の「関数パッケージ」の「アップロード」ボタンを押して、作成した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をコールしてユーザーに対してメッセージを送り返すなど、実際のアプリケーション要件に沿って実装するためのベースは一応構築できたのかなと思います。

参考

LINE Messaging API 公式ドキュメント
AWS公式ドキュメント - Lambdaのgoサンプルコード

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした