Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

はじめに

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

ht164
サンデープログラマーです。 Twitter: @ht164 Mastodon: @ht164@mstdn.ht164.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away