はじめに
Google Home miniを半額で手に入れたので、何か使ってやろうと思い、しゃべらせてみることにしました。もうすでに誰かがやっている気もしますが、Mastodonのタイムラインの内容をしゃべらせてみます。
環境
- Ubuntu Server 17.10
- Node.js
Debian系のディストリビューションなので利用しました。Raspberry Piとかも同じDebian系なので同じようにできるのではと思います。
Google Homeにしゃべらせる
google-home-notifierというライブラリがすでにあるので、使いました。
非常に簡単に使えます。
google-home-notifier インストール
導入はgoogle-home-notifierのREADMEに書いてあるとおりですが、まずNode.jsと必要なライブラリをインストールします。
$ sudo apt-get install nodejs npm git-core libnss-mdns libavahi-compat-libdnssd-dev
その後、npmを使ってインストールします。
$ npm install google-home-notifier
READMEの After npm install に書かれている通り、一部修正します。
node_modules/mdns/lib/browser.js というファイルの
Browser.defaultResolverSequence = [
rst.DNSServiceResolve(), 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo()
, rst.makeAddressesUnique()
];
この部分を、下記のように書き換えます。
Browser.defaultResolverSequence = [
rst.DNSServiceResolve(), 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo({families:[4]})
, rst.makeAddressesUnique()
];
google-home-notifier の利用
使うのはしゃべらせる機能だけなので、こんな感じです。
const googlehome = require('google-home-notifier');
var m = 'しゃべらせる内容';
googlehome.device('Google-Home','ja');
googlehome.notify(m);
家のGoogle Homeは「Google-Home」で始まる機器名だったようなので、上記でデバイスを検索できています。
実行すると、通知音の後、mに入れた文字列をしゃべってくれます。
MastodonのHome Timelineの取得
StreamingAPIがあるようなので、それを使います。
まず、WebSocketを利用できるようにします。
npm install websocket
次に、Mastodonにクライアントの登録、およびアクセストークンを取得します。こちらはすでに他の方の優秀な記事がWeb上にあるので、見てください。
アクセストークンを取得したら、WebSocketで接続します。トゥートが来たらmessageの受信が行われます。eventプロパティが'update'のものが新規トゥートです。
const WebSocket = require('websocket').w3cwebsocket;
const access_token = '取得したアクセストークン';
const host = 'Mastodonのホスト名。例えばmstdn.jpなど';
var ws = new WebSocket('wss://' + host + '/api/v1/streaming?access_token=' + access_token + '&stream=user');
ws.onmessage = (message) => {
var d = eval('(' + message.data + ')');
var p = eval('(' + d.payload + ')');
if (d.event == 'update') {
// p.contentがトゥートの内容
}
}
HTMLタグ除去
p.contentはHTMLのフラグメントとなっているようなので、しゃべらせるにはHTMLタグは不要です。striptagsなるライブラリがあるので、それを使って除去したりすると良いです。
$ npm install striptags
const striptags = require('striptags');
// p.contentに対してstriptags()を実行する
組み合わせる
後は、MastodonのHome Timelineのトゥートを受信した際に、Google Homeにしゃべる内容を伝えれば良いです。
ws.onmessage = (message) => {
var d = eval('(' + message.data + ')');
var p = eval('(' + d.payload + ')');
if (d.event == 'update') {
var m = striptags(p.content);
googlehome.notify(m);
}
}
まとめ
これまでのプログラムをa.jsとかに保存して、Node.jsから実行すると、MastodonにWebSocketで接続して、Home Timelineに対するトゥートがあるまで待ちます。トゥートが来たらgoogle-home-notifierを利用してGoogle Homeがしゃべります。
const googlehome = require('google-home-notifier');
const WebSocket = require('websocket').w3cwebsocket;
const striptags = require('striptags');
const access_token = '取得したアクセストークン';
const host = 'Mastodonのホスト名。例えばmstdn.jpなど';
var ws = new WebSocket('wss://' + host + '/api/v1/streaming?access_token=' + access_token + '&stream=user');
ws.onmessage = (message) => {
var d = eval('(' + message.data + ')');
var p = eval('(' + d.payload + ')');
if (d.event == 'update') {
var m = striptags(p.content);
googlehome.notify(m);
}
}
$ node a
応用
ws.onmessage の中で googlehome.notify を呼ぶための条件をつければ、特定の内容を含むトゥートのときだけ通知する、ということもできます。