ねぇ Google、 Rebuild.fmを流して(がやりたかった話)


この記事は JustSystems Advent Calendar 2017 の 11日目の記事です。

はじめに

GoogleHome 便利ですよね
発売日の次の日に購入してから、IFTTTIRKit,Trelloなどと連携してかなり生活が豊か(というのかわかりませんが??)になっています。

そんな僕が今GoogleHomeでどうしてもやりたいことは

「ねぇ、Google Rebuild.fmを流して」  

Rebuild.fmとは?

こちら -> Rebuild.fm
ホストの宮川さん@miyagawaが毎回ゲストを招いて技術系トーク(とそれ以外の話)を繰り広げるPodcastです。
とっても勉強になるし話も面白い!
これを音楽と同じ感じでGoogleHomeにお願いしたかったのです。  

結果

できなかった。。

この記事はこれを実現するために色々やった記録です。
目的は果たせませんでしたが、得るものは色々ありました。  
ので、「あーこれできないんだ」的なものを中心にお伝えできればと思います。
逆に「えっそれできるよ?」「〜でやればよくね?」等ありましたらぜひコメントで教えてください

やったこと

Audioが再生したい

まず、GoogleHomeでRebuildを流すということは任意のAuidoを再生できればいいということ!
ということで、そのやり方を探したところこんなやり方が見つかりました。

google-home-notifier

google-home-notifier

ほうっ!
Httpリクエストで任意の言葉をGoogleHomeに喋らせることができて、Audioの再生も可能らしいっ!!
↓しかもすでに情報も多そうっ!!!
GoogleHomeスピーカーに外部からプッシュして自発的に話してもらいます
帰宅したらGoogleHomeから好きな音声で「おかえり」って言ってもらいます
Google Home開発入門 / google-home-notifier解説

でも今回はサーバを立てるとかしたくなかったので、別の方法を探すことにしました。(これが大きな過ちでした

SSML

Action on Google でSSML(Speech Synthesis Markup Language)が使えるらしいっ!
要はAction on GoogleでレスポンスにSSMLのAudioタグを使えば一発OKらしいっ!!

こんな感じ(URLは実際と異なります)

これしかないっ!!!

 SSMLを使ってみる

Rebuild.fmのページにはダウンロードリンクが用意されています。
こちらのパスをみると http://cache.rebuild.fm/podcast-ep196.mp3 となっていたので早速、試して見ました。

Action on googleの使い方はこちらがとてもわかりやすいです。
Actions on Googleでapi.aiを使ってGoogle Homeに何か言わせてみる



実行のイメージはこうです



でも動かない・・・

調べるとどうやら、 httpではなくhttps 出ないとダメな模様 _(:3」 ∠ ) _

GoogleDriveに保存したファイルを再生する

しかたない。
少々面倒ですが、GoogleDriveに保存したファイルを再生させることにします。


こんな感じ

GoogleDriveならGoogleAppsScriptで自動でGoogleDriveに保存することができます。  

function doPost(request) {
  // DiologFlowからのリクエストパラメータで第何回かを取得する
  var episode = JSON.parse(request.postData.contents).result.resolvedQuery;

  // googleドライブのフォルダ準備
  // IDはあらかじめスクリプトプロパティに定義
  var scriptProperties = PropertiesService.getScriptProperties();
  var folderId = scriptProperties.getProperty('DRIVE_FOLDER_ID');
  var folder = DriveApp.getFolderById(folderId);

  // ファイルを取得
  var name = 'podcast-ep' + episode + '.mp3';
  var audio = UrlFetchApp.fetch('http://cache.rebuild.fm/' + name).getBlob();

  // ファイルを保存
  folder.createFile(audio);
}



「Driveへの保存」と「GoogleHomeに喋らせる(SSML形式での返却)」をどういう流れで行うかはさておき(結構重要)、とりあえずGoogleHomeにDriveのファイルを再生させてみます。  

SSMLのsrcを書き換えて実行してみます。

<speak>
  <audio src="https://drive.google.com/uc?export=download&id=[ID]">再生ファイルが見つかりません。</audio>
</speak>

(GoogleDriveの共有リンクはダウンロードリンクではないため、こちらを参考にURLに手を加えています。)


...「再生ファイルが見つかりません。」

GoogleHomeから聞こえてくる無機質な声のエラー文言。
なんで😨??
「S」なのにっ!!

おそらくですが静的な直リンク出ないとダメみたいです。(DropBoxでもダメでした
(Rebuildのファイルが仮にhttpsだとしても無理だった??)

S3を使う

こうなったら引くに引けません。
「ラズパイあるんだからサーバたてた方が早くね?」とかいう理性を無視して感情の赴くままAwsのアカウントをつくります(持ってませんでした

AWSは公式のドキュメントがとってもわかりやすいです!
AWS アカウント作成の流れ
Amazon S3 コンソールユーザーガイドにようこそ


とりあえず、手作業でmp3を置いてURLを書き換え

<speak>
  <audio src="https://s3-ap-northeast-1.amazonaws.com/.../podcast-ep195.mp3">再生ファイルが見つかりません。</audio>
</speak>

いざ実行、、


...「いやねー(Nさんの声)」

キター!!!!!


GoogleHomeから聞こえてくる準レギュラーNさんのいい声。
これができればもう勝ったも同然


当然こんな感じの構想

 GoogleAppsScriptからS3へアップロード

あとは自動でS3にAudioファイルをアップロードすればほぼ完成。
ここではこちらを使わせていただきますアリガタヤ

S3-for-Google-Apps-Script

上記のコードの保存部分をアップロード処理に書き換えてこんな感じ

function doPost(request) {
  // DiologFlowからのリクエストパラメータで第何回かを取得する
  var episode = JSON.parse(request.postData.contents).result.resolvedQuery;

    // AWSのKeyはあらかじめスクリプトプロパティに定義
  var scriptProperties = PropertiesService.getScriptProperties();
  var accessKey = scriptProperties.getProperty('AWS_ACCESS_KEY');
  var secretKey = scriptProperties.getProperty('AWS_SECRET_KEY');

  // ファイルを取得
  var name = 'podcast-ep' + episode + '.mp3';
  var audio = UrlFetchApp.fetch('http://cache.rebuild.fm/' + name).getBlob();

  // ファイルをS3にアップロード
  var service = S3.getInstance(accessKey, secretKey);
  service.putObject('[S3のBucket名]', '[ディレクトリ]/' + name, audio, null);
}

試しに実行、、






はい、


10Mまでしかputできないっぽいです  

まとめ  

  • Action on Googleを使えば静的な直リンクのAudioファイルを再生できる(ただしhttpsに限る) 
  • GoogleAppsScript -> S3 のファイルアップロードは地味に使えそう
  • 大人しくサーバたててリベンジします

終わりに

この記事に関する質問、ご意見お待ちしています