I would like to be able to open a deep link and take that protocol url and login with it. I have successfully got the electron app to open from the deep link but I can't seem to get the url or parameter from the deep link. I followed the tutorial from https://www.electronjs.org/docs/latest/tutorial/launch-app-from-url-in-another-app but I wasn't able to get it to work on ubuntu. In the tutorial it when you open from deep link it opens a dialog box but the open-url listener isn't getting called. Is there something I am missing to getting the open-url to work on linux.
Heres my index.ts
import {app, BrowserWindow, ipcMain, powerMonitor, Menu, Tray, contextBridge, ipcRenderer, shell, dialog} from 'electron'
import path from "path"
import pushReceiver from "electron-fcm-push-receiver"
let mainWindow: BrowserWindow | null;
let deeplinkingUrl: any = null
try {
if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient('proto', process.execPath, [path.resolve(process.argv[1])])
}
} else {
app.setAsDefaultProtocolClient('electron-fiddle')
}
} catch(e) {
logEverywhere(e);
}
const hasLock = app.requestSingleInstanceLock()
if (!hasLock) {
app.quit()
} else {
app.on('second-instance', (ev,argv) => {
logEverywhere(ev)
logEverywhere("Second instance was opened")
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}
if (process.platform == 'win32') {
// Keep only command line / deep linked arguments
deeplinkingUrl = argv.slice(1)
}
logEverywhere(argv.slice(3))
//mainWindow?.loadURL(argv.slice(3))
logEverywhere('app.makeSingleInstance# ' + deeplinkingUrl)
})
app.on('open-url', (event, url) => {
event.preventDefault()
deeplinkingUrl = url
dialog.showErrorBox('Welcome Back', `You arrived from: ${url}`)
logEverywhere("testing" +url)
})
app.whenReady().then(() => {
const w = new BrowserWindow({
width: 1366,
height: 768,
webPreferences: {
preload: path.join(__dirname, './preload.js'),
nodeIntegration: true,
enableRemoteModule: true
} as any,
});
w.removeMenu();
try {
w.loadURL("https:local-host");
mainWindow = w;
pushReceiver.setup(w.webContents);
logEverywhere("Loaded Why test");
w.on('closed', function () {
mainWindow = null;
});
const tray = new Tray(path.join(__dirname, "icon.png"), "asd546sdf-7dea-4b73-964b-6s5dfscsasdf");
tray.setToolTip("Test Site");
tray.setContextMenu(Menu.buildFromTemplate([
{
label: "Open",
click: () => {
w.show()
}
},
{
label: 'Dev Console',
click: () => {
w.webContents.openDevTools()
},
},
{
label: "Reload",
click: () => {
w.webContents.reloadIgnoringCache()
}
},
{
label: "Quit",
click: () => {
app.quit()
}
}
]));
tray.setTitle("Test Site");
tray.on("click", ev => {
w.show()
});
// w.webContents.send("asdf", 2)
} catch (e) {
console.error(e);
}
});
(global as any).goToForeground = () => mainWindow?.show()
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit();
}
});
ipcMain.on('app_version', (event: Event) => {
(event as any).sender.send('app_version', {version: app.getVersion()});
});
ipcMain.on('goToForeground', (event) => {
console.log("Showing")
mainWindow?.show()
})
powerMonitor.on('shutdown', (ev: Event) => {
ev.preventDefault()
app.quit()
})
}
function logEverywhere(s: any) {
console.log(s)
if (mainWindow && mainWindow.webContents) {
mainWindow.webContents.executeJavaScript(`console.log("${s}")`)
}
}
// Handle window controls via IPC
ipcMain.on('shell:open', () => {
const pageDirectory = __dirname.replace('app.asar', 'app.asar.unpacked')
const pagePath = path.join('file://', pageDirectory, 'index.html')
shell.openExternal(pagePath)
})
Heres my package.json file
{
"name": "test-electron",
"version": "1.0.0",
"description": "Electron wrapper",
"main": "dist/index.js",
"scripts": {
"start": "tsc && electron-forge start",
"package": "electron-forge package",
"make": "electron-forge make",
"publish": "electron-forge publish",
"lint": "eslint --ext .ts ."
},
"author": "Test",
"license": "ISC",
"config": {
"forge": {
"packagerConfig": {
"protocols": [
{
"name": "electron-fiddle",
"schemes": ["electron-fiddle"]
}
]
},
"makers": [
{
"name": "@electron-forge/maker-squirrel",
"config": {
"name": "my_new_app"
}
},
{
"name": "@electron-forge/maker-zip",
"platforms": [
"darwin"
]
},
{
"name": "@electron-forge/maker-deb",
"config": {
"mimeType": ["x-scheme-handler/electron-fiddle"]
}
}
]
}
},
"devDependencies": {
"@electron-forge/cli": "^6.0.0-beta.63",
"@electron-forge/maker-deb": "^6.0.0-beta.63",
"@electron-forge/maker-rpm": "^6.0.0-beta.63",
"@electron-forge/maker-squirrel": "^6.0.0-beta.63",
"@electron-forge/maker-zip": "^6.0.0-beta.63",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"electron": "^17.1.1",
"electron-fcm-push-receiver": "^2.1.7",
"typescript": "^4.6.2"
},
"dependencies": {
"electron-squirrel-startup": "^1.0.0",
"electron-updater": "^4.6.5",
"@electron-forge/cli": "^6.0.0-beta.63",
"@electron-forge/maker-deb": "^6.0.0-beta.63",
"@electron-forge/maker-rpm": "^6.0.0-beta.63",
"@electron-forge/maker-squirrel": "^6.0.0-beta.63",
"@electron-forge/maker-zip": "^6.0.0-beta.63",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"electron": "^17.1.1",
"electron-fcm-push-receiver": "^2.1.7",
"typescript": "^4.6.2"
}
}
Figured out what was wrong. The documentation has the linux and mac as the same but linux is different or at least on debian it is. The documentation says to put into the app.on('open-url', (event, url)
event but this doesn't work for linux or at least it didn't work for me.
Apparently or what I found that you have to grab it from the arguments from when it is called by the operating system to open. So what I did was in the app when ready event is finished i did:
app.whenReady().then(() => {
const argv = process.argv
const lastArg = argv[argv.length-1]
});
So that gets the parameter from the deep link if you don't have the app running if the app is running already you then need to get the arg from using the on second instance event like so:
app.on('second-instance', (ev:Event, argv: string[], workingDirectory:string, additionalData) => {
const lastArg = argv[argv.length-1]
if (lastArg.startsWith("protocal://")) {
onDeepLink(argv[argv.length-1])
}
I think this is also how it works with windows as well but I need to do more testing for that.