こんにちは、サイオステクノロジー技術部 武井です。今回は、Amazonが販売しているスマートスピーカーAmazon Echo(アマゾンエコー、以降Echo)を使って、弊社ヘルプデスクの未処理のチケット数を教えてくれるスキルを作ってみたいと思います。
Amazon Echoとは?
音声だけで操作できるスマートスピーカーです。例えば「アレクサ、音楽かけて」とEchoに話しかけると、音楽を再生してくれたりします(Amazon Prime MusicもしくはAmazon Prime Music Unlimitedの契約が必要)。
また、「スキル」というものをアレクサにインストールすると、色々な機能を拡張できます。iPhoneでいうところのアプリみたいなイメージです。
例えば、インターネットラジオ「ラジコ」のスキルをインストールして、「ラジコ、何かラジオかけて」というとラジオを再生してくれます。
スキルは、独自開発も可能で、今回はこのスキルを自分で作っちゃおうという話です。
やりたいこと
弊社は、お客様に導入したシステムのサポート窓口「ヘルプデスク」を開設しております。このヘルプデスクあてに来た問い合わせは、オープンソースのチケット処理システム「OTRS」で管理しています。
仕組みとしては、特定のメールボックスを定期的にフェッチして、そのメールアドレス宛の問い合わせ内容をデータベースに格納し、「対応中」「完了」というステータスをつけたり、その他、チケット管理に必要な色々な情報を付与します。
今回やりたいことは、アレクサに「ヘルプデスクの未処理のチケット数を教えて」と話しかけると、「12件のチケットがあります」みたいな感じで、未処理のチケット数を返してくれるスキルを開発することです。
スキル開発の流れ
スキル開発の詳細については以下を参考に頂ければと思います。非常にわかりやすくまとまっています。
https://developer.amazon.com/ja/alexa-skills-kit/training/building-a-skill
が、せっかちな人のためにすごく簡単にスキル開発の流れをまとめてみました。
まずはじめに、Alexaの基本的な構成を図にしてみました。
上記の流れを順を追って、ご説明します。
(1)では、ユーザーがEchoに向かって話しかけます。Echoの音声解析エンジンがユーザーの発話を解析します。このエンジンが非常に優秀で、ちゃんと聞き取ってくれますし、結構離れていてもOKです。この発話内容は後ほど、Alexaエンジンに送られるわけですが、Alexaエンジンでは発話内容を以下のように分類します。
ウェイクワード
Echoに話しかける際の、最初の言葉です。どんなときでもこの言葉を最初に発する必要があります。人で言うところの名前みたいなものですね。
呼び出し名
スキルの名称です。これを発話することで、起動するスキルを決定します。例えば天気予報を教えてくれるスキルであれば、事前に呼び出し名を「天気予報」と定義しておけば、「アレクサ、天気予報で明日の降水確率を教えて」といえば、天気予報のスキルが起動します。
サンプル発話
Alexaに命令をする時の、基本的な発話内容です。ここでは、「明日の降水確率を教えて」と定義していますが、人によっては色々な言い方をするので、たくさん定義しておくと便利です。例えば、「明日の降水確率は何?」と聞く人もいれば、「明日の降水確率を知りたい」という人もいるかも知れません。その分だけ、サンプル発話を登録しておけば、それだけいろんな言い回しにも答えることが出来ます。
スロット
変数のようなものです。上記の図では「明日の降水確率を教えて」ですが、「明後日の降水確率を教えて」もあるかもしれませんし、「2018年3月14日の降水確率を教えて」もあるかもしれません。ユーザーの発話の中で、変動する部分で、しかもその内容によって、Alexaからの答えを変えたい場合は、スロットを使います。
(2)では、Echoが発話内容を認識して、クラウド上にあるAlexaに発話内容を送ります。
(3)では、先程(1)で紹介した「呼び出し名」「サンプル発話」「スロット」の定義内容に基づいて、発話内容を解析して、Lambdaにリクエストを送ります。
(4)では、(3)で送られてきたリクエストに基づいて答えを生成します。Lambdaでなくても可能ですが、Lambdaが一番手順が簡単です。
つまり、スキル開発とは以下の2点を行うことになります。
- (3)で説明した「呼び出し名」「サンプル発話」「スロット」の定義をAmazon Developer Console上で行う。
- (4)で説明した「答え」の生成をLambda(でなくてもよいのですが)で開発する。
今回のシステム構成
今回のキモは、OTRSの未処理のチケット数をどのようにして取得するかということです。実はここのところは、OTRSではRest APIを用意していて、簡単に未処理のチケット数を取得することが可能です。ということで、今回のシステム構成は以下のようになります。
ポイントは(4)で、LambdaからOTRSのAPIを叩いているところです。ここで未処理のチケット数を取得して、Alexaに返しています。では、実際の開発手順をご説明していきます。
開発手順
ここからは、先のシステム構成でご説明したものを開発していきます。
まず、OTRSのAPIにアクセスできるための設定を行います。OTRSに管理者でログインして、上部メニューの「管理」をクリックします。そして、画面右下部の「システム管理」から「Webサービス」をクリックします。
「Add Web Service」をクリックします。
「名前」に「Ticket」、「プロバイダーとしてのOTRS」の「Network transport」で「HTTP::REST」を選択して、「保存」をクリックします。
「追加」という項目が表示されますので、「Ticket::TicketSearch」を選択します。
以下の画面が表示されます。「名前」に「Search」、「Mapping for incoming request」と「Mapping for outgoing response」に「Simple」を選択して「保存」をクリックします。
以下の画面で、「プロバイダーとしてのOTRS」の「Configure」をクリックします。
下記のように設定して「保存して終了」をクリックします。
以上で、OTRS側の設定は完了です。
次に、「呼び出し名」「サンプル発話」「スロット」の定義をAmazon Developer Console上で行います。下記のURLにアクセスして下さい。
「サインイン」をクリックします。
アカウント作成画面が表示されます。必要な項目を入力して、「Amazon Developerアカウントを作成」をクリックして下さい。
以下の画面が表示されます。必要な項目を入力して下さい。
最後に「保存して続行」をクリックして下さい。
ライセンス確認画面が表示されます。
ひとしきり確認して、最後に「承認して続行」をクリックして下さい。
支払いの確認画面が表示されます。とりあえず、今回はテスト的に作成するだけなので、すべて「いいえ」としておきます。最後に「保存して続行」をクリックして下さい。
Amazon Developer Consoleのダッシュボードが表示されます。「ALEXA」のタブをクリックして下さい。
「Alexa Skills Kit」をクリックして下さい。
「Create Skill」をクリックして下さい。
スキル名を入力します。ここでは「CountOTRSTickets」とします。「Next」をクリックして下さい。
「Custom」の方を選択して「Create skill」をクリックして下さい。
「Skill Invocation Name」があります。これが最初に説明した「呼び出し名」になります。「ヘルプデスク」と入力して下さい。
次に、サンプル発話の部分を作成します。「Intents」をクリックして下さい。すると、画面右部にテキストボックスと「Create custom intent」のボタンが表示されます。テキストボックスの部分にサンプル発話名を入れます。ここでは「CountNewOrOpenTickets」として、「Create custom intent」をクリックして下さい。
サンプル発話を入力します。念の為、色々と入力しましたが「未処理のチケット数を教えて」だけでいいかもしれません。最後に「Save Model」を行って、保存して下さい。
とりあえず、Amazon Developer Consoleでの基本的な設定は終わりました。次は、答えの内容を作るために、Lambdaの設定をしましょう。
以下のURLにアクセスして、AWSのマネジメントコンソールに行きます。
https://aws.amazon.com/jp/console/
「コンソールへログイン」をクリックして下さい。
下記の画面でログインIDを入力し、次の画面でパスワードを入力します。
下記のように、リージョンを「アジアパシフィック(東京)」にします。
「AWSサービス」の表示の下のテキストボックスに「lambda」と入力して、Enterを押して下さい。
「関数の作成」をクリックします。
「設計図」の方を選択して、下記のテキストボックス(フィルターの追加)と書いてあるところに「alexa」と入力してEnterをクリックして下さい。そして、その結果として表示されるものの中から「alexa-skill-kit-sdk-factskill」をクリックして下さい。
関数の基本情報を入力します。下記のように入力します。最後に「関数の作成」をクリックして下さい。
トリガーの追加の画面で「Alexa Skills Kit」をクリックして下さい。左部の画面に追加されます。
ちょっと下にスクロールすると「トリガーの設定」があります。「スキルID検証」を「無効」にして、「追加」をクリックして下さい。
ちょっと上に戻って、「CountNewOrOpenOTRSTickets」をクリックすると、下の方にindex.jsが表示さます。
index.jsのコードを以下のように書き換えて下さい。
'use strict'; const Alexa = require('alexa-sdk'); const https = require('https'); // (1) const APP_ID = undefined; const HELP_MESSAGE = 'You can say tell me a space fact, or, you can say exit... What can I help you with?'; const HELP_REPROMPT = 'What can I help you with?'; const STOP_MESSAGE = 'Goodbye!'; const handlers = { 'LaunchRequest': function () { this.emit('OTRS'); }, 'CountNewOrOpenTickets': function () { // (2) const host = '[OTRSのFQDN]'; // (3) const path = '/otrs/nph-genericinterface.pl/Webservice/Ticket/Search'; // (4) const port = 443; // (5) const json = { UserLogin:"[OTRSの管理者ユーザー名]", // (6) Password:"[OTRSの管理者ユーザー名のパスワード]", // (7) States:"new" } let postDataStr = JSON.stringify(json); let options = { host: host, port: port, path: path, method: 'POST', agent: false, headers: { 'Content-Type': 'application/json', 'Content-Length': postDataStr.length } }; var req = https.request(options, (res) => { var body = ''; res.on('data', (chunk) => { body += chunk; }); res.on('end', () => { var result = JSON.parse(body); // (8) var count = result['TicketID'].length; // (9) this.emit(":tell", count + '個のチケットがあります'); // (10) }); res.on('error', (e) => { console.log('problem with request: ' + e.message); }); }); req.write(postDataStr); req.end(); }, 'AMAZON.HelpIntent': function () { const speechOutput = HELP_MESSAGE; const reprompt = HELP_REPROMPT; this.response.speak(speechOutput).listen(reprompt); this.emit(':responseReady'); }, 'AMAZON.CancelIntent': function () { this.response.speak(STOP_MESSAGE); this.emit(':responseReady'); }, 'AMAZON.StopIntent': function () { this.response.speak(STOP_MESSAGE); this.emit(':responseReady'); }, }; exports.handler = function (event, context, callback) { const alexa = Alexa.handler(event, context, callback); alexa.APP_ID = APP_ID; alexa.registerHandlers(handlers); alexa.execute(); };
標準から大きく異なる部分だけを説明します。
(1)は、OTRSのRest APIに接続するためのHTTPクライアントをrequireしています。
(2)は、Amazon Developer Consoleの方で、サンプル発話名として指定した「CountNewOrOpenTickets」と同じ名前の関数を設定します。この名前と一致した関数がLambda側で呼び出されます。
(3) は、OTRSのFQDNを設定します。
(4)は、OTRSのRest APIのパスを設定します。このパスは先程行ったOTRSの設定に基づき決定されます。
(5)は、OTRSのポート番号を指定します。
(6)は、OTRSの管理者のユーザー名を指定します。
(7)は、OTRSの管理者のユーザー名のパスワードを指定します。
(8)は、OTRSのRest APIを叩いた結果のレスポンスをJSONオブジェクトに変換しています。このJSONオブジェクトは未処理のチケットのチケットIDが配列として入っています。
(9)は、JSONオブジェクトに入っているチケットIDの配列の数をカウントしています。
(10)は、Alexaにレスポンスを返すところです。(9)で取得した配列の個数が未処理のチケット数をメッセージとして返しています。
画面上部のARNと記載されているところに書いてある値をメモします。後ほどAmazon Developer Consoleで使います。これは、LambdaのエンドポイントURLです。これをAmazon Developer Consoleで設定すると、この関数が呼び出されるようになります。そして、最後に「保存」をクリックします。
Amazon Developer Consoleに戻ります。画面左部メニューの「Endpoint」をクリックして、「AWS Lambda ARN」を選択して、先程メモした値をテキストボックスに入力します。最後に「Save Endpoints」をクリックします。
左部メニューの「Invocation」をクリックして、「Save Model」「Build Model」の順番にクリックします。スキルの開発は終わりです。
次は、テストしてみましょう。Alexは実機がなくてもシミュレートできるインターフェースが用意してあります。画面上部の「Test」をクリックして下さい。
横にスライドできるような丸いものがあると思います。それをクリックします。テストモードが有効になります。
マイクのマークがあるテキストボックスに「ヘルプデスクの未処理のチケット数を教えて」と入力してEnterを押して下さい。すると「XX個のチケットがあります」と表示されれば大成功です━━━━(゚∀゚)━━━━!!
さて、次は実機で動かしてみましょう。スキルはAmazonの審査を受けて、公開しなくても、ベータテストと言って、特定のアカウントだけでテストできるモードがあります。Amazon Developer Consoleの画面上部の「Launch」をクリックして下さい。
何やらいろんなチェック項目が出てきました。この内容によってテストが出来なくなるのかどうかは確認してませんが、私はとりあえず全部Noとしました。最後に「Save and continue」をクリックして下さい。
「Beta Test」をクリックして、「Enter Email Address」の部分に、テストをしたいAmazon Echoに紐付いているAmazonアカウントを入力して、「Add」を入力して下さい。
「Enable beta testing」をクリックして下さい。
すると、先程登録したAmazonアカウントのメールアドレス宛に以下のようなメールが届きます。「Enable Alexa skill “CountOTRSTickets”」をタップして下さい。
同意画面が表示されますので、「同意する」をタップして下さい。
するとAlexaのアプリの画面に遷移して、以下のようになります。「有効にする」をタップして、スキルを有効にして下さい。
さぁ、これで準備は整いました。Echoに向かって、「ヘルプデスクの未処理のチケット数を教えて」と叫んで見て下さい。「XX個のチケットがあります」と返ってくれば成功です(`・ω・´)シャキーン
最後に
いかがでしょうか?Echoって面白いですね。色々アイデアが広がりそうです。これからスキルの開発をする方にとって、本記事がお役に立てれば幸いです。