google homeにつぶやきを読み上げてもらうfrom linuxホスト

# google homeにつぶやきを読み上げてもらうfrom linuxホスト
google home mini 買っちゃったけど
IoTデバイス不足で静かなものです...
つぶやきでも喋ってもらいますか

雑なのでいろいろ抜けてますが取っ掛かりとしてはまぁありかなと思って書いておきます。

* コードが少ない
* 普通のlinuxで動いた
* mdnsいけてるみたい

という事が言いたいだけです。

参考させて頂きました https://qiita.com/SatoTakumi/items/c9de7ff27e5b70508066

RaspberryPiでweb apiするのが流行りみたいですが

*単なるlinuxホスト*で動かします。(Fedora 27)

作業してる裏でターミナルから実行させて流してます。

##必要なもの 
本当にコレで揃っているか無駄ないか覚えてない...X-(

* dnf install nodejs
* dnf install avahi-compat-libdns_sd-devel
* npm install google-home-notifer
* npm install mdns
* npm install chalk (必須ではないですコンソール出力に色つけたかっただけ)

-gとかはそれぞれよしなに。

mdns(avahi)でぼんじゅぅるぅ〜出来なかったので以下参考に
https://qiita.com/udon11/items/fef44cec7b243f93151b
https://github.com/noelportugal/google-home-notifier (下の方に)

~/node_modules/mdns/lib/browser.js を編集したらmy環境では取れました。
_動きますがlibから「Avahi native apiを使うように変更しなさいよ」って出ます_

面倒ならip直書き方式でも良いかと。(他記事参照でお願いします

適当なディレクトリで以下ファイル並べて
__mkfifo googleHome.pipe__
しておいてください。
走行は
__node ghpipe.js__
してconsole1つ放置してください。Ctrl-cで終了想定。
喋るかの確認とかはmkfifoしてあるので実行中に他から並行で
__echo "そだねー" > googleHome.pipe__
とかで試せます。

##ソース(同じディレクトリに並べてください
```ghpipe.js
var fifoPath;
const fs = require('fs');
process.argv.forEach(function (val, index, array){
  if ( val === '-f' && array[index + 1] != undefined) {
    fifoPath = array[index + 1];
  }
});
console.log(fifoPath);
try {
  fs.statSync(fifoPath);
} catch(err) {
  fifoPath = './googleHome.pipe';
}
// console.log('ghpipe:' + fifoPath);
const googleHomePipe = require('./googleHomePipe');
googleHomePipe.connect(fifoPath);
const twline = require('./twline');
twline.connect(fifoPath, 'user');
```

```googleHomePipe.js
module.exports = {
  connect: function(fifoPath){
    const fs = require('fs');
    const fd = fs.openSync(fifoPath, 'r+');
    const stream = fs.createReadStream(null, { fd });
    const googlehome = require('google-home-notifier');
    const language = 'ja';
    googlehome.device('Google-Home', language);

    stream.on('data', (data) => {
      var msg = data.toString().trim();
      // console.log('message:', msg);
      if (msg === 'EOF') {
        console.error('CLOSE END.');
        stream.close();
        return;
      }
      googlehome.notify(msg, function (res) {
        // console.error(res);
      });
    });

    stream.on('error', function(error) {
      console.error(error);
      throw error;
    });

  }
};
```

```twline.js
module.exports = {
  connect: function(fifoPath, filter) {
    const chalk = require('chalk');
    const fs = require('fs');
    const twitter = require('twitter');
    const client = new twitter({
        consumer_key:        '取得方法 twitter apiとかで検索してください',
        consumer_secret:     '何か他のapi利用したクライアント動かすと',
        access_token_key:    '取得してくれて',
        access_token_secret: 'ファイルに残してくれたりするのでそれ流用とかでも。',
    });
    const fifo = fs.createWriteStream(fifoPath);

    client.stream(filter, function (stream) {
      stream.on('data', function(tweet) {
        // console.log('tw: %o', tweet);
        var msg = tweet.user.name + ' ' + tweet.text.toString().trim();
        console.log(chalk.white.bgBlue(tweet.user.screen_name) + ' ' + tweet.text);
        fifo.write(msg);
      });

      stream.on('end', function() {
        console.info('END');
      });

      stream.on('error', function(error) {
        console.error(error);
        throw error;
      });
    });
  },
};
```

空き時間にちょこちょこやったので基本コピペで異常系無視でconstとvarの使い分けとかstreamとかイイカゲン過ぎますのであしからず。
twline.jsのほうでtwitter.streamのfilterを検索とかにも出来ると思いますがリクエスト走ると前のはキャンセルされちゃいますのでカブらずに最後のだけ喋る感じです。