4. Amazon AlexaからHerokuのRailsにつなぐ


連載記事

前後関係があるため順番に読んでもらえると分かりやすくなっています。

1. Amazon AlexaとFire TVでHello Worldを試してみる - Qiita
2. Amazon Alexaで音声から引数を受け取る - Qiita
3. Amazon AlexaのCustom Slot Typesを設定する - Qiita
4. Amazon AlexaからHerokuのRailsにつなぐ - Qiita
5. Amazon Alexaで会話を続ける(セッションを引き継ぐ) - Qiita
6. Amazon Alexa のスキルを日本語化する - Qiita
7. 自作した日本語のAlexa SkillをEcho dotで動かす - Qiita

はじめに

今までの記事では「FireTV <=> Alexa <=> Lambda」のサーバーレスという構成で作ってきました。
普段はRuby on Railsで開発しているため、今回はLambdaの所をHeroku + Ruby on Railsに切り替える方法を試してみます。
構成は下記のような「FireTV <=> Alexa <=> Heroku(Ruby on Rails)」です。

この構成で前回までに作ったHello worldの簡単なサンプルを実装します。

Amazon AlexaのCustom Slot Typesを設定する - Qiita

Rails側のルーティング

FireTVで受け取った音声はAlexaを経由してPOSTで送られます。
そこでルーティングは下記の様にしました。

POST    /talks  talks#create
#config/routes.rb
Rails.application.routes.draw do
  resources :talks, only: %i(create)
end

#app/controllers/tasks_controller.rb
class TalksController < ApplicationController
  protect_from_forgery with: :null_session

  # POST /talks
  def create
    Rails.logger.info params
  end
end

これでAlexaから送られるデータを受け取れるようになります。
このプログラムをHerokuに上げておきましょう。

Alexa側のEndpointを変更

次にAlexaのEndpointをLambdaからHerokuに変更します。

Configurationの項目のEndpointをHTTPSに変更します。
Defaultの所にHerokuで受け取り可能なURLを設定します。
今回の例だと https://xxx.herokuapp.com/talksとします。

SSL Certificateの項目のCertificate for DEFAULT Endpointを「My development endpoint is a sub-domain〜」に変更します。
Alexa側の設定は以上です。

HerokuでAlexaからのPOSTを確認

AlexaからPOSTされるパラメーターをHerokuで確認してみましょう。
Alexaからのアクセスが確認できない場合にはSSL CertificateやEndpointの設定が正しくない可能性があります。

#access.log
# ログは一部加工しています。
Oct 2 21:04:42 app[web] INFO I, [2017-10-02T12:04:42.871451 #6]  INFO -- : Started POST "/talks" for xxx.xxx.xxx.xxx at 2017-10-02 12:04:42 +0000
Oct 2 21:04:42 app[web] INFO I, [2017-10-02T12:04:42.872727 #6]  INFO -- : Processing by TalksController#create as JSON
Oct 2 21:04:42 app[web] INFO I, [2017-10-02T12:04:42.872906 #6]  INFO -- : Parameters: {"version"=>"1.0"...

Railsでレスポンスを返す

Railsはalexa-rubykitというgemを入れて処理します。

damianFC/alexa-rubykit: Amazon Echo Alexa's App Kit Ruby Implementation

gem 'alexa_rubykit'

後はコントローラーで受け取ったリクエストから名前を取り出してレスポンスで返してあげれば完成です。
FireTVに向けて話しかけると正しい音声が返ってくるはずです。

自分「tell Hello world hello my name is Tarou.」
FireTV「Hello world! Tarou.」

#app/controllers/talks_controller.rb
class TalksController < ApplicationController
  protect_from_forgery with: :null_session

  # POST /talks
  def create
    request = AlexaRubykit::build_request(params)
    response = AlexaRubykit::Response.new
    response.add_speech("Hello world! #{request.slots[:firstName][:value]}")
    render json: response.build_response
  end
end

まとめ

これで既存のサービスが稼働している場合でもAlexaと連携することができるようになったのでより柔軟な開発ができる。

Let's enjoy Alexa.