0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【AWS Lambda×LINE Messaging API】翻訳アプリを作ろう

Last updated at Posted at 2021-06-26

はじめに

皆さん、Lambdaをご存知でしょうか?
Lambdaはサーバーレスアーキテクチャを実現する上で根幹となるサービスです。

サーバーレスアーキテクチャとは

AWSにおけるサーバーレスとは、**「インスタンスベースの仮想サーバー(EC2など)を使わずにアプリケーションを開発するアーキテクチャ」**を指します。

一般にシステムの運用には、プログラムを動かすためのサーバーが必要です。
そしてそのサーバーは、常に稼働していなければなりません。

しかし開発者がやりたいことは、「サーバーの管理」なのでしょうか?
エンドユーザーに価値を届けることこそが使命なわけです。

ということで、こういうめんどくさい作業から解放してくれるのがサーバーレスアーキテクチャなわけです。

サーバーレスアーキテクチャでよく使われるサービスは以下の通りです。
特に、丸で囲っている3つがよく使われます。

スクリーンショット 2021-06-26 15.43.25.png

ということで、この3つ全てを使った翻訳アプリを作りたいと思います。

アーキテクチャ

以下の2つの条件を満たしたら成功です。

①LINEで「こんにちは」と入力したら、「Hello」と返ってくる
②タイムスタンプと「こんにちは」、「Hello」がDBに保存される

arch.png

ハンズオン

前提

初めてAWSを使う方に対しての注意です。
ルートユーザーで行うのはよろしくないので、全ての権限を与えたAdministratorユーザーを作っておいてください。

公式サイトはこちらです。

文章は辛いよって方は、初学者のハンズオン動画があるのでこちらからどうぞ。

また、LINE Developersのアカウントも必要となります。
LINE関連の記事を書いているのでこちらから確認してください。
チャネルシークレットチャネルアクセストークンが発行できればOKです。

Lambdaで使うコードを作る

LINE Messaging API SDK for nodejsに書いていることをやっていきます。

package.jsonの作成

ターミナル
$ npm init -y

パッケージのインストール

ターミナル
$ npm install @line/bot-sdk aws-sdk --save

翻訳部分を作る

今回は、翻訳する部分、DBにデータを登録する部分と様々な機能があるため動作ごとにファイルを切り分けてあげましょう。
以下のように作っていきます。

.
├── api/
│   ├── Common/
│   │        └── getTranslate.js
│   │        └── putDynamoDB.js
│   └── index.js

まずは、index.jsが作っていきます。

index.js
'use strict';

// パッケージのインストール
const line = require('@line/bot-sdk');

// LINEアクセストークンの設定
const config = {
  channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN,
  channelSecret: process.env.CHANNEL_SECRET,
};

// インスタンス化
const client = new line.Client(config);

// モジュールのインストール
const translate = require('./Common/getTranslate');

exports.handler = async (event, context) => {
  // JSONとして解析して値やオブジェクトを構築する
  const body = JSON.parse(event.body);

  // LINE Eventを取得
  const response = body.events[0];

  // 翻訳を行うために必要な情報
  const input_text = response.message.text;
  const sourceLang = 'ja';
  const targetLang = 'en';

  // 翻訳(関数呼び出し)
  const res = await translate.getTranslate(input_text, sourceLang, targetLang);
  const output_text = res.TranslatedText;

  // メッセージ送信のために必要な情報
  const replyToken = response.replyToken;
  const post = {
    type: 'text',
    text: output_text,
  };

  try {
    // メッセージの送信
    await client.replyMessage(replyToken, post);
  } catch (err) {
    console.log(err);
  }
};

では次に、getTranslate.jsを作っていきましょう。
コードだけ書いても訳がわからないと思うので、リファレンスを見ましょう。

入力されたテキストをソース言語からターゲット言語に変換する、translateTextを使います。
必須項目は以下の3つで、SourceLanguageCodeに元の言語コード、TargetLanguageCodeに変換先の言語コード、Textに変換するテキストを入れればいいことがわかります。

SourceLanguageCode: 'STRING_VALUE', /* required */
TargetLanguageCode: 'STRING_VALUE', /* required */
Text: 'STRING_VALUE', /* required */

