IKEPの制作ブログ

学生エンジニアIKEPの制作ブログです。作品の技術話や制作での経験談などを書いています。

DialogflowとIFTTT, GASを使ってGoogleHome開発をやってみた

世間のスマートスピーカーブームに乗せられてGoogle Home miniを購入しました。ヨドバシで見ると半額の3000円くらいで安く売ってるし、なんか開発できたら面白そうだからまあ買うかと…。そこで最初に作ったGoogleHomeアプリのことを書きます。

 

前回、GAS(Google Apps Script)でwebアプリケーションを作ったという記事を書きました(前回の記事を読んでいない方のために簡単に言うと、大学サークルの機材貸出返却システムをGASを使ってwebアプリとして作った。詳しくはこちら)。今回はそれを拡張し、GoogleHomeを使って「~~~貸出!」とか言うだけで機材の貸出返却手続きをできるようにしたものです。

 

処理の流れとしては、GoogleHome(Google Assistant)で操作 -> Dialogflowでデータ取得 -> 以前作ったGAS&GoogleスプレッドシートにGETリクエスト -> GASで処理後、IFTTTに処理結果通知文をPOST送信 -> IFTTT内でwebhooksをトリガーにLINEへ通知、という感じです。

 

f:id:IKEP:20180519202815p:plain

 

GETリクエスト、POST送信はJSON形式で行っています。

本当は、GASからの処理結果通知文をDialogflowに返してその文章をGoogle Homeに喋らせたかったのですが、調べて見るとGASのdoGetのの戻り値(今回は処理結果通知文のJSONデータ)はGAS側でリダイレクトされる模様。リダイレクトされた先でJSONが取得されるそうです。つまり、GASからの返答を直接dialogflowで取得できないらしい(泣)….(コチラの方の記事を参考にさせていただきました)。

 

GASとdialogflowの間にAWSとかGoogle Cloud functionsなどのサーバーを挟んで右から左に流すようにすればできるみたいです(詳しくはコチラ)。自分はGoogle Cloud functionsでやってみようとしたが、サーバー系を触るのはは初めてなので案の定、エラー出まくりで断念…(泣)。(勉強するか~…..)

 

そこでGASからIFTTTにPOST送信して、webhookをトリガーにLINEに通知することにしました。

 

 

Dialogflow

Dialogflowの使い方は多くの方が書いていらっしゃるので簡単に

サークルの機材はナンバリングされているので(カメラ番号1番のならC1、レンズ番号1番ならL1など)機材の種別、番号と手続き者の学籍番号、貸出か返却か、のEntitiesを作成(機材の種別=>class、番号=>no、自分の学籍番号=>stNo、貸出か返却か=>key1、key2。Endは終了コマンド)。

 

f:id:IKEP:20180519202901p:plain

 

Entitiesの具体的な中身はこんな感じ↓

 

f:id:IKEP:20180519202931p:plain

 

で、貸出の時のIntentsはこんな感じ↓

 

f:id:IKEP:20180519203009p:plain

f:id:IKEP:20180519203044p:plain

 

Training phrasesの候補の作り方と先ほどのEntitiesとの組み合わせで簡単にそこそこAIっぽく作れます♪

 

Action and parametersのREQUREDにチェックを入れておくと、音声コマンドの中に後でGETリクエストするときに必ず必要なものがない時に聞いてきてくれるようにできます。聞き返す文章はAction and parametersのPROMPTSに書いておきます

 

f:id:IKEP:20180519203126p:plain

 

あとはGETリクエストを送るためにFulfillmentのEnable web hook call for this intentにチェックを入れておきます。

 

そして、左のタブからFulfillmentを選択し、GETリクエストを送る先のURLを書けば完成!

 

f:id:IKEP:20180519203223p:plain

 

 

 

GAS

先ほどのDialogflowのからのwebhookをdoPost(e)で受け取っています。Dialogflowで送ったデータはJSON形式でパラメータeの中に格納されています。

コードはコチラ

