Edited at

LINE Botから送った音声メッセージをClovaで再生する(Node.js)

この投稿はLINEBot&Clova Advent Calendar 2018の7日目の投稿です。


はじめに

LINEの音声メッセージ入力で録音した音声をClovaで非同期に再生できると、

いろいろとコミュニケーションの幅が広がるのではないかと思い、サンプルアプリを作成しました。

LINEが提供しているMessaging APICEKを使用して簡単に実現できたので、その解説を行います。


想定環境と作るもののイメージ

学校がおわり、家でお留守番している子供にがClovaに話しかけると、親があらかじめ録音しておいた伝言を再生します。

グループ化 7.png


構成要素


  • AWS


    • API Gateway

    • Lambda

    • DynamoDB

    • S3(音声メッセージ保存用)



  • Node.js

  • LINE


    • Messaging API SDK

    • CEK(Clova Extensions Kit)




仕組み/システム構成図

グループ化 6.png


  • 音声メッセージ登録処理:


    • Messaging APIのコンテンツを取得するを参考に、音声メッセージをm4aとして取得。

    • 取得した音声メッセージをS3に格納する。

    • DynamoDBにS3のURLをLINE IDと紐づけて格納する。



  • 音声メッセージ取得処理:




サンプルコード

全ソースはこちら(mono0423/dengonkun)をご参照ください。

ポイントとなる部分のみをピックアップします。


LINEBot_音声ファイル取得部分

exports.handler = async (event) {

const body = JSON.parse(event.body);

// 音声ファイルを取得
const audioData = await fetchAudioMessage(body.events[0].message.id);

// S3にpublic-readで音声ファイルを格納する
const paramS3 = {
ACL: 'public-read',
Body: audioData,
Bucket: process.env.AUDIO_BUCKET,
Key: "audio.m4a",
};
await s3.putObject(paramS3).promise();

// DynamoDBにS3のURLをインサートする。
// (省略)
}

// messageIdをもとに、音声ファイルをバイナリで取得する
const fetchAudioMessage = async (messageId) => {
return new Promise((resolve, reject) => {
lineClient.getMessageContent(messageId).then((stream) => {
const content = [];
stream
.on('data', (chunk) => {
content.push(new Buffer(chunk));
})
.on('error', (err) => {
reject(err);
})
.on('end', function() {
resolve(Buffer.concat(content));
});
});
});
}



ClovaSkill側ソース

exports.handler = async (event) => {

const context = new clova.Context(JSON.parse(event.body));
const requestType = context.requestObject.request.type;
const requestHandler = clovaSkillHandler.config.requestHandlers[requestType];

await requestHandler.call(context, context);

return {
statusCode: 200,
body: JSON.stringify(context.responseObject),
};
};

// Clovaスキル実行時の動作を設定
const clovaSkillHandler = clova.Client.configureSkill()
.onLaunchRequest(async (responseHelper) => {
// DynamoからS3のURLを取得し、s3urlに格納(省略)
const s3url = "urlToAudioFileFromDynamoDB";

responseHelper.setSimpleSpeech(
// createSpeechUrlメソッドに音声ファイルへのURLを渡して再生する
clova.SpeechBuilder.createSpeechUrl(s3url),
).endSession();
});



まとめ

Messaging APIとCEKを利用し、非同期な音声メッセージの再生を簡単に実現することができました。

Clovaスキル作成方法の記事もどんどん増えてきているので、みなさんもスキル作成にチャレンジしてみてはいかがでしょうか。


明日の記事は@vui_rieさんの「LINE Clova&BOTと生きた2018年

」です!