そのあとはこのデータを実行するだけです。

translate.translateText(params, function(err, data) {
  if (err) console.log(err, err.stack); // an error occurred
  else     console.log(data);           // successful response
});

APIが理解できたところで進めていきましょう。

Common/getTranslate.js
// パッケージのインストール
const AWS = require('aws-sdk');

// 必要なAWSサービス
const translate = new AWS.Translate();

exports.getTranslate = (input, inLang, outLang) => {
  return new Promise((resolve, reject) => {
    // 必要なデータ
    const params = {
      Text: input,
      SourceLanguageCode: inLang,
      TargetLanguageCode: outLang,
    };

    // 翻訳を行う
    translate.translateText(params, (err, data) => {
      if (err) {
        console.log(err);
        reject();
      } else {
        resolve(data);
      }
    });
  });
};

Lambdaを作成する

Lambdaとコンソールで検索してください。

スクリーンショット 2021-06-26 18.10.34.png

「関数の作成」をクリック

スクリーンショット 2021-06-26 18.11.47.png

設定を見ていきましょう!

スクリーンショット 2021-06-26 21.21.51.png

作成完了しました!

スクリーンショット 2021-06-26 21.23.50.png

では、先ほど作成したコードをLambdaで使えるようにしましょう。
方法は2つあります。
・S3経由
・zip経由

zipの方が簡単なので今回はzipにします。
今回ファイルサイズだいぶ限界になるので10MBオーバーしたときはS3にアップロードしてください。
ちなみにaws-sdkをインストールしましたが、Lambdaに標準装備しているパッケージなのでこちらをアンストして容量下げてもらっても構いません。

node_moduleCommonディレクトリindex.jsの3つをzipにしてください。
命名は適当でいいです。

スクリーンショット 2021-06-26 21.27.22.png

ではアップロードしましょう。

スクリーンショット 2021-06-26 21.27.58.png

では次に環境変数の設定を行います。
先ほどLINEで取得した値をこちらで入力します。

スクリーンショット 2021-06-26 18.22.16.png

では最後に、実行ロールにAWS Translateの権限を付与しましょう。

スクリーンショット 2021-06-26 21.32.49.png

ポリシーをアタッチさせましょう。

スクリーンショット 2021-06-26 21.33.58.png

スクリーンショット 2021-06-26 21.34.51.png

これでアタッチできました。

一旦Lambdaは完了です。

API Gatewayの設定

API Gatewayとコンソールで検索してください。

APIタイプはREST APIで作成します。

スクリーンショット 2021-06-26 18.24.51.png

API名は適当でいいです。

スクリーンショット 2021-06-26 21.35.59.png

メソッドの作成をしましょう。

スクリーンショット 2021-06-26 18.27.26.png

POSTを選択して決定。

スクリーンショット 2021-06-26 18.28.04.png

セットアップを行う。

スクリーンショット 2021-06-26 21.37.57.png

CORSの設定を行います。

スクリーンショット 2021-06-26 18.31.10.png

デフォルトのままでOK

スクリーンショット 2021-06-26 18.31.40.png

最後にデプロイしましょう!

スクリーンショット 2021-06-26 18.32.59.png

ステージ名も適当でいいです。

スクリーンショット 2021-06-26 18.33.29.png

このようにURLが発行されます。

スクリーンショット 2021-06-26 18.34.21.png

ではこのURLをLINEの方に入力しましょう。

完了したらテストです。
結果を見てみましょう。

iOS の画像 (1).png

うまくいってますね!

Lambdaで使うコードを作る

DBにデータを登録する機能を作る

.
├── api/
│   ├── Common/
│   │        └── getTranslate.js
│   │        └── putDynamoDB.js
│   └── index.js

最初に、index.jsから作っていきます

index.js
'use strict';

// パッケージのインストール
const line = require('@line/bot-sdk');

// LINEアクセストークンの設定
const config = {
  channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN,
  channelSecret: process.env.CHANNEL_SECRET,
};

// インスタンス化
const client = new line.Client(config);

// モジュールのインストール
const translate = require('./Common/getTranslate');
const dynamodb = require('./Common/putDynamoDB');

exports.handler = async (event, context) => {
  // JSONとして解析して値やオブジェクトを構築する
  const body = JSON.parse(event.body);

  // LINE Eventを取得
  const response = body.events[0];

  // 翻訳を行う
  const input_text = response.message.text;
  const sourceLang = 'ja';
  const targetLang = 'en';

  // 翻訳(関数呼び出し)
  const res = await translate.getTranslate(input_text, sourceLang, targetLang);
  const output_text = res.TranslatedText;

  // メッセージ送信のために必要な情報
  const replyToken = response.replyToken;
  const post = {
    type: 'text',
    text: output_text,
  };

  // DB-タイムスタンプ
  const date = new Date();
  const Y = date.getFullYear();
  const M = ('00' + (date.getMonth() + 1)).slice(-2);
  const D = ('00' + date.getDate()).slice(-2);
  const h = ('00' + (date.getHours() + 9)).slice(-2);
  const m = ('00' + date.getMinutes()).slice(-2);
  const s = ('00' + date.getSeconds()).slice(-2);
  const dayTime = Y + M + D + h + m + s;

  try {
    // メッセージの送信
    await client.replyMessage(replyToken, post);
    // DB保存(関数呼び出し)
    await dynamodb.putDynamoDB(dayTime, input_text, output_text);
  } catch (err) {
    console.log(err);
  }
};

次に、putDynamoDB.jsを作ります。
コードだけ書いても訳がわからないと思うので、リファレンスを見ましょう。

アイテム(レコード)を作成したいので、putItemを使います。
必須項目は以下の3つで、Itemにデータ、ReturnConsumedCapacityに集計、TableNameにテーブルの名前を入れればいいことがわかります。

var params = {
  Item: {
   "AlbumTitle": {
     S: "Somewhat Famous"
    }, 
   "Artist": {
     S: "No One You Know"
    }, 
   "SongTitle": {
     S: "Call Me Today"
    }
  }, 
  ReturnConsumedCapacity: "TOTAL", 
  TableName: "Music"
 };

そのあとはこのデータを実行するだけです。

 dynamodb.putItem(params, function(err, data) {
   if (err) console.log(err, err.stack); // an error occurred
   else     console.log(data);           // successful response
 });

APIが理解できたところで進めていきましょう。

Common/putDynamoDB.js
// パッケージのインストール
const AWS = require('aws-sdk');

// 必要なAWSサービス
const dynamodb = new AWS.DynamoDB();

exports.putDynamoDB = (dayTime, input, output) => {
  return new Promise((resolve, reject) => {
    const params = {
      Item: {
        timestamp: {
          S: dayTime,
        },
        input_text: {
          S: input,
        },
        output_text: {
          S: output,
        },
      },
      ReturnConsumedCapacity: 'TOTAL',
      TableName: 'translations_history',
    };

    dynamodb.putItem(params, (err, data) => {
      if (err) {
        console.log(err);
        reject();
      } else {
        resolve();
      }
    });
  });
};

では最後に、実行ロールにAWS DynamoDBの権限を付与しましょう。

スクリーンショット 2021-06-26 21.32.49.png

ポリシーをアタッチさせましょう。

スクリーンショット 2021-06-26 21.33.58.png

スクリーンショット 2021-06-26 21.54.15.png

これでアタッチできました。

DynamoDBを作成する

スクリーンショット 2021-06-26 21.57.58.png

設定はこのようにします。

スクリーンショット 2021-06-26 21.58.59.png

これで完了です。

最後に正しく動作するか確認していきましょう。

翻訳は正しくできていますね!

iOS の画像 (2).png

では次に、DBにデータが保存されているか確認しましょう。

スクリーンショット 2021-06-26 22.08.15.png

保存されてますね!
時刻も問題なく反映されています。

これで全て終了です。

最後に

少し難しかった等あれば、DynamoDBを使わないただのおうむ返しアプリなども作っているのでこちらも参考にされてください。

次は以前作成した天気予報アプリなどをLambdaでデプロイしていきます。

最後まで読んでいただきありがとうございます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?