【Electron入門】GithubのIssueを一瞬で確認できるアプリを作って業務効率化してみた #2 GithubAPI編

## はじめに
[前回](https://qiita.com/ikkei12/items/cba90ac057e8f0a9c2c5)はwindowの作成をしました。
今回はGithubAPIを導入して完成させようと思います。
長くなってしまうのでJavaScriptでDOMの作成をする部分やCSSの説明は省きます。
気になる方はコードをご確認ください！

## 完成品
option(alt) + Spaceで表示/非表示が切り替えられます。

![scc.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488042/e31df68d-1879-ca25-6ad3-950a4f87d880.gif)

## 現状
![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488042/563a9615-0192-68f9-2d24-2ed8a4468d05.gif)

## Access Tokenを生成する
それではやっていきましょう。

Githubにログインし、
`Settings > Developer settings > Personal access tokens`
と進みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488042/006d1932-afbc-e3bd-0b86-51a802c73ab9.png)


`Generate new token`を押すとtoken作成画面に進めます。

・`Note`にはtokenを識別するために用途を書きます。自分は`git-electron`としました。

・`Select scopes`でtokenの権限を選択できます。今回は`repo`の権限全てにチェックをつけます。


`Generate token`を押すとAccess Tokenが生成されるので、
**後ほど使うので、赤く囲まれている部分のAccess Tokenをコピーしておきます。**

![スクリーンショット 2020-11-21 12.13.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488042/1b1e8c25-6994-4690-73e5-5fb7b29d64f6.png)

## AccessTokenを使ってAPIにアクセスする

実際にGithubAPIを叩いてみます。

通信には`axios`を使用しました。
Tokenの管理には`dotenv`を使用しました。

1 . アプリのルートパスで`.env`ファイルを作成して以下のように編集します。

```:.env
GH_ACCESS_TOKEN=[先ほどコピーしたAccess Token]
GH_BASE_URL=https://api.github.com
```

2 . main.jsに以下を追記して`.env`ファイルを読み込みます。

```javascript:main.js
require("dotenv").config({ path: __dirname + "/.env" });
```

※ AccessTokenは外部に見られたくないので、Githubで公開する際には`.gitignore`を作成してremoteに送らないようにしましょう。

```:.gitignore
.env
```

<br>
3 . axiosを拡張する

axiosの設定を共通化するために拡張します。
自分は`plugins`ディレクトリを作成して、配下に`axios.js`を作成しました。

```javascript:plugins/axios.js
const axiosBase = require("axios");

const axios = axiosBase.create({
  baseURL: process.env.GH_BASE_URL,
  headers: {
    Authorization: "Bearer " + process.env.GH_ACCESS_TOKEN,
    "Content-Type": "application/json",
  },
});
module.exports = axios;
```

これ以降、axiosを呼び出すときはこのaxios.jsを呼び出します。

これでGithub APIを呼び出す準備は整いました！


## フロント(Window)からAPIを呼び出す

Electronには`メインプロセス`と`レンダラープロセス`があります。

メインプロセス内(ここで言うmain.js)でBroeserWindowインスタンスを作成し、そのBroeserWindowインスタンスがレンダラープロセス内でWebページ(html)を表示します。
[公式ドキュメント](https://www.electronjs.org/docs/tutorial/quick-start#main-and-renderer-processes)

よってhtmlから呼び出したJavaScriptなどはレンダラープロセスで実行する事になります。

ここで困ることが一点あります。
`main.js`はメインプロセス上で動くので、Node.jsの文法が使えますが、レンダラープロセスでは使えません。

`require`などNode.js上で使えるメソッドをフロントからの要求に応じて使えるようにするには、
contextBridgeを使って、メイン⇔プロセス間の通信をセキュアにする必要があります。
<br>
詳しく知りたい方は以下の記事がうまくまとまっていると思うので参考にしてみてください！

[ElectronでcontextBridgeによる安全なIPC通信 - Qiita](https://qiita.com/pochman/items/64b34e9827866664d436)
[ElectronでcontextBridgeによる安全なIPC通信（受信編） -Qiita](https://qiita.com/pochman/items/62de713a014dcacbad68)


### contextBridgeを実装する

contextBridgeを使用する為の`preload.js`をルートディレクトリに作成します。

```javascript:preload.js
const { contextBridge } = require("electron");

contextBridge.exposeInMainWorld("api", {
  github: {
    getIssues: () => {
      // メインプロセスで行いたい処理を書く
      const axios = require("./plugins/axios");
      axios
        .get("/issues")
        .then((res) => {
          console.log(res);
        })
        .catch((e) => console.log(e));
    },
  },
});
```

次にmain.jsを修正して、BrowserWindowでpreload.jsを読み込むよう設定します。

```javascript:main.js
  const win = new BrowserWindow({
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      preload: __dirname + "/preload.js",
    },
    // .....省略......
  })
```
最後にindex.htmlにscriptタグと発火用のボタンを追加して、preload.jsで定義した関数を呼び出せるようにします。

```html:index.html
  <body style="-webkit-app-region: drag">
    <div style="background: #fff; height: 300px">
      <h1>Hello World!</h1>
      <button onclick="fetchAPI()">get issues</button>
    </div>
  </body>
  <script>
    function fetchAPI() {
      window.api.github.getIssues();
    }
  </script>
```

ボタンを押して、Electron上でDeveloper toolを開くとIssueのデータが取れていると思います！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488042/aed6eb0e-0136-5ebf-5402-c9a865a86ee4.png)


デスクトップアプリとして使いたい場合は、`npm run build`でelectron-builderが起動し、`dist`配下にアプリが生成されます。

DOMの生成やCSSはリポジトリを参考にしてみてください！


## 最後に
今回はElectroとGithubAPIを組み合わせて業務効率化アプリを作ってみました。

かなり手軽にデスクトップアプリを作成することができた一方、いくつか制限もあったので大規模開発での導入には検討が必要かもしれません。(と言ってもVSCodeなどもelectronで開発されているのである程度安心していいと思っています)

こんな感じで週1~2でアウトプットを記事にしていこうと思います。是非LGTM、フォローの方お願い致します！

Twitterのフォローもお願い致します！
https://twitter.com/1keiuu