MattermostをElectronでデスクトップアプリ化した

最近は面白いと思ったものを気が向いた時になんとなく触る、ということが多いです。

最近MattermostというWebベースのチャットアプリを使い始めました。 (Dockerで公開されているというのは本当に便利ですね。ちょっと試してみるためだけにサーバーの環境を触らなくて済むし、自力で環境を整える手間が省けます)

www.moongift.jp

Webアプリの常としてブラウザを開いていないと使えないので、うっかりウィンドウを閉じてしまわないよう意外に気を使います。 Chromeでタスクバーにショートカットを作れば見た目上は別アプリにできるんですが、Macではこの方法が使えないので地味に不便でした。

ElectronでChatworkをデスクトップアプリ化 (Webview + badge) - Qiitaをたまたま見て「これだ」と思ったのでElectronを使ってMattermostのデスクトップアプリを作ってみました。

github.com

Electron

ElectronはGitHubが公開している、デスクトップアプリを作るためのフレームワークです。 有名なところではAtomエディタやVisual Studio Codeで使われています(と言うか元々Atomのために作られた)。

Macで動作することと自分がNode.jsを一応使えたことがElectronを使った理由として大きいです。

基本的な実装

単にWebViewで表示するところまではElectronのチュートリアルと、Qiitaの記事を見たらあっさりできました。はっきり言ってコピペ。 HTMLに関しては最近まで「frameタグ」とか「右クリック禁止」のレベルで止まっていたのですが、今回はWebViewタグ一発なのであまり問題になりませんでした。

未読の取得

未読があることが分かればよいので、unread-titleクラスの数(=未読チャンネルの数)を数えます。 WebViewの中でDOMを取得する必要があるので、WebViewのpreload属性でロードしておきます。

// webview/mattermost.js
var ipc = require('ipc');

ipc.on('retrieveUnreadCount', function(){
  var unreadCount = document.getElementsByClassName('unread-title').length;
  ipc.sendToHost('retrieveUnreadCount', unreadCount);
});

件数を取得したら、Windowsではタスクバーにオーバーレイアイコンを、OS XではDockにバッジを表示します。

f:id:yuya-oc:20160206211625p:plain f:id:yuya-oc:20160206211639p:plain

常駐化

ウィンドウを閉じてしまうと当然DOMは取れず、未読件数も取得できないので対処が必要です。 mainWindowのcloseイベント発生時に、ウィンドウを最小化または非表示にしてやります。 OS XではDockアイコンをクリックした場合にappのactivateイベントでmainWindowを再表示します。

アプリの終了はCtrl+QまたはCommand+Qです。 appのbefore-quitイベントでwillAppQuitをtrueにして、ウィンドウを閉じられるようにします。

// main.js
mainWindow.on('close', function(event){
  // Minimize or hide the window for close button.
  if(!willAppQuit){ // avoid [Ctrl|Cmd]+Q
    event.preventDefault();
    switch (process.platform) {
      case 'win32':
        mainWindow.minimize();
        break;
      case 'darwin':
        mainWindow.hide();
        break;
      default:
    }
  }
});

app.on('activate', function(event){
  mainWindow.show();
});

app.on('before-quit', function(){
  willAppQuit = true;
});

作ってみて

WindowsだとElectronがHTML5のデスクトップ通知をしてくれません。 ElectronのIssueに挙がっているのですが、どうなるかはわかりません。 せめて通知が来たことをイベントを拾えるようになって欲しいところです。

Electronのチュートリアルを読み始めてからWebViewでMattermostを表示して未読件数を取得するところまで、でだいたい3時間程度なので、かなり手軽にアプリを作れてしまって驚いています。 C#(フォーム, XAML)とかWin32C++ってなんとなく気合い入れないと作らないですし(しかもWindowsだけ)、Electronは手軽に作れることが重要な便利ツールにこそ良さそうです。