Edited at

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」を選択します。




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


  • 「API」で「新規APIの作成」を選択

  • 「セキュリティ」で「オープン」を選択

  • 「追加」ボタンをおす

※Lambda上ではなくAPI Gateway上からですとより詳細な設定が行えます。

 特にLambda上ではメソッドがANYに固定されてしまいますが、ここをPOSTのみにもできます。

 (@zono_0 さんのコメントより)





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





  • 画面下側が更新されるので「詳細」を開く

  • 「URLの呼び出し」のURLをコピー





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




以上で公式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 で作ったカスタムスキルを色んなサーバーにデプロイしてみる

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