1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

マストドンのHome TimelineをGoogle Homeにしゃべらせる

Posted at

はじめに

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がしゃべります。

a.js
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 を呼ぶための条件をつければ、特定の内容を含むトゥートのときだけ通知する、ということもできます。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?