JSONから必要なデータを取り出し、そのデータを貸出返却手続きをしている関数に渡すだけです。この関数からの通知メッセージ文をIFTTTのURLのパラメータとして

var url = "IFTTTのURL?"+"value1="+str+"&value2="+class+no+"&value3="+key;

UrlFetchApp.fetch(url);

するだけです。IFTTTのURLについてはもう少し先↓

 

IFTTT

GASからのリクエストをWebhooksをトリガーにして通知メッセージをLINEに送信します。

アプレットはこんな感じ↓

f:id:IKEP:20180520141316p:plain

f:id:IKEP:20180520141336p:plain

Value1には通知メッセージ、Value2には機材番号、Value3は貸出か返却かが自動的に格納されています。

 

 

完成

これで完成です。実際に動かしてみると.....

 

 



Dialogflowの使い方で少し困ることがありましたが、非常に簡単にできました♪

Dialogflowでスマートスピーカーの簡易AI、GASでサーバー、スプレッドシートでデータベースとしてそれぞれ使えるので便利ですね

 

次はサーバーをちゃんと立ててがっつりしたもの作ろかな〜......

web知識0大学生がGASを使い、3日でサーバーレス機材管理システムを作る

僕がサークルのためのwebアプリを作成した時の話を書きます。

私が大学で所属しているサークルは、写真系のサークルです。そのサークルでは一眼レフカメラなどの機材貸出を自由にできるのですが、貸出の手続きがめんどくさかったり、誰が何を借りているのかの管理が雑だったりという状況でした(笑)。

 

当時はプログラミングを勉強しだして数ヶ月が経ったころで、何か人のためになるものを作ってみたいと思っているところでした。そこで機材貸出手続きの煩雑さをなくし、かつ管理も簡単に行えるシステムを作ろうと思い立ちました。

 

まず考えたのは、当時Swiftを勉強中だったのでiPhoneアプリとして作ろうと考えましたが、サークルにはAndroidユーザーもいたので却下!(Xamarinなどで作ってもいいが当時は知らなかった...)

次にwebアプリ。これならインターネットに繋がりさえすればみんなが使えるからいいのでは?しかし、サーバーやデータベースの知識はないし、そもそもサーバーなどを使うとなると自分が卒業したときに(文系の学生もいるため)後輩がシステムの保守に苦労するのではと...。

 

そこで調べた結果、Google Apps Script(以下、GAS)を使おうと決めました。サーバーはGoogleのものだから管理もいらないし、簡易データベースのようなものとしてGoogleスプレットシートも使える!web公開できるので誰もが使える!何より自分が卒業してから機材が増えても、後輩はスプレッドシートに追加機材の名前を書くだけでいい!

 

じゃあ、GASで作ってみるぞっと...

Googleドライブから新規にスプレッドシートを作成。

シート1枚目にはこんな感じで↓

f:id:IKEP:20180516200025p:plain

 

シート2枚目にはこんな感じ↓

f:id:IKEP:20180516200101p:plain

 

シート3枚目はこんな感じ↓

f:id:IKEP:20180516200133p:plain

 

これだけでプログラムからデータを書き込めば、簡易データベースみたいに使えるからラクチン♪

 

そして、プログラムを書く

スプレッドシートの「ツール」→「スクリプトエディタ」を開く

f:id:IKEP:20180516200439p:plain

 

開いたら、あとはプログラムをカタカタと書くだけ...

こんな感じ↓

f:id:IKEP:20180516200801p:plain

 htmlと.gs(google scriptの略?)ファイルで構成されてます。

.gsは基本的にはJavaScriptです。それにGoogleのサービス(スプレッドシートへの書き込みやGmail送信など)を使えるようにしたもの、みたいな感じです。

まだまだ未熟な時期でしたので汚いコードですね...笑

それでもプログラムを見たいもの好きな方はこちらへどうぞ↓

コードを見たい方はこちら(github)

 

追記 

リファクタリングを行い、コードの大幅な修正を行いました。

コードを見たい方はこちら(github)

 

