こんにちは、吉岡([twitter:@yoshiokatsuneo])です。
皆さんは、スマートスピーカーを使っていますか?
私は最近、Amazon Echoで「アレクサ(Alexa)」を使い始めました。最初は 「正直そんなに必要ないのでは?」 という気持ちもあったのですが、実際に使い始めると、なかなか便利で手放せなくなってしまいました。
携帯電話を取り出す必要もなく、誰でも、どこからでも、声だけで使える というのは利便性が高いですね。最近の機械学習・AI技術の進歩もあり、認識精度もいよいよ実用的になってきたなと感じます。
ある調査によると、アメリカでは成人の18%がスマートスピーカーを保有しており、さらに保有者の 65%は「手放せない」と言っている…という結果も出ています。 (参考: The Smart Audio Report | National Public Media)
このスマートスピーカー Amazon Echo(アレクサ、Alexa)ですが、自分でプログラミングをして、自由に拡張し、機能を増やすことができます。
Amazon Echo(アレクサ、Alexa)は単体でも便利ですが、自分好みの機能を追加すると、さらに便利で使うのも楽しくなります。
プログラミングといっても、音声認識などはプラットホーム側でやってくれるので、文字列処理だけで比較的簡単に拡張できてしまいます。
スマートスピーカーは声だけで使えるので、自分で作ったプログラムをすぐに同僚や友人、家族などに使ってもらえるのも魅力的ですよね。
ただ、実際にAlexaアプリをプログラミングして動かすには、開発環境やサーバの設定が必要です。プログラミング自体は簡単でも、実際に作って動かすところまで持っていくのはなかなか面倒な作業も伴います。
そこで、今回はPaizaCloudを利用してみます。
PaizaCloudは、クラウド上で動く開発環境です。PaizaCloudでは、面倒なインストールや環境設定をすることなく、Web開発やアプリケーション開発を簡単・手軽に始められます。
PaizaCloudでは、Alexaアプリの開発に適した環境も用意されているので、ブラウザさえあれば、すぐにAlexaアプリをプログラミングして開発することができます。
開発環境がクラウド上で動作しているので、自分でサーバなどを用意しなくても、作ったプログラムはその場ですぐに動かせます!
今回は、実際にPaizaCloud上でRubyを使って、ツイートを読み上げてくれるAlexaアプリを作ってみましょう。
手順に沿っていけば、誰でも10分程度でAlexaアプリを作り、その場で動かしてみることができます。
PaizaCloud Cloud IDEを使う
それでは、始めていきましょう。まずは、PaizaCloudにログインします。
PaizaCloud Cloud IDEのサイトはこちらです。
メールアドレスなどを入力して登録すると、登録確認メールが送られてきます。GitHubやGoogle(Gmail)ログインを利用すると、ボタン一つで登録することもできます。
サーバを作る
次は、開発環境となるサーバを作ります。
「新規サーバ作成」ボタンを押して、サーバ作成画面を開きます。
特に何も変更せずに、もう一度「新規サーバ作成」ボタンを押すと、3秒程度でGoogle Homeアプリの開発環境がブラウザ上にできあがります。
Amazon開発者アカウントの作成
Alexaでアプリを開発する準備をしましょう。
Alexaの拡張機能はAlexa Skill(アレクサスキル)と呼びます。
Alexa Skillの作成は、Amazon開発者ポータルでできます。
まずは、AmazonのAlexa開発者ポータルをブラウザで開きましょう。 https://developer.amazon.com/
Alexaの開発をするには開発者用アカウントが必要ですので、なければ作成しましょう。
ページ上部の「サインイン」ボタンを押します。
サインイン画面が表示されます。
ロゴが"amazon developer"となっていることで、通常のamazonサイトではなく開発者向けサイトのログイン画面だということがわかります。
ここで、amazon.co.jpのアカウントを使ってログインします。
注意点として、「Amazon Developerアカウントを作成」ボタンは押さないでください。
「Amazon Developerアカウントを作成」でアカウントを作成してしまうと、日本のアマゾン(amazon.co.jp)ではなく、アメリカのアマゾン(amazon.com)向けのアカウントが作られてしまい、日本のアマゾンと関連づいたAmazon Echoなどで、開発アプリのテストができなくなってしまいます。
必ず、すでに持っている日本のアカウントを使ってログインしてください。もし、amazon.comのアカウントを作成してしまった場合は、amazon.comのメールアドレスを変更するなどして、開発者アカウントを作り直す必要があります。
初めてログインすると、開発者向けアカウントの申請画面が表示されます。
プロフィール情報を入力し、ライセンスに同意します。支払いタブでは設定変更は必要ありません。
これでアカウントが作成できました。
Amazon開発者ポータル(https://developer.amazon.com)で、「サインイン」ボタンを押してログインします。
ログインしたら、画面上部の「Developer Console」をクリックするか、以下のURLからアマゾンアプリ開発者ポータルの開発者コンソールを開きます。 https://developer.amazon.com/home.html
Alexa Skillの作成
次に、Alexa Skillを作成しましょう。
開発者ポータル上部のタブから「ALEXA」を選びます。
Alexa Skills Kitの「始める」を選びます。
「Alexa Skill Kit を使用して Alexa スキルを開発する」の画面が表示されますので、「新しいスキルを追加する」を選びます。
Alexaスキルの作成画面が表示されました。ここでAlexaスキルの作成を行います。
スキル:スキル情報
まずは、スキル情報を設定しましょう。スキルの種類は「カスタム対話モデル」を選びます。言語は「日本語」に設定します。
スキル名はAlexaアプリの名前を設定します。ここでは、「私のTwitter」としておきます。
呼び出し名はアプリを呼び出すときの名前を設定します。ここも「私のTwitter」にしておきます。
これで、「アレクサ、私のTwitterを開いて」と呼び出すことができるようになりました。
設定ができたら、保存ボタンをクリックした後、次へボタンをクリックします。
スキル:対話モデル
次に、対話モデルを設定します。ここで、どのような発話を認識するかを設定します。
まずは単純に何もせずに挨拶だけする設定にしてみましょう。
インテントスキーマでは、インテントを記述します。インテントとは、意図、目的、という意味で期待する動作を示します。ここでは、挨拶用のインテントを作成します。以下のようにJSON形式で設定を行い、GreetIntentという名前で挨拶用のインテントを設定します。
{ "intents": [ { "intent": "GreetIntent" } ] }
カスタムスロットは特に設定しません。
サンプル発話では、ユーザのどのような発話を認識して、どのインテントを対応づけるか設定します。
ここでは、挨拶インテントの一個しかなくて区別は必要ないので、以下のように適当にGreetIntentをHiという発話に対応するように設定します。
GreetIntent Hi
設定できたら「次へ」ボタンをクリックします。
スキル:設定
スキルの設定画面に移動しました。
ここでは、エンドポイントを設定します。エンドポイントとは、ユーザの発話を認識した後に起動するプログラムのことです。
プログラムはHTTPリクエストで呼び出すので、インターネット上でウェブサーバとして起動している必要があります。
AWS Lambdaまたは、HTTPSを選択できます。ここでは、PaizaCloud上でサーバを動作させるため、HTTPSを選びましょう。
なお、AWS Lambdaでは大規模な環境でも動作するようなサービスを作れますが、起動する言語が限られているなど自由度が低くデバッグが難しくなることがあります。
デフォルト欄では、サービスのURLを設定します。
Alexaのプログラムを動作させるウェブサーバは、証明書付きで暗号化されたHTTPSが必須で、ポート番号もデフォルトで動作させる必要があります。面倒な設定ですが、PaizaCloudではあらかじめHTTPSの設定はされており、任意のポート番号でサービスを動作させることができるので、特に設定することなく利用できます。
PaizaCloudで動かすサーバのホスト名は「サーバ名.paiza-user.cloud」になります。
また、次に作成するRuby Sinatraのサーバは80番で動作させます。PaizaCloudで立ち上げたサーバは自動的にSSLを利用できますので、プロトコルはHTTPではなく、HTTPSにします。特に、HTTPのデフォルト80番で立ち上げたサーバは、HTTPSのデフォルト443番で自動的に利用できます。
サービスのパス名は、 "/endpoint"としておきましょう。
結果、 URLは https://サーバ名.paiza-user.cloud/endpoint となります。(「サーバ名」は、作成したサーバの名前に 置き換えてください) 繰り返しになりますが、HTTPは指定できないので、HTTPSにしてください。また、ポート番号はURLでは指定できません。
他の項目は特に設定する必要はありません。
エンドポイントが設定できたら、「次へ」ボタンを押します。
スキル:SSL証明書
SSL証明書の設定をしましょう。PaizaCloudではワイルドカード証明書を利用しているので、2番目の「My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certificate authority」を選択します。他の設定を選ぶと、接続エラーになりますので、間違えずに設定してください。
設定したら、「次へ」ボタンを押します。
テスト画面が表示されます。
「このスキルはあなたのアカウントを使ってテストすることができます。」が有効になっていることを確認してください。この項目が有効になっていれば、あなたのAmazon Echoから、このアプリを呼び出すことができます。
「アレクサ、 私のtwitterを開いて」というように、Amazon Echoに話しかけてみましょう。
「リクエストされたスキルにアクセスできません」と返事がきました。そうですね、まだ実際に動作を行うプログラムは作成していませんでした。というわけで、次はプログラムを作成しましょう!
プログラムの作成
それでは、PaizaCloud上でプログラムを書いていきます。ここでは、RubyとSinatraを使ってサーバを作ります。
PaizaCloudでは、ブラウザ上でファイルの作成・編集ができます。
PaizaCloudの画面左側の「新規ファイル」アイコンをクリックしてみましょう。
ファイル名を入力する画面がでてくるので、ファイル名を"server.rb"として、「作成」ボタンを押します。
ファイルが作成されました!
まずは、単純に何か固定のメッセージを返してみましょう。以下のようなRubyプログラムを作成します。
require 'sinatra' require 'sinatra/reloader' require 'sinatra/json' post '/endpoint' do return json({ "version": "1.0", "response": { "outputSpeech": { "type": "PlainText", "text": "こんにちは、こちらはサーバプログラムです。", }, } }) end get '/' do return "Hello World" end
プログラムが作成できたら、「保存」ボタンで保存します。
では、プログラムを見てみましょう。"post /endpoint'"ブロックでは、POST "/endpoint"リクエストに対するアクションを書きます。ブロックの返り値がHTTP応答となります。
AlexaのサービスはJSON形式を利用しますので、json()メソッドを使います。
"response"の"outputSpeech"の"text"フィールドには、このアプリが話す内容を書いておきます。ここでは、固定の「こんにちは、こちらはサーバプログラムです。」というメッセージを返します。
また、動作確認のため、トップページ(GET '/'リクエスト)へのアクションを"get '/'"ブロックに書いておきます。ここでは単純に"Hello World"としておきます。
それでは、このプログラムを実行して動かしてみましょう。
実行するには、"sudo ruby ./server.rb -o 0 -p 80"のようにコマンドを実行します。
sinatraは、デフォルトではlocalhostのみで待ち受けて外部から接続できません。そこで、このように、"-o 0"(又は"-o 0.0.0.0")オプションを追加してグローバルアドレスで待ち受けて外部から接続できるようにします。
また、sinatraはデフォルトではポート4567番で待ち受けますので、"-p 80"オプションを追加して、HTTPのデフォルトポート80番で待ち受けるようにします。PaizaCloudでは、このようにHTTPのデフォルトポート(80番)で待ち受けたサービスは、自動的にHTTPSのデフォルトポート(443番)でも待ち受けることができます。80番で待ち受けるサービスは一般ユーザでは実行できないので、このように"sudo"コマンドを前につけて、root権限で実行するようにします。
PaizaCloudでは、ブラウザ上で、コマンドを入力するための「ターミナル」を使うことができます。
画面左側の、「ターミナル」のボタンをクリックします。
ターミナルが起動しますので、"sudo ruby ./server.rb -o 0 -p 80"と、実行するコマンドを入れて改行キー(エンターキー)を押しましょう。
$ sudo ruby ./server.rb -o 0 -p 80
コマンドが実行されました。"tcp://0:80"と表示されており、ポート番号80でサーバが動作していることがわかりますね。
また、画面の左側に、"80"と書かれたボタンが追加されています。
HTTP 80番ポートでサーバが起動しますが、PaizaCloudでは、このHTTP 80番ポートに対応したブラウザ起動ボタンを自動で追加しています。HTTPS(443番)でも接続できるようになっています。
ボタンをクリックすると、ブラウザ(PaizaCloudの中で動くブラウザ)が起動して、"Hello World"と表示されました!
それでは、このプログラムがちゃんと呼び出されるか確認してみましょう。
スキル:テスト
Amazon Echoなどで直接試すこともできますが、開発者ポータルではブラウザ上でテストできるシミュレータが提供されていますから、それを使ってみます。
下記URLの、アマゾンアプリ開発者ポータルに戻ります。 https://developer.amazon.com/edw/home.html#/skills
"Alexa Skills Kit"の"始める"ボタンをクリックし、表示される一覧から作成中のアプリ(私のTwitter)を選び、スキル設定ページを開きます。ページ左側のメニューから「テスト」を選びます。
いくつかシミュレーターが用意されています。
テストシミュレータではブラウザ上で対話ができますが、現状日本のアカウント(amazon.co.jp)では使えないようです。ここでは、サービスシミュレーターを使ってみましょう。
サービスシミュレータの「発話を入力してください」に何かメッセージを入れて「私のTwitterを呼び出す」ボタンを押してみます。
結果が表示されました。
サービスリクエストが、先ほど作成したプログラム(サーバ)に送信されたJSONデータです。サービスレスポンスが、サーバからの返事です。
「こんにちは、こちらはサーバプログラムです。」と返事が返ってきていますね!
今度は、実際にAmazon Echoに話かけてみましょう。
あなた:「アレクサ、私のツイッターを開いて」
Alexa:「こんにちは、こちらはサーバプログラムです。」
返事が返ってきました!成功です!
Twitterからのツイート取得
それでは、いよいよツイートを読み込んで、読ませてみましょう。
ツイートを読み込むには、TwitterのAPIキーが必要になります。やり方がわからない方は以下の記事を参考にしていただいて、あらかじめAPIキーを用意しておきましょう。 paiza.hatenablog.com
設定ファイル(twitter-config.rb)を作成して、このAPIキーを以下のように設定します。
ここで、YOUR_CONSUMER_KEY / YOUR_CONSUMER_SECRET / YOUR_ACCESS_TOKEN / YOUR_ACCESS_SECRET には、取得したAPIキーに置き換えてください。
twitter-config.rb:
require 'twitter' config = { consumer_key: "YOUR_CONSUMER_KEY", consumer_secret: "YOUR_CONSUMER_SECRET", access_token: "YOUR_ACCESS_TOKEN", access_token_secret: "YOUR_ACCESS_SECRET", } $twitterRestClient = Twitter::REST::Client.new(config) $twitterStreamingClient = Twitter::Streaming::Client.new(config)
サーバプログラムを、ツイートを読み込んで返すように変更します。
server.rb:
require 'sinatra/json' require './twitter-config' post '/endpoint' do tweets = $twitterRestClient.home_timeline text = tweets[0].text return json({ "version": "1.0", "response": { "outputSpeech": { "type": "PlainText", "text": "えーぴーあいから最新ツイートを読み上げます。" + text, }, } }) end get '/' do return "Hello World" end
プログラムを見てみましょう。$twitterRestClient.home_timelineでは、Twitter APIを利用して、あなたのタイムラインのツイートを読み出しています。
メッセージは、ツイートオブジェクトのtextメソッドで取得できるので、「tweets[0].text」として取得します。そして、取得したツイートメッセージをJSON形式で返します。
サーバプログラム(server.rb)をCtrl-Cで終了してから再起動します。
$ sudo ruby ./server.rb -o 0 -p 80
動作を確認してみましょう。
まずは、サービスシミュレータで確認してみます。すると、最新のツイートメッセージが表示されました。
実際に、Amazon Echoに話しかけてみましょう。
あなた:「Alexa、私のTwitterを開いて」
Alexa: 「えーぴーあいから最新ツイートを読み上げます。ご飯なう。」
最新ツイートを読み上げてくれています!
Twitterのツイート検索
今度は、ツイートの検索機能を追加してみましょう。「〜で検索」という言葉に反応するようにしてみます。
開発者コンソール(https://developer.amazon.com/edw/home.html#/skills)でスキルを選択し、設定画面を開きます。
ページ左側から「対話モデル」を選びます。
インテントスキーマでインテントを設定します。
ここでは、検索用にSearchIntentという名前のインテントを作成しましょう。また、「〜で検索」の、「〜」のように固定されていないメッセージを扱う場合は、スロットを利用します。
スロットはプログラムの変数のように、ユーザの発話に応じて値が入ります。ここでは、「Keyword」という名前のスロットを作成します。スロットはタイプを指定します。ここでは、「KEYWORD_TYPE」という名前のスロットを作成しています。
{ "intents": [ { "intent": "SearchIntent", "slots": [ { "name": "Keyword", "type": "KEYWORD_TYPE" } ] } ] }
次に、カスタムスロットタイプでは、スロットタイプを設定します。KEYWORD_TYPEで受け入れたい文字一覧を設定しておきます。Alexaでは、このようにあらかじめ候補となる文字列を設定することで、認識率を上げています。
ここでは、例としてスポーツをいくつか入れておきましょう。
サッカー 野球 卓球 テニス 水泳 スキー
設定できたら、「更新」ボタンをクリックして追加します。
次に、サンプル発話を設定します。ここでは、「〜を検索」というメッセージがKeywordIntentに割り当てられるように、以下のように設定します。{Keyword}の部分はスロットになり、任意の文字がわりあてられます。(注意: {Keyword}の後ろにはスペースを入れてください。)
SearchIntent {Keyword} で検索
サーバプログラム"server.rb"も以下のように変更しておきます。
server.rb:
require 'sinatra' require 'sinatra/reloader' require 'sinatra/json' require './twitter-config' post '/endpoint' do obj = JSON.parse(request.body.read) puts "REQUEST:", JSON.pretty_generate(obj) message = 'なになにを検索、と話してください。' if obj['request']['intent'] && obj['request']['intent']['slots']['Keyword'] keyword = obj['request']['intent']['slots']['Keyword']['value'] tweets = $twitterRestClient.search(keyword).take(5) if tweets[0] text = tweets[0].text message = "#{keyword}でのツイート検索結果を読み上げます。" + text else message = "#{keyword}のツイート検索結果はありませんでした。" end end return json({ "version": "1.0", "response": { "outputSpeech": { "type": "PlainText", "text": message, }, "shouldEndSession": false, } }) end get '/' do return "Hello World" end
プログラムを見てみましょう。ユーザの「〜で検索」という発言の「〜」の部分はHTTPの要求ボディにJSON形式で渡されますので、JSON.parseでオブジェクトに変換します。
初回接続時のメッセージを「なになにを検索、と話してください。」としておきます。
request/intent/slots/Anyフィールドにパラメータが保存されているので、"keyword"パラメータを取得します。
キーワードでツイートを検索します。検索するには、$twitterRestClient.searchメソッドを呼び出します。取得できたら、ツイートの内容をJSONオブジェクトで返します。
サーバプログラム(server.rb)をCtrl-Cで終了してから再起動します。
$ sudo ruby ./server.rb -o 0 -p 80
動作を確認してみましょう。
まずはサービスシミュレーターで試してみてください。
「サッカーを検索」のように入れてみると…結果が返ってきましたか?
いよいよ、Amazon Echoの実機で話しかけてみましょう。
あなた: 「Alexa、私のTwitterを開いて。」
Alexa: 「なになにを検索、と話してください。」
あなた: 「サッカーを検索」
Alexa: 「サッカーでのツイート検索結果を読み上げます。...」
会話ができています!成功ですね!
これでAlexaアプリが完成しました!
なお、PaizaCloudの無料プランでは、一定時間が経つとサーバは停止します。継続的に動かしたい場合は、ベーシックプランへアップデートしてください。 詳しくはこちら
まとめ
PaizaCloud上で、Amazon Echoで動作するAlexaアプリをRubyプログラムを書いて作り、その場で実際に動かしてみました。
Alexaアプリは、音声認識をあまり意識しなくても、簡単に作れるようになっています。また、作ったアプリを声だけで、誰でもすぐに使えるのも魅力的です。どんなメッセージにどう応答させるかを考えながら作ったり、使いながら改良したりするのは楽しいですね。興味のある方は、ぜひ作ってみてください!
(botを作ってみたらpaiza(@paiza_official)まで教えてくれるとうれしいです!)
「PaizaCloud」では、環境構築に悩まされることなく、ブラウザだけで簡単にウェブサービスやサーバアプリケーションの開発や公開ができます。
「paizaラーニング」では、未経験者でもブラウザさえあれば、今すぐプログラミングの基礎が動画で学べるレッスンを多数公開しております。
そして、paizaでは、Webサービス開発企業などで求められるコーディング力や、テストケースを想定する力などが問われるプログラミングスキルチェック問題も提供しています。
スキルチェックに挑戦した人は、その結果によってS・A・B・C・D・Eの6段階のランクを取得できます。必要なスキルランクを取得すれば、書類選考なしで企業の求人に応募することも可能です。「自分のプログラミングスキルを客観的に知りたい」「スキルを使って転職したい」という方は、ぜひチャレンジしてみてください。