ElectronでデスクトップにOfficeアシスタントのイルカを蘇らせる

# はじめに
AIチャットボットなどが実用化されてきた昨今、その先駆けとも言える存在がタイトルにもある__Officeアシスタント__機能です。
下記の画像の様にMicroSoft Officeに現れてはユーザのサポートをしてくれる存在ですね。
（エイプリルフールに蘇ったOfficeアシスタントの[ClippyのTwitter](https://twitter.com/ClippyTheClip/status/451041565394214912)よりの引用）
昔のOfficeを使用されていた方なら馴染みがあるのではないでしょうか。
![BkJr6fyCIAEOGU_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969561/de249e05-bd13-e9cb-512e-1c527ec57811.jpeg)

愛らしいマスコット的な存在の彼らですが、残念なことにOffice2007をもって削除されてしまいました。~~アシスタントなのに邪魔なことが多かったので・・・~~

そんな彼らを2021年に蘇せるべくElectronを使ってデスクトップに降臨の儀を執り行うのが今回の趣旨です。（AIなどを作るわけではないので悪しからず）
今回はOfficeアシスタントの中でも私が特に好きだったイルカのカイル君をモチーフに作成していきます。
![kyle-icon_400x400.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969561/bad74c76-b2d6-db1c-23fb-5a66d087715a.png)
> カイル2010 Twitterアカウントより
https://twitter.com/kyle_2010

# 作成方針
- デスクトップに背景を透明化したカイル君を表示する
- アシスタントなのでWeb検索（Google検索）くらいは出来るようにする
- 「お前を消す方法」と検索するとカイル君が消える

> 「お前を消す方法」は邪険に扱われがちなOfficeアシスタントの有名なネタです。Cortanaなどでもネタにされています。
https://nlab.itmedia.co.jp/nl/articles/1705/24/news146.html
「現代に蘇るExcelイルカの悲劇　Win 10搭載「Cortana」に「お前を消す方法」と質問するとまさかの反応が」



# Electronとは
GitHub社が開発したオープンソースのソフトウェアフレームワークです。
HTML・CSS・JavaScriptといったWeb技術を用いてデスクトップアプリケーションを作ることが出来ます。
SlackやVisual Studio Codeなどに使用されていることで有名ですね。

今回Electronを採用した理由は手軽にデスクトップアプリケーションを作成できるという点と、今回の仕様の実装に必要な画面の透明化などが容易そうだった点などが挙げられます。

# 作成
## Electronのインストール
```bash
$ npm i electron -g
$ electron main.js # メインプロセスのjsを指定
```
メインプロセス・レンダラープロセスなどElectronの詳細については割愛させていただきますので、他の方が作成された参考文献の記事などをご参照ください。

## メインプロセス
昔Electronを触っていた時はNode.jsの機能をやりたい放題使用していましたがセキュリティ的に問題だったみたいですね（当然）。
今回はプロセス間通信を使って画面制御やWeb検索の実行を行っていきます。

### メイン画面
透明化・フレームレスなどの指定のためパラメータをいくつか指定していきます。
また、プロセス間通信のため「webPreferences」オプションを下記に設定しました。

```js
const {app,BrowserWindow,ipcMain} = require('electron');
const path = require('path')

// メイン画面（透明化・フレームレスなどを指定）
let mainWindow = null;
app.on('ready', () => {
  mainWindow = new BrowserWindow({
    width: 245, 
    height: 230,
    transparent: true,
    frame: false,
    resizable: false,
    maximizable: false,
    webPreferences: {
      enableRemoteModule: false,
      nodeIntegration: false,
      contextIsolation: true,
      preload: path.join(app.getAppPath(), 'preload.js')
    }
  });
  mainWindow.loadURL('file://' + __dirname + '/index.html');

  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});
```

### プロセス間通信（contextBridge設定）
上記「preload.js」の設定内容です。
今回は画面終了用のcloseとWeb検索画面起動のopenを用意します。

```js:preload.js
const { contextBridge, ipcRenderer} = require("electron");
contextBridge.exposeInMainWorld(
  "api", {
    close: () => {
      ipcRenderer.send("main_close");
    },
    open: (arg) => {
      ipcRenderer.send("sub_open", arg);
    }
  }
);
```

### プロセス間通信（メイン画面終了）
カイル君が消えるための処理です。

```js
ipcMain.on("main_close", (event) => {
  mainWindow.close();
});
```

### プロセス間通信（検索画面を開く）
引数に渡されたパラメータを検索パラメータとして渡して検索画面を開きます。

```js
ipcMain.on("sub_open", (event, arg) => {
  const subWindow = new BrowserWindow({
    webPreferences: {
      contextIsolation: true,
      enableRemoteModule: false
    }
  });
  const googleBaseURL = 'https://www.google.com/search';
  const query = '?q=' + arg;
  subWindow.loadURL(googleBaseURL + query);
});
```

## レンダラープロセス
### プロセス間通信呼び出し
検索ボタンを押下されたタイミングで入力テキストを取得し検索子画面を呼び出します。
「お前を消す方法」と入力された時に限ってはカイルくんに再び消えてもらいます。

```js
document.getElementById('btn_search').addEventListener('click', () => {
  const text = document.getElementById('text_search').value;
  if (text === 'お前を消す方法') {
    window.api.close();
    return;
  }
  window.api.open(text);
})
```

# 成果物
時を経てDesktopに降臨したカイル君です。
フリー画像を使用したため見た目が異なるのはご愛嬌。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969561/10967e85-53e0-e84f-c11b-387df76dc9c8.png)

検索した結果がこちら
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969561/d4d65dc5-05db-7e46-7c13-2d7635dbe4ff.png)

禁断の質問
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969561/ac36ceaf-55fe-8e18-323d-b6730f2a8a8b.png)

↓

・・・。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969561/28d0da7d-8ca5-6d04-0a19-cc3d055ba3e7.png)

# さいごに
今回の成果物はこちらになります。
https://github.com/kanaria42/kyle-electron

もう少し機能を追加するなりすれば実用的なアシスタントになるかもしれません。
いつかアップデートで公式のカイル君が蘇る日を夢見て今回は終了とさせていただきます。

# 参考文献
[ようこそ！Electron入門](https://qiita.com/umamichi/items/6ce4f46c1458e89c4cfc)
[ElectronでcontextBridgeによる安全なIPC通信](https://qiita.com/pochman/items/64b34e9827866664d436)
[CSSデザインジェネレータ](https://generator.web-alpha.info/fukidashi/index.php#step1)
↑吹き出し実装に使用させていただいたもの