この投稿はLINEBot&Clova Advent Calendar 2018の 7 日目の投稿です。
はじめに
LINE の音声メッセージ入力で録音した音声を Clova で非同期に再生できると、
いろいろとコミュニケーションの幅が広がるのではないかと思い、サンプルアプリを作成しました。
LINE が提供しているMessaging APIとCEKを使用して簡単に実現できたので、その解説を行います。
想定環境と作るもののイメージ
学校がおわり、家でお留守番している子供にが Clova に話しかけると、親があらかじめ録音しておいた伝言を再生します。
構成要素
- AWS
- API Gateway
- Lambda
- DynamoDB
- S3(音声メッセージ保存用)
- Node.js
- LINE
- Messaging API SDK
- CEK(Clova Extensions Kit)
仕組み/システム構成図
- 音声メッセージ登録処理:
- Messaging API のコンテンツを取得するを参考に、音声メッセージを m4a として取得。
- 取得した音声メッセージを S3 に格納する。
- DynamoDB に S3 の URL を LINE ID と紐づけて格納する。
- 音声メッセージ取得処理:
- LINE ID をもとに、DynamoDB から S3 に格納されている音声メッセージファイルの URL を取得。
- CEK のオーディオコンテンツの再生を指示するを参考に、音声を再生する。
サンプルコード
全ソースはこちら(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年
」です!