LINE Botに送信された音声をAmazon S3に保存する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、中村です。
今回はLINE Botに送信された音声データを、Amazon S3に保存してみます。

はじめに

今回の機能を実現させるには、下記のような流れになります。

  1. LINE開発者コンソールで、チャンネルを作成。
  2. 保存用のS3バケットを作成。
  3. Lambdaにソースデプロイ・IAMロールを作成。
  4. API Gatewayを設定。
  5. テスト

今回は、2.3について説明します。
その他設定については、こちらを参考にしてみてください。

LambdaではじめてのLINE Botを作る

S3バケットを作成

S3にアクセスし、"バケットを作成する"をクリック。

バケット名を入力し、リージョンを指定(既存のバケットと設定が同じでいい場合は選択)

プロパティを指定(今回は、特に設定なしで構いません)

アクセス許可の設定は、作業ユーザーのみを追加しパブリックアクセス禁止。

設定を確認し、問題なければ"バケットを作成"をクリック。

Lambdaにソースデプロイ・IAMロール作成

ソースをデプロイ

注意点

  • LINEからの接続確認の場合、処理をせずステータスコード: 200を返します。
  • わかりやすいように、メッセージタイプが音声かそうでないかでメッセージを切り分けています。
'use strict';
var channelAccessToken = process.env.CHANNEL_ACCESS_TOKEN;

const C = require('./const');
const MESSAGE = require('./message');
const AWS = require('aws-sdk');
const LINE = require('@line/bot-sdk');
const S3 = new AWS.S3({region: 'us-east-1'});
const LINE_CLIENT = new LINE.Client({channelAccessToken: channelAccessToken});

const makeParams = async function(messageId) {
    return new Promise((resolve, reject) => {
        LINE_CLIENT.getMessageContent(messageId).then((stream) => {
            var content = [];
            stream.on('data', (chunk) => {
                console.log('data');
                console.log(chunk);
                content.push(new Buffer(chunk));
            }).on('error', (err) => {
                reject(err);
            }).on('end', function(){
                console.log('end');
                console.log(content);
                resolve(Buffer.concat(content));
            });
        });
    });
};

exports.handler = async function(event) {
    console.log(JSON.stringify(event));
    let response = { statusCode: 200 };
    let body = JSON.parse(event.body);
    if (body.events[0].source.userId == C.TEST_CONNECTION_USERID) {
        console.log(MESSAGE.TEST_CONNECTION);
        return response;
    } else {
        var replyMessage = [];
        if (body.events[0].message.type == 'audio') {
            var params = {
                Body: await makeParams(body.events[0].message.id),
                Bucket: C.BUCKET_NAME,
                Key: body.events[0].message.id + '.m4a',
            };
            await S3.putObject(params, function(err, data) {
                if (err) console.log(err);
                else console.log(data);
            });
            replyMessage.push({ 'type': 'text', 'text': MESSAGE.AUDIO_UPLOAD });
        } else {
            replyMessage.push({ 'type': 'text', 'text': MESSAGE.AUDIO_ONLY });
        }
        await LINE_CLIENT.replyMessage(body.events[0].replyToken, replyMessage);
    } 
    return response;
};

IAMロールの作成

IAMにアクセスし、ポリシーを作成。
今回は、S3へ書き込みができる権限を付加。

確認して問題がなければ、"Create policy"をクリックしてポリシーを作成。

IAMのロールから、Lambda作成時のロールを開く。
"ポリシーのアタッチ"をクリックし、先ほど作成したポリシーを選択

"ポリシーのアタッチ"をクリックすると、選択したポリシーが追加されるのを確認。

テスト

実際にテストしてみましょう。

LINEに"S3にアップロードしました"が表示されます。この時S3には音声ファイルが生成されています。

まとめ

いかがでしたでしょうか。
音声が取得できるので、LexやTranscribeなどのサービスと連携も今後やって行きたいと思います。