@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
JavaScript
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