基本的には貸出、返却ボタンを押すとJavaScriptを実行して入力データを取得。そのデータを.gsファイルの関数でスプレッドシートと比較しながらエラーチェック。エラーがあるならどういうエラーかをString文で返し、問題なしなら貸出返却の記録をスプレッドシートに書き込み完了メッセージをStringで返す。そのString文をhtmlファイル内のJavaScriptでalertするという流れです。(詳しくはコードを見てください)

 

プログラムができたら、webアプリとして導入

「公開」→「ウェブアプリケーションとして導入」

f:id:IKEP:20180516232300p:plain

「自分(~~~@gmail.com)」と「全員(匿名ユーザーを含む)」を選択。これでURLさえ知っていれば誰でもwebアプリにアクセスできるようになります。

f:id:IKEP:20180516232549p:plain

更新を押すとURLが現れます。これがwebアプリのURLになります。以後、プログラムを更新しても同じURLです。

ここで、僕がつまずいたことを二点。

1. 上記で行ったURLは「https://script.google.com/~~~~/exec」になっていると思います。しかし、「最新のコード」いうリンクをクリックして開くのは「https://script.google.com/~~~~/dev」。何が違うのかというと、プログラムを変更するとdevにはすぐに適用されるが、execは上の写真でプロジェクトバージョンを変更して更新ボタンを押さないと適用されない。devは開発中の確認用、execは正式公開用ということだろう。

 

2. gs内でdoGet()関数を書かないとhtmlに記述したのが表示されない。

