人生リアルタイムアタック

当面はPython学習帳

Electronで簡単なFacebookアプリを作ってみた

30分でElectronのデスクトップアプリが作れるということで試しにFacebook専用アプリを作ってみた。

参考にしたページ

環境構築

$ mkdir electronic-facebook
$ cd ./electronic-facebook
$ npm install -g electron-prebuilt # Electronのインストール
$ npm init -y # package.jsonの作成

アプリの開発

やりたいこと

  • デスクトップアプリケーションとしてFacebookだけを表示する
  • 未読のメッセージがあればその未読数を表示する

くらいなので、シンプルに以下のようなファイル構成で開発する。

electronic-facebook/
├── package.json # nodeのパッケージ管理ファイル
├── main.js # メイン実行ファイル
├── index.html
├── index.css
└── badge.js

package.json

Quick Start に従いpackage.jsonを編集。

{
  "name": "electronic-facebook",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  }
}

main に指定したjsが最初に読み込まれる。Quick startに合わせてmain.jsにした。

main.js

Electron実行時に実行されるメインファイル。

'use strict';

var app = require('app');
var BrowserWindow = require('browser-window');
require('crash-reporter').start();

var mainWindow = null;
app.on('window-all-closed', function() {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('ready', function() {
  mainWindow = new BrowserWindow({width: 980, height: 780});
  mainWindow.loadUrl('file://' + __dirname + '/index.html');
  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});

ちなみに mainWindow.loadUrl('https://www.facebook.com'); とするとそのまま画面=Facebookになる。特に他要素を追加するつもりが無ければそのまま読み込んでもいいかもしれない。

index.html(とcss)

Quick Start を参考に、ElectronのViewとなるhtmlを作成する。
今回はシンプルにjs, cssを1つずつと、Facebookページをwebview要素で読み込むだけ。

<!DOCTYPE html>
<html>
  <head>
    <title>Electronic Facebook</title>
    <link rel='stylesheet' href='./index.css'>
  </head>
  <body>
    <webview id='mainWebView' src='https://www.facebook.com' autosize='on'></webview>
    <script src='./badge.js'></script>
  </body>
</html>

css<webview> のスタイルを調整する(無いと微妙なスペースが出来る)

webview {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

未読メッセージ数の取得とbadgeの表示(badge.js)

ElectronでChatworkをデスクトップアプリ化 (Webview + badge) - Qiita を参考に、未読メッセージ数の取得とbadgeの表示を行う。 FacebookもChatworkとほぼ同じtitleフォーマットなのでロジックが参考先のchatwork.jsと全く同じになってしまった...

'use strict';
var remote = require('remote');
var app = remote.require('app');

var webview = document.getElementById('mainWebView');
var title = '';
var unreadCount = 0;

// check title every second
setInterval(function() {
  title = webview.getTitle();
  var result = title.match(/\((\d+)\)/);
  if(result) {
    unreadCount = result[1];
  } else {
    unreadCount = '';
  }
  app.dock.setBadge(unreadCount);
}, 1000);

起動してみる

$ electron .

で立ち上げられます。

f:id:ShineSpark:20150902151622p:plain

ログイン後の画面はモザイク処理が面倒なので割愛。
Facebookは width: 1097px以上から友人のログイン状況のステータスバーが表示されるので幅を広げてみた方がいいかもしれない。

パッケージング

現在では maxogden/electron-packager · GitHub を利用すると簡単なようです。

$ npm install -g electron-packager

で electron-packager をインストールし、

$ electron-packager . Electronic-Facebook --platform=darwin --arch=x64 --version=0.31.2

するだけで簡単に出来てしまった。

知見

Webサイト側でrequire.jsが利用されているとnodeの require() が上書きされる

原因は ElectronでjQueryがundefinedになる - Qiita と同様。
new BrowserWindow({...}) の所でnode-integration: false を利用してもいいのだが、これではnodeのAPIが利用できずbadgeを表示できない。
今回は素直にFacebookを直に呼ぶのではなく、 <webview> で呼ぶことで対応した。

<webview id='mainWebView' src='https://www.facebook.com' autosize='on'></webview>

該当事象についてはこちらも参考: Facebook returns errors after loading through atom-shell. · Issue #1131 · atom/electron · GitHub

パッケージングについて

Webで調べてていろんなやり方が見つかった。

現時点では maxogden/electron-packager · GitHub が一番簡単だった。grunt依存もしてないし。いろんなやり方があったのはまだベストプラクティスが纏まってない段階でWebに記事を書いてくれた人が居たからだと思う。先人に感謝。

BASIC認証について

ElectronはまだBASIC認証がサポートされていない。
HTTP Basic Authentication support · Issue #1362 · atom/electron · GitHub

実は最初はRedmineとかJIRAとかの専用アプリを作ってみようとしたのだが、これで断念した。 業務で使っているITS/BTSツールは常時ブラウザに表示しっぱなしの人は多いと思うのだが、チケット起票する際って大抵他ページを開きながら起票したいケースが多く、MDIだったOperaでもないと同時表示しづらくて面倒なんですよね。

Electronだと開発コスト全然高くないので、BASIC認証サポートされたタイミングで業務用ツールを個別アプリにしまくろうと思う。

あ、今回書いたコードはこちらです。

github.com