ブラウザ(Chrome)のURL Schemeからデスクトップアプリを起動する

2021年08月04日
2021年09月03日

TL;DR

{APP_SCHEME}:///で開きます。

  • Slack slack:///
  • Asana asanadesktop:///

Slack App Open ※デスクトップアプリがないと開きません。

ちなみにChromeアプリは、chrome://appsで管理できます。

アプリのインストールと管理-Chromeウェブストアのヘルプ

環境

  • Electron
  • Vue.js

調査内容

SlackやNotionなどのデスクトップアプリは、ログインする際に、ブラウザに移動しログインさせた後にデスクトップアプリに戻ります。

これらの動きについて調査します。

上記を調査するにあたって3つにスコープを分けました。

  • 1.Electronからブラウザ遷移させる
  • 2.ブラウザからデスクトップアプリ(Electron)を開く指示を出す
  • 3.ELectronを開いた時に値を受け取れるかを調べる

それぞれ解決策が見えたので共有します。

デスクトップアプリのログインフロー

基本的な処理の流れは、以下のようになります。

  • 1.ログイン画面を表示(デスクトップアプリ)
  • 2.デスクトップアプリからブラウザに移動(デスクトップアプリ)
  • 3.ブラウザで認証する(ブラウザ)
  • 4.ブラウザからデスクトップアプリを開く(ブラウザ)

Electronからブラウザ遷移させる

How do I open a url from on default OS browser?

下記を任意のAPIで呼び出します。

js
const shell = require('electron').shell shell.openExternal('http:localhost:4000/login') // ログインページ

この際に、queryを入れることによって、デスクトップアプリからのログインかを判別します。

js
const shell = require('electron').shell shell.openExternal('http://localhost:8080/login?desktop_login') // desktop_loginで判別する

ブラウザからデスクトップアプリ(Electron)を開く指示を出す

js
window.location.href = 'slack:///'

認証時のアクセストークンなどを扱う場合は、 asanadesktop:///desktop_start_session?external_auth_token=xxxx&email=xxxx@xxxx.xxx のようなリンクになるかと思います。これはAsanaの例です。 (試していないので注視してください!)

デスクトップアプリのSchemeを定義する

nklayman/vue-cli-plugin-electron-builder: Easily Build Your Vue.js App For Desktop With Electronを使用しています。

通常のelectron-builderであれば、Common Configuration - electron-builderを参照してください。

vue.config.js
module.exports = { pluginOptions: { electronBuilder: { builderOptions: { protocols: { name: 'App', schemes: [ 'appdesktop' // ここがschemeになる ] }, // ついでにアイコン設定 mac: { icon: 'src/assets/app.icns' }, win: { icon: 'src/assets/app.ico' } } } }, }

nom run electron:buildを実行すると、dist_electron/builder-effective-config.yamlが生成されるので、こちらで正しく設定されるか確認してください。

正しく設定できている場合、dmgを解凍して、Chromeでappdesktop:///を叩くと、起動できるはずです。

electron:serveの場合のScheme定義

json
"electron:serve": "vue-cli-service electron:serve --mode development",

electron:serveの場合は、vue.config.jsで設定したProtocol Schemeがうまく働かないので、下記のように設定してみてください。

js
app.setAsDefaultProtocolClient('appdesktop')

ELectronを開いた時に値を受け取れるかを調べる

下記でScheme起動したURLを受け取ることができます。ここでTokenなどを受け取りましょう。 遷移などは、ipcRenderer.on()を使用し発火させます。

js
app.on('open-url', async (event, url) => { console.log('event:', event) console.log('url:', url) // Focus if (win) { if (win.isMinimized()) win.restore() win.focus() } })