Line
DynamoDB
lambda
linebot
LINEmessagingAPI

LINE Messaging API とAWSサービスを連携させてみる~位置情報をDynamoDBに保存する~

概要

GWももう終わりですね。。。GW中に一つでも投稿しようと思っていたので、以前からやりたいなぁと思っていた。
LINE Messaging APIから位置情報を送信してAWSのDynamoDBへの保存を試してみました。
ふとこの場所メモしておきたいなあと思ったときにいろいろな地図アプリはあるけど、便利な反面いまひとつ自由度がない気がしているので、純粋に位置情報の保存だけしてます。
今後はこの位置情報を使っていろんな地図表示ができたらなぁと思っています。

できるようになること

  • LINEのUIを使って位置情報が送信できる
  • 送信した位置情報はLINE bot/AWS Lambda(Python)経由でAWSのDynamoDBに保存される
  • AWSはDynamoDB/Lambda/API Gatewayを使えるようになる
  • 位置情報だけでなくテキストなども送信/保存できる

参考書籍

Amazon Web Services クラウドネイティブ・アプリケーション開発技法 一番大切な知識と技術が身につく

AWSのシステムアーキテクトを中心を説明した本は多いですが、
アプリケーション作成をメインに記載されていた本はこの本くらいだったので購入
基本的なサービス説明からサンプルプログラム/サンプルアプリケーションが豊富なので役立ちました。

およその作業時間

1時間

事前準備

LINEアカウントを作成しLINEのChannleを作ったり、AWSのサービスを使うためにAWSのアカウントを作成する必要があります。Google等で調べればすぐ出てくると思いますが、以下の記事も参考に。
大量データの送信/保存でなければ無料です。

実施手順

1.DynamoDBテーブル作成
2.ロール作成
3.位置情報保存用Lambda関数作成
4.API Gateway公開
5.LINE Channle設定

以降、それぞれについて要点を記載します。
張り付けてある画面は一部のため適宜画面の表示内容に従って操作してください。

1.DynamoDBテーブル作成

最初はDynamoDBにテーブルを作成します。
AWSのサービスからDynamoDBを選び、テーブルの作成をクリック

image.png

テーブル名とプライマリキーが必須のため入力します。
今回は、LINEDatatimestampとしています。
※timestampは、LINEから送られてくるデータでユニークそうなものを選びました。適宜変更してください。
あとはデフォルトのまま、作成をクリック

image.png

2.ロール作成

次にLambda関数に設定するロールを作成します。
サービスから IAM > ロール 選び、ロールの作成をクリック

image.png

ロール名は任意の名称を入力
信頼されたエンティティの種類を選択では、AWSサービスのLambdaを選択
ポリシーにはお試しのためAmazonDynamoDBFullAccessを選択
※正式運用時はベストプラクティスに従い最小権限を設定しましょう(^^;)

image.png

3.位置情報保存用Lambda関数作成

いよいよLambda関数を作成します。
サービスからLambda選び、関数の作成をクリック

image.png

名前は任意の名称を入力
ランタイムは、Python 3.6を選択
ロールは先ほど作成済の既存ロールを選択
最後に関数の作成をクリック

image.png

画面中央くらいにあるコードを書くところに以下のコードを記載
戻り値には入力をそのまま返却するように設定(特に意味はない(^^;))
コードを書いたら右上のボタンで保存します。

image.png

import boto3, json
from datetime import datetime

print('Loading function')      # Functionのロードをログに出力

def lambda_handler(event, context):
    # 文字列へ変換
    jsonstr = json.dumps(event, indent=2)
    print("Received event: " + jsonstr)

    timestamp = event['events'][0]['timestamp']
    print("timestamp: " + str(timestamp))

    dynamoDB = boto3.resource("dynamodb")
    table = dynamoDB.Table("LINEData") # DynamoDBのテーブル名

    # DynamoDBへのPut処理実行
    table.put_item(
      Item = {
        "timestamp": str(timestamp), # Partition Keyのデータ
        "message": jsonstr
      }
    )

    return event

保存したら同じく右上のテストイベントの設定からコードのテストを実行

image.png

テストデータには以下のLINE Messaging APIの疑似送信データを設定


{
  "events": [
    {
      "type": "message",
      "replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
      "source": {
        "userId": "U4af4980629...",
        " type": "user"
      },
      "timestamp": 1462629479859,
      "message": {
        "type": "location",
        "id": "325708",
        "title": "位置情報",
        "address": "Unnamed Road",
        "latitude": 35.65910807942215,
        "longitude": 139.70372892916203
      }
    }
  ]
}

テストデータの詳細は、Messaging API APIリファレンスを参照
 Messaging API APIリファレンス

送信時のイベントオブジェクトは以下
 Webhookイベントオブジェクト

位置情報はこの辺↓ですね
 位置情報

テスト実行後以下のようなメッセージがでれば成功です。

image.png

4.API Gateway公開

サービスからAPI Gatewayを選び、APIの作成をクリック

image.png

API名に任意の名称を設定し、APIの作成をクリック

image.png

作成したAPIにリソース(アクセス時のURLにあたるもの)を追加します。
アクションからリソースの作成選択し、リソース名に任意の名称を設定し、リソースの作成をクリック

image.png

リソースが作成できたらリソースに対し、メソッドを設定します。
作成したリソースを選択した状態で、アクションからメソッドの作成をクリックすると
リソースの下にセレクトボックスが表示されるためPOSTを選択後、
すぐ横の保存(チェックボタンのようなもの)をクリック

image.png

メソッドが作成できたらメソッドに対するセットアップを行います。
作成したLambda関数を設定し、保存をクリック

image.png

保存できたらここでもテストを行いましょう。
テストをクリックし、

image.png

表示されたリクエスト本文に先ほどと同じLINE Messaging APIの疑似送信データを設定し、
テストボタンを押すとテストできます。

image.png

テストが成功したらいよいよデプロイ(公開)です。
アクションからAPIのデプロイをクリック
ステージ名に任意の名称を設定後、デプロイをクリック

image.png

デプロイに成功すれば、画面左側のツリーからステージをクリック後、
該当のリソース/メソッドを選択すると呼び出し用のURLが表示されます。

image.png

試しにアドレスバーにそのまま張り付けると
 message:"Missing Authentication Token"
と、表示されます。わかりにくいですが、POSTメソッドだけの定義のためGETだとこのように返却されるようです(^^;)

5.LINE Channle設定

LINEからAPIにアクセスするため、LINEのChannleに公開されたURLを設定します。
Webhook送信利用するに設定後URLを貼り付けます。

image.png

画面下部に友達追加用のQRコードがあるのでそれで友達追加して位置情報を送ってみます。

image.png

LINEからメッセージを送信する度にDynamoDBのテーブルにレコードが登録されていれば成功です。

image.png

まとめ

送信画面、DB構築に悩まず位置情報が保存できるアプリケーションが短時間で作れるのがすごい。
今後は、この位置情報をこまめに蓄積しいい感じに地図描写ができるアプリケーションを作りたいと思う。