00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Deep Links e Protocol Handler

I deep links permettono di aprire la tua applicazione Electron da URL personalizzati (es. mia-app://open/file). Questo è utile per OAuth, link condivisibili e integrazione con altre applicazioni.

Registrare un Protocollo Personalizzato

Registrazione a Runtime

const { app } = require('electron');

// Registra il protocollo 'mia-app://'
if (process.defaultApp) {
  // Durante lo sviluppo
  if (process.argv.length >= 2) {
    app.setAsDefaultProtocolClient('mia-app', process.execPath, [
      path.resolve(process.argv[1]),
    ]);
  }
} else {
  // App distribuita
  app.setAsDefaultProtocolClient('mia-app');
}

Dopo la registrazione, gli URL come mia-app://qualcosa apriranno la tua applicazione.

Deregistrare il Protocollo

app.removeAsDefaultProtocolClient('mia-app');

Verificare la Registrazione

const isDefault = app.isDefaultProtocolClient('mia-app');
console.log('Protocollo registrato:', isDefault);

Su Windows e Linux

Su queste piattaforme, l’URL viene passato come argomento della command line:

// Gestisci l'URL quando l'app è già aperta (single instance)
const gotTheLock = app.requestSingleInstanceLock();

if (!gotTheLock) {
  app.quit();
} else {
  app.on('second-instance', (_event, commandLine) => {
    // L'URL è nell'ultimo argomento
    const url = commandLine.pop();
    handleDeepLink(url);

    // Porta la finestra in primo piano
    if (mainWindow) {
      if (mainWindow.isMinimized()) mainWindow.restore();
      mainWindow.focus();
    }
  });
}

// Gestisci l'URL all'avvio dell'app
app.whenReady().then(() => {
  createWindow();

  // Controlla se l'app è stata aperta con un deep link
  const url = process.argv.find((arg) => arg.startsWith('mia-app://'));
  if (url) {
    handleDeepLink(url);
  }
});

Su macOS

Su macOS, il deep link arriva tramite l’evento open-url:

app.on('open-url', (event, url) => {
  event.preventDefault();
  handleDeepLink(url);
});

Handler Universale

function handleDeepLink(url) {
  try {
    const parsed = new URL(url);
    const protocol = parsed.protocol;  // 'mia-app:'
    const host = parsed.hostname;       // 'action'
    const pathname = parsed.pathname;   // '/param1/param2'
    const params = parsed.searchParams; // ?key=value

    console.log(`Deep link: ${host}${pathname}`);

    switch (host) {
      case 'open':
        // mia-app://open/file?path=/documenti/test.txt
        const filePath = params.get('path');
        if (filePath) openFile(filePath);
        break;

      case 'settings':
        // mia-app://settings/theme
        openSettings(pathname.slice(1));
        break;

      case 'auth':
        // mia-app://auth/callback?token=xxx
        const token = params.get('token');
        if (token) handleAuthCallback(token);
        break;

      default:
        console.log('Deep link non riconosciuto:', url);
    }
  } catch (error) {
    console.error('URL deep link non valido:', error);
  }
}

Un caso d’uso comune è il flusso OAuth:

// 1. Apri il browser per l'autenticazione
const { shell } = require('electron');

function startOAuth() {
  const authURL = 'https://provider.com/oauth/authorize'
    + '?client_id=APP_ID'
    + '&redirect_uri=mia-app://auth/callback'
    + '&response_type=code';

  shell.openExternal(authURL);
}

// 2. Gestisci il callback
function handleAuthCallback(token) {
  // Ricevi il token dal deep link mia-app://auth/callback?token=xxx
  mainWindow.webContents.send('auth:success', token);
}

Single Instance Lock

Per evitare che vengano aperte più istanze dell’app quando si clicca un deep link:

const gotTheLock = app.requestSingleInstanceLock();

if (!gotTheLock) {
  // Un'altra istanza è già in esecuzione
  app.quit();
} else {
  app.on('second-instance', (_event, commandLine) => {
    // Gestisci il deep link dalla seconda istanza
    const url = commandLine.find((arg) => arg.startsWith('mia-app://'));
    if (url) handleDeepLink(url);

    // Porta la finestra esistente in primo piano
    if (mainWindow) {
      if (mainWindow.isMinimized()) mainWindow.restore();
      mainWindow.focus();
    }
  });

  app.whenReady().then(createWindow);
}

Configurazione per la Distribuzione

Windows (electron-builder)

{
  "build": {
    "win": {
      "target": "nsis"
    },
    "nsis": {
      "perMachine": false
    },
    "protocols": {
      "name": "Mia App Protocol",
      "schemes": ["mia-app"]
    }
  }
}

macOS (Info.plist)

Con electron-builder, aggiungi nella configurazione:

{
  "build": {
    "mac": {
      "target": "dmg"
    },
    "protocols": {
      "name": "Mia App Protocol",
      "schemes": ["mia-app"]
    }
  }
}

Sicurezza

  1. Valida sempre gli URL — non fidarti dei dati nei deep links
  2. Usa HTTPS per OAuth — mai HTTP per flussi di autenticazione
  3. Limita le azioni — permetti solo azioni predefinite, non comandi arbitrari
  4. Sanifica i parametri — tratta i parametri dei deep link come input non fidato