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

この記事は [JustSystems Advent Calendar 2017](https://qiita.com/advent-calendar/2017/justsystems) の 11日目の記事です。

# はじめに

GoogleHome　便利ですよね:smiley:
発売日の次の日に購入してから、[IFTTT](https://ifttt.com/)や[IRKit](http://getirkit.com/),[Trello](https://trello.com/)などと連携してかなり生活が豊か（というのかわかりませんが:thinking:??）になっています。 

そんな僕が今GoogleHomeでどうしてもやりたいことは
  
**「ねぇ、Google Rebuild.fmを流して」　**　


## Rebuild.fmとは？

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


## 結果  

できなかった。。  

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

# やったこと

## Audioが再生したい

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

### google-home-notifier

[google-home-notifier](https://github.com/noelportugal/google-home-notifier)  

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

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

### SSML  

https://developers.google.com/actions/reference/ssml

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

こんな感じ(URLは実際と異なります)
<img width="790" alt="response.png" src="https://qiita-image-store.s3.amazonaws.com/0/96682/ee9b324d-0ed9-6a37-34ca-334142c7ce31.png">

これしかないっ！！！

##　SSMLを使ってみる

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

Action on googleの使い方はこちらがとてもわかりやすいです。
[Actions on Googleでapi.aiを使ってGoogle Homeに何か言わせてみる](https://qiita.com/syarihu/items/53ea1a65f481f8121109)

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

<img width="70%" alt="response.png" src="https://qiita-image-store.s3.amazonaws.com/0/96682/78054eae-eef0-4942-02b5-1d59b6437a45.png">  

<br>
でも動かない・・・

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

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

しかたない。
少々面倒ですが、GoogleDriveに保存したファイルを再生させることにします。
<br>
こんな感じ
<img src="https://qiita-image-store.s3.amazonaws.com/0/96682/554cdf59-7057-b4b0-9f1f-aeaf5d34789f.png" width=70%>

GoogleDriveなら[GoogleAppsScript](https://developers.google.com/apps-script/)で自動でGoogleDriveに保存することができます。　　

``` js
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);
}
```
<br>
「Driveへの保存」と「GoogleHomeに喋らせる（SSML形式での返却）」をどういう流れで行うかはさておき（結構重要）、とりあえずGoogleHomeにDriveのファイルを再生させてみます。　　
<br>

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

```
<speak>
  <audio src="https://drive.google.com/uc?export=download&id=[ID]">再生ファイルが見つかりません。</audio>
</speak>
```
(GoogleDriveの共有リンクはダウンロードリンクではないため、[こちら](http://atranticlabo.seesaa.net/article/440878948.html)を参考にURLに手を加えています。)
<br>
．．．「再生ファイルが見つかりません。」
<br>

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

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

## S3を使う

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

AWSは公式のドキュメントがとってもわかりやすいです！
[AWS アカウント作成の流れ](https://aws.amazon.com/jp/register-flow/)
[Amazon S3 コンソールユーザーガイドにようこそ](http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/user-guide/what-is-s3.html)
<br>
とりあえず、手作業でmp3を置いてURLを書き換え

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

いざ実行、、
<br>
．．．「いやねー（Nさんの声）」
<br>

キター！！！！！
<br>
GoogleHomeから聞こえてくる準レギュラーNさんのいい声。
これができればもう勝ったも同然:sunglasses:
<br>
当然こんな感じの構想
<img src="https://qiita-image-store.s3.amazonaws.com/0/96682/86019cc7-8d28-51b4-3934-d69e3bfdada0.png" width=70%>


##　GoogleAppsScriptからS3へアップロード

あとは自動でS3にAudioファイルをアップロードすればほぼ完成。
ここではこちらを使わせていただきます:relaxed:ｱﾘｶﾞﾀﾔ

[S3-for-Google-Apps-Script](https://engetc.com/projects/amazon-s3-api-binding-for-google-apps-script/)

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

``` js
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);
}
```
試しに実行、、  
<br>

<img width="625" alt="error.png" src="https://qiita-image-store.s3.amazonaws.com/0/96682/85f30954-4964-8ab2-89f1-a0e343a08007.png">  
<br>
はい、
<br>
<img width="625" alt="error.png" src="https://qiita-image-store.s3.amazonaws.com/0/96682/e9573a65-2aad-4ce6-09a9-66a07d337220.png">  

1０Mまでしかputできないっぽいです:innocent:　　

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

# 終わりに

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