Help us understand the problem. What is going on with this article?

Clova公式SDK(Node.js)のAWS、Firebaseでの動かし方

More than 1 year has passed since last update.

はじめに

前回の記事(Clova公式SDK(Node.js)の使い方まとめ)にて公式SDKの使い方を説明して、サーバでの動かし方も追記しますと書いたものの、ボリュームが大きかったので記事を分割しました。

AWS(Lombda)とFirebase(Functions)での動かし方をそれぞれ説明していきます。
どちらも公式SDKのサンプルにあるようなexpressで動かすコードの最後に2~3行追加するだけでおっけーです。

AWS(Lambda)で動かしてみる

aws-serverless-expressを使う

公式SDKのサンプルではexpressで動かされており、できるだけソースをいじらずLambdaで動かせないかなと調べてみたところ、「aws-serverless-express」というのがありました。

まずはnpmインストール。

$ npm i aws-serverless-express

そして以下のようにちょこっといじるだけでexpressがLambdaで動きます。
なおapp.post()の第一引数を作成したLambda関数名にしておく必要があります。

// 公式サンプルの最後の方
...

const app = new express();
const clovaMiddleware = clova.Middleware({ applicationId: "YOUR_APPLICATION_ID" });
// Use `clovaMiddleware` if you want to verify signature and applicationId.
// Please note `applicationId` is required when using this middleware.
app.post('/clova', clovaMiddleware, clovaSkillHandler);

// Or you can simply use `bodyParser.json()` to accept any request without verifying, e.g.,
app.post('/clova', bodyParser.json(), clovaSkillHandler);

// 以下の3行を追加するだけ!
const awsServerlessExpress = require('aws-serverless-express');
const server = awsServerlessExpress.createServer(app);
exports.handler = (event, context) => awsServerlessExpress.proxy(server, event, context);

あとはソースをnode_modulesごとzipに固めてLambdaにアップロードすればおっけーです。

Lambda関数の作り方(Alexaスキル作成時との差異)

Alexaの場合はトリガーに「Alexa Skill Kit」を選択しますが、Clovaの場合はちろんそれは使えません。
じゃあどうするのかというと「トリガーの追加」から「API Gateway」を選択します。

image

API Gateway選択後の操作を箇条書きしていきます。

  • 「API」で「新規APIの作成」を選択
  • 「セキュリティ」で「オープン」を選択
  • 「追加」ボタンをおす

※Lambda上ではなくAPI Gateway上からですとより詳細な設定が行えます。
 特にLambda上ではメソッドがANYに固定されてしまいますが、ここをPOSTのみにもできます。
 (@zono_0 さんのコメントより)

image

  • 画面右上の「保存」ボタンをおす

image

  • 画面下側が更新されるので「詳細」を開く
  • 「URLの呼び出し」のURLをコピー

image

  • Clova Developer Centerの「サーバ設定」より「ExtensionサーバーのURL」に貼り付けて保存

image

以上で公式SDKをLambdaで動かせます!

Firebase(Functions)で動かしてみる

Firebase Functionsはデフォルトでexpressを動かせます
ただコードの注意点としてはエンドポイントとなるURLの最後のパスをexportsで指定します。
そのため、app.post()の第一引数は'/'としておく必要があります。
↓のコードの例ですとhttps://xxx.xxx.xxx/clova/clovaexports.clovaで指定しています。
あと、Clova Developer Centerの「サーバ設定」にURLを貼るときはURLの最後に/を忘れずにつけて下さい。

// 公式サンプルの最後の方
...

const app = new express();
const clovaMiddleware = clova.Middleware({ applicationId: "YOUR_APPLICATION_ID" });
// Use `clovaMiddleware` if you want to verify signature and applicationId.
// Please note `applicationId` is required when using this middleware.
// app.post('/clova', clovaMiddleware, clovaSkillHandler);
app.post('/', clovaMiddleware, clovaSkillHandler);

// Or you can simply use `bodyParser.json()` to accept any request without verifying, e.g.,
// app.post('/clova', bodyParser.json(), clovaSkillHandler);
app.post('/', bodyParser.json(), clovaSkillHandler);

// 以下の2行を追加する!
const functions = require('firebase-functions');
exports.clova = functions.https.onRequest(app);

これで動く!!
…が、

Firebaes FunctionsではES2016/ES2017が使えない

Firebase Functionsは現状Node.jsのバージョンが6となるためES2016/ES2017の構文(async/awaitとか)は使えません。
ES2015で書くか、Babelなりでトランスパイルの必要があります。

公式SDK内でES2017の記述がある?

getSlots()を使ったら以下のエラーが出ました。

Object.values is not a function 

Object.valuesはES2017の機能なので、Firebase Functionsでは動きません。
公式SDKはTypeScriptで書かれており、ES2015形式へのトランスパイルが行われているはずですが、そこでなんかおかしな事が起きてるのかな?(TypeScriptよくわかんない><)

Firebaseは無料プランでおっけー

Firebaseは無料プランでは外部APIを叩けません。
じゃあClovaで使って大丈夫なの?と思いましたが、あくまでhttpリクエストを送って投げ返してるだけなので、ソース上で外部API叩いてなければ大丈夫です。

ForkされたSDKを使う

@chibi929 さんが公式SDKをForkしてLambda、Firebaseで簡単に使えるよう拡張してくれています。
chibi929/clova-cek-sdk-nodejs

使い方はこちらの記事に。
Clova SDK で作ったカスタムスキルを色んなサーバーにデプロイしてみる

御本人に本家にプルリクしてもらうようお願いしたので、こちらがマージされたら更に使いやすくなりますね。

miso_develop
Google Homeの購入を機にITに目覚めた初心者非エンジニアです!分からないことがあったら相談したり一緒に考えたりしたいので是非ともフォローお願いします!
iotlt
IoT縛りの勉強会です。 毎月イベントを実施しているので是非遊びに来てください! 登壇者を中心にQiitaでも情報発信していきます。 https://iotlt.connpass.com
https://iotlt.connpass.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away