LoginSignup
0
1

Google拡張機能と連携できるElectronベースのアプリを作った(Electronで別アプリからアクセスできるローカルサーバーを開く)

Last updated at Posted at 2024-05-17

はじめに

色々な経緯があり、Google拡張機能でWindows標準の通知機能を使っていました。

  • 手軽に呼び出せる
  • 色々な画面を開いていたりバックグラウンドでも通知ができる
  • 履歴が残る
  • うるさすぎない

と、かなりいいことづくめなのですが・・。
欠点があります。

それは、

  • メインウィンドウにしか表示させられない
  • ゲーム中などは通知がオフになる
    • 設定でオンには出来るが、その場合ゲームの邪魔になるかゲームをサブウィンドウに移したりしないといけない
    • ゲームが起動される画面は基本的に毎回メインウィンドウなので、開くたびに動かすのが面倒くさい(win + shift + 矢印でいけるとしても面倒くさい!!!!!)
    • Windows11だと、通知バーをサブウィンドウに移すことが出来ない
      Notifications on second monitor in Windows 11 - Microsoft Community

ということです。

これがあまりにもしんどすぎたので、連携出来るアプリを作成しました。

連携方法

JavaScriptから別のアプリケーションに連携する方法が一つしか思いつかなかったので、ローカルにサーバーを立てて、POSTリクエストを送るという形で実装しました。

main.js
// Electronアプリ
const http = require('http');

// メインとなるウィンドウを作成
let win;
app.whenReady().then(() => {
    win = new BrowserWindow({
        width: 600
		,height: 800
		,webPreferences: {
			preload: __dirname + '/preload.js'
		}
    });

    win.loadFile('index.html');
});

// 下記鯖立て処理
const port = 8081; // ここは空いているポート番号なら好きなもので良い

http.createServer((req, res) => {

    // うまく動かなかったときに拾ってきたヘッダーなので、もしかしたら問題あるかも。要確認
    const headers = {
        'Access-Control-Allow-Origin': '*', /* @dev First, read about security */
        'Access-Control-Allow-Methods': 'OPTIONS, POST, GET', // 動作確認用にGETも含んでいるが、今回のケースであれば正直使わない
        'Access-Control-Max-Age': 2592000, // 30 days
        'Access-Control-Allow-Headers': 'content-type' // Might be helpful
    };

    if (req.method === 'OPTIONS') {
        res.writeHead(204, headers);
        res.end();
        return;
    }

    if (['GET', 'POST'].includes(req.method)) {
        let body = '';
        req.on('data', chunk => {
            body += chunk;
        });
        req.on('end', () => {
            res.writeHead(200, headers);
            res.end('OK');

            win.webContents.send('add-alert', JSON.parse(body));
        })
        return;
    }

}).listen(port);
extension.js
// Google拡張機能
function sendAlert(imgSrc, message) {
	const req = new XMLHttpRequest();
	req.open('POST', 'http://localhost:8081');
	req.setRequestHeader('Content-Type','application/json');

    // 通知の画像と文言を送信
	req.send(JSON.stringify({
		img: imgSrc
		,text: message
	}));
}

詰まった点

Requestの受付がうまくいかなかった

Request周りの理解が浅く、「POSTで投げれば内容を受け取れる」程度の認識だったのですが、少なくとも今回のケースに関しては下記のような流れのようです。

  1. 「OPTIONS」形式でRequestを受け、問題がないか確認する
    (204を返すことで問題なしとしている)
  2. 「POST」形式でのRequestが複数回送られてくる
    そのため、dataをつなぎ合わせる必要がある
  3. 最後にendが送信されて、リクエスト処理が終了する

参考:

受け取ったdataの型が不正

きちんとJSON.stringifyJSON.parseをしていないのが悪かったです。
スミマセン。

正直Tauriで作りたかった → 作れた

のですが、Tauriでローカルサーバーを立てる方法がわからず・・。

このプラグインを使うことで立てられるっぽいのですが、理解が浅いこともありうまく動作しませんでした。
利用しているサンプルも全く見つからなかった。

どなたか詳しい方おられましたら教えて下さい。

作れました。

おわりに

そもそも、もっと簡単な方法があったんじゃないか?という疑問が消えないのですが、とりあえず出来たので良しとします。
また一つ学びました。

0
1
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
0
1