function doGet() {
return HtmlService.createTemplateFromFile(htmlファイル名).evaluate().setTitle(webアプリ名(ブラウザのタブに表示される));

これを書いておかないと、URLにアクセスしても(Getリクエストしても)htmlファイルが返ってこないので表示されない。(当たり前と言えば当たり前だが...(^^;;)

 

 

では、URLにアクセスして試すと.....

f:id:IKEP:20180516214521j:imagef:id:IKEP:20180516214536j:image

f:id:IKEP:20180516234955j:plain

ちゃんとスプレッドシートの状態に応じて、返ってくるメッセージが変わっています👏

f:id:IKEP:20180516215149j:image

貸出受付メッセージが出たものは貸出記録がスプレッドシートに書き込まれています(^^)

 

 

ここまで実装して色々と大変だったことを...

1. JavaScriptファイルを保存できないのでhtmlファイル内の<script>タグに直書きしなければならない.....

2. JavaScriptからgoogle.script.run.(.gs内の関数名)で.gsの関数を呼び出せるが、非同期であること。

3. gsからの結果をJavaScriptの呼び出し元で受け取ること

 

特に2,3が大変でした。

2については最初、google.script.run.(.gs内の関数名)で.gsの関数を呼び出していました。しかし、非同期なので3ができない.....。調べて見るとどうやらgoogle.script.run.withSuccessHandler(xxx).(.gs内の関数名)で解決できる模様(xxxは.gs内の関数実行した後に実行する関数)。で、html内で

function xxx(str){

         alert(str);

}

ように書くと.gsのreturn結果がstrに格納されていて無事アラート画面が出ました😆

 

+α、返却期限を過ぎていたら返却催促のメールを行うようにして見ました。

シート1枚目の貸出状況を確認して、貸出中の人の返却期限を今日の日付と比較。期限を過ぎていたらその人の学籍番号をもとにシート2枚目からメールアドレスを取得。あとは、メール送信という流れです。(詳しくはコードを見てください。.gsのcheck関数です。)

 

あとはトリガーを設定

時計見たいなマークをクリック

f:id:IKEP:20180516205725p:plain

こんな感じに設定↓

f:id:IKEP:20180516205846p:plain

これだけで自動的に毎日9時ごろにcheck関数を実行してくれるのですごいラク

 

 

f:id:IKEP:20180516205300p:plain

 

無事メールが届きました😁

 

QRコード読み取りでデータ入力もできるようにしましたが、これはネットの先人のものをいただいてきました 笑

————————————————————

 

 

これで貸出返却手続きが1分足らずでできるようになりました!さらに誰が何をいつまで借りていてるのかもスプレッドシートを見るだけで一目瞭然です。返却記録も残せるし、返却催促も勝手にやってくれるので、すごい楽になりました^_^

 

今回GASを使って思ったことは、

GAS便利すぎーー!!!

サーバー•データベースレスでwebアプリが作れるし、doGet(e)でパラメータeに応じたGetリクエスト処理もできるので自作APIも作れちゃう!!(これについては別記事で)

web関係知識、JavaScript経験ともに0な私でも2、3日で作れましたので、非常におススメです( ^ω^ )

 

 

 

駆け出しの大学生がVRコンテストに出場した時のお話

 

半年ほど前にVRのコンテストに出場した時のことを書きます。 

私は当時、大学の授業を通じてプログラミングに興味を持ち、独学でプログラミングを勉強していました。

そのころの実力はエンジニアとして勉強しだして半年なため、まだまだ未熟でした(今もですが...)。具体的には、やっと自分のiPhoneアプリが作れるようになったくらいでした。

 

そんな時、国際学生対抗バーチャルリアリティコンテスト2017(IVRC2017)の募集をしているのを耳にしました。VRに興味はありましたが、果たして自分にできるのかという不安がありました。しかし、過去に同じようなことがあってやらずに後悔したので、今回はやってみようと参加することにしました。

 

 企画書制作

企画書を提出してそれにより選考が行われるので企画会議を行った結果、『体験者がかぐや姫になり、竹の中から生まれる時の体験をできるVRコンテンツ』を作成することに決定。

理由は、

1.日本人なら誰でも知っており、桃太郎と同じように出生ストーリーに疑問を持ったことがある。

2.翁に自分の竹を切られる瞬間に作品としてのインパクトがある

といったようなことだったと思います。

すると、無事選考を通過しコンテスト参加決定🎉

 

 

作品制作

私はHMD内の映像制作(Unityでの制作)を担当することになりました(以下動画参照)。

ここで疑問が....

「翁は光ってる竹に気付いた結果かぐや姫を見つけたけど、そもそもなんで竹が光ったんだ??」

結果、「かぐや姫は光らないと放ったらかしにされて生きていけないから!」と勝手に考え、「だったら体験者に光ってもらおう!」と(笑)

そこで体験者が体を左右に揺らすことで自分が光りだすインタラクションを作ることにしました。HMDにLEDを取り付け、さらにHMD内の映像でも視界周辺を黄色に変化させることに。

 

また、翁に自分の竹を切られた時の体験のインパクトを高めるため、風圧の表現に空気砲を、真っ暗な竹の中から明るい外の世界を変化をHMD内の映像で表現することに。

 

完成形がこんな感じ↓

f:id:IKEP:20180422190123j:plain

かなり手作り感が出ていますが( ̄▽ ̄;)...

 

体験者の視点(HMD内の映像)はこんな感じ↓

*PC上でプログラムを実行したものをキャプチャした動画です

 

 

「かなりいい感じじゃね!?」っと思っていました。

会場へ行くまでは......

 

 コンテスト当日

コンテスト当日、会場について真っ先に思ったことは、

「レベルが違う.....」

でした。他の参加チームとの作品完成度の違いを思い知りました。

作品のアイディアだけを考えると私のチームもいい勝負だったと思います。しかし、

そのアイディアをどう表現するのか、どういうシステム,機構を用いて作成するか、VRの弱点や利点をどのように隠し、どのように利用するのか、

全てにおいて大きな壁を思い知りました......

当然といえば当然です。プログラミングを勉強して半年の『駆け出し者』が、専門で研究している学生と対等であるわけがありません。

 

しかし、ショックに思うよりかは楽しみの方が大きかったです。新しい知識を得られただけでなく、自分が学生のうちにどこまで成長できるのか、といったことがなんとなく実感することができたからです。

 

続きを読む