UNPKG

@smj0x/homebridge-shortcuts-buttons

Version:

Run any Apple Shortcut with just the tap of a button, and execute a custom unix command (or another shortcut!) after completion to handle its success/failure, using x-callback-url.

98 lines 4 kB
import { exec } from 'child_process'; import * as fs from 'fs'; import * as SSH2 from 'ssh2'; export class ShortcutsRunner { log; sshConfig; constructor(log, sshConfig) { this.log = log; this.sshConfig = sshConfig; } async runShortcut(shortcutName) { if (this.sshConfig && this.sshConfig.enabled) { return this.runShortcutViaSSH(shortcutName); } else { return this.runShortcutLocally(shortcutName); } } runShortcutLocally(shortcutName) { return new Promise((resolve, reject) => { const cmd = `shortcuts run "${shortcutName}"`; this.log.debug(`Running local command: ${cmd}`); exec(cmd, (error, stdout, stderr) => { if (error) { this.log.error(`Error executing shortcut locally: ${error.message}`); this.log.debug(`stderr: ${stderr}`); reject(error); return; } this.log.debug(`Shortcut executed successfully: ${stdout}`); resolve(); }); }); } runShortcutViaSSH(shortcutName) { return new Promise((resolve, reject) => { if (!this.sshConfig) { reject(new Error('SSH configuration is not provided')); return; } const { host, port, username, privateKeyPath, passphrase } = this.sshConfig; try { // Read private key const privateKey = fs.readFileSync(privateKeyPath); const conn = new SSH2.Client(); conn.on('ready', () => { this.log.debug(`SSH connection established to ${host}`); const cmd = `shortcuts run "${shortcutName}"`; this.log.debug(`Running command on remote host: ${cmd}`); conn.exec(cmd, (err, stream) => { if (err) { conn.end(); this.log.error(`SSH exec error: ${err.message}`); reject(err); return; } let stdoutData = ''; let stderrData = ''; stream.on('close', (code) => { conn.end(); if (code !== 0) { this.log.error(`Remote command failed with code ${code}`); this.log.debug(`stderr: ${stderrData}`); reject(new Error(`Command exited with code ${code}`)); return; } this.log.debug(`Remote shortcut executed successfully: ${stdoutData}`); resolve(); }); stream.on('data', (data) => { stdoutData += data.toString(); }); stream.stderr.on('data', (data) => { stderrData += data.toString(); }); }); }); conn.on('error', (err) => { this.log.error(`SSH connection error: ${err.message}`); reject(err); }); conn.connect({ host, port, username, privateKey, passphrase: passphrase || undefined, }); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); this.log.error(`Failed to establish SSH connection: ${errorMessage}`); reject(error); } }); } } //# sourceMappingURL=shortcutsRunner.js.map