3.5.5 • Published 3 months ago

@smj0x/homebridge-shortcuts-buttons v3.5.5

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
3 months ago

verified-by-homebridge NPM Version GitHub Actions Build Status GitHub Actions CodeQL Status Codacy grade Codacy coverage semantic-release: angular Commitizen friendly Dependabot

Features highlights

  • Run your Apple Shortcuts directly from your native Home app (or any HomeKit compatible integration).
  • Optionally, choose a custom callback command (even another shortcut) to execute once your shortcut completes (success/failure/cancel), leveraging an integrated x-callback-url server.
  • Choose to display your shortcuts buttons as Outlets or Switches.
  • All via UI plugin configuration, no other setup required.
  • Super fast and light, zero runtime package dependencies.
  • Execute shortcuts locally or on a remote macOS machine via SSH

How does it look like

The screenshots below give you an idea of how the end result may look like on an iOS Home app. The different variations of UI depend on the values you choose for the Display buttons as option in the plugin configuration form, and for the Show as single tile / Show as separate tiles option in the Accessory Settings on the Home app.

Bear in mind that in order to obtain a result similar to the screenshots above, you may have to add a few shortcuts buttons in the config first. E.g. by default Apple Home won't display the cute "power on" round button for a single outlet service, rather will display it instead as an actual outlet on the room view and as a switch on the accessory view.

How it works

  1. When you tap the button/switch, the plugin executes a command on the machine where Homebridge is running which runs the relevant Apple Shortcut. The button/switch then automatically toggles back off after a moment.

    There are no restrictions on the content of the shortcuts to run, including ones running scripts over SSH on other hosts. The plugin has no role in this, as it only instructs Shortcuts to run them via native url schema.

  2. If you left enabled the option Enable Callback Command (see description below), the plugin will inform Shortcuts to give a signal back once the shortcut execution is completed.

    This is done using the x-callback-url standard, which effectively appends to the shortcut execution request the instructions on what to do when it succeds, fails, or is canceled.

  3. Once the shortcut has run, Shortcuts will invoke a callback in this plugin, indicating the status of the execution and the result if any. When the plugin receives the callback request it runs the relevant command (either the default callback command or a custom one if provided, see below).

    This is possible because the plugin includes a very light http server running locally within Homebridge, which receives the callback from Shortcuts and determines the next command to run. The two actors in the data flow are independent and communicate only via url schemas; this removes the need for any active polling or scheduled tasks. Also, the plugin's server issues a dedicated single-use authorization token for each interaction with Shortcuts, making it more difficult for things to get messy.

Configuration

FieldTypeDefaultDescription
Namestring"ShortcutsButtons"Display name of the platform bridge.
Accessory Namestring"Shortcuts"Display name of the platform accessory.
Display buttons as"Outlet" \| "Switch""Outlet"Display the shortcuts buttons as Outlets or as Switches. See the related documentation for a visual preview of the two options in the Apple Home app.
Shortcuts buttonsarray-Add a new item to this list for every Apple Shortcut you want to be able to launch.The machine running Homebridge must have access to every shortcut listed here (i.e. the macOS user must be logged into the iCloud account where the shortcuts are stored). If you change the name of a shortcut from the Shortcuts app remember to update it here too.
↳ Button titlestring-A title to display for this button.
↳ Shortcut namestring-The name of the Apple Shortcut to launch, as displayed in your Shortcuts app.
Enable CallbackbooleantrueThe plugin will wait for the shortcut to complete its run, and will execute a callback action of your choice.
Callback Type"Default (display notification)" \| "Custom unix command" \| "Shortcut name""Default (display notification)"With the default option, after the shortcut completion, a notification with the outcome of the shortcut run is displayed on the host running Homebrige.If you choose to customize the callback behaviour, you have two choices: use any unix command that your host is able to execute, or just use another shortcut to handle the callback if you like. Depending on your choice, you must complete the next field accordingly.Please see the related documentation for more detail.
Custom callback command / callback shortcut namestring-Either a unix command or the name of a shortcut to run, depending on the value selected in the previous field. In the former case, all the content of the field will be treated as a command and executed: in the latter, this field expects just the plain name of the shortcut as displayed in the Shortcuts app. If you left the previous field on the default value, any text inserted here will be ignored.You can also read input parameters from your custom command/shortcut. Please see the related documentation for more detail.
Custom callback command timeoutnumber5000The time in milliseconds that the x-callback-url server should wait for the callback command execution to complete before timing out.
Callback Server Hostnamestring"127.0.0.1"IPv4 address or hostname to expose the internal x-callback-url http server (must be accessible from a browser on the machine running Homebridge).
Callback Server Portnumber63963A free port number for the internal x-callback-url HTTP server.
Callback Server Protocol"http" \| "https""http"If you access other Homebridge services (e.g. UI) behind a reverse proxy with TLS certificate installed, you may want to access the x-callback-url server via https as well.
Execute shortcuts via SSHboolean-Enable this to run shortcuts on a remote macOS machine via SSH
SSH Hoststring-Hostname or IP address of the remote macOS machine
SSH Portnumber22SSH port (default: 22)
SSH Usernamestring-Username for SSH authentication
SSH Private Key Pathstring-Path to the SSH private key file
SSH Private Key Passphrasestring-Passphrase for the SSH private key (if required)

Callback command

As mentioned in the configuration documentation above, there are three options available to handle the callback following a shortcut execution:

Default (display notification)

By default, a native notification with a brief summary on the shortcut result is displayed on the host machine running Homebrige (with sound effect Glass for success and Sosumi for failure). The handler for this behaviour is delivered as HomebridgeShortcutsButtons - Notify Shortcut Result.app (which is copied into the /bin directory of the distributed npm package).
For it to run you will have to approve a couple of permissions requests the first time it runs (one to display notifications, one to access shortcuts results in order to print the summary in the notification body).

Custom unix command

If you choose to manually write a custom callback script, everything you input in the command field will be passed over to node child_process.exec, which will try to execute it in a subshell. Your input can be directly some inline code, or it can be code that runs a file on your machine containing a more elaborate script.
The stdout/stderr generated by your command will be propagated onto the top shell (respectively with Logger.debug/error) which is buffered on your Homebridge UI.

Environment variables

In your command you have at your disposal the following environment variables which give you contextual information about the shortcut which triggered the callback:

VariableTypeNotes
SHORTCUT_NAMEstringName of the run shortcut
SHORTCUT_STATUS"success" \| "error" \| "cancel"Cancel: manually stopped
SHORTCUT_RESULTstring \| undefinedOnly on success status
SHORTCUT_ERRORstring \| undefinedOnly on error status

Shortcut

For some it might be easier to just use another shortcut to handle the actions to perform on completion of the initial shortcuts configured to run on buttons press. You could even have the same shortcut handling its own error status, for example in case of operation that can be retried (and with the input variables provided - see below - it would be easy to distinguish a standard run from a retry one, for instance). Just be wary of infinite loops.
Remember to only insert in the custom command field the shortcut name as it appears in the Shortcuts app, same as for the shortcuts names configured for the homekit buttons above.

When it comes to passing relevant variables to the callback shortcut, the situation it's not as easy as the previous case. Shortcuts only accept one single text input when called via url schema. Luckily, we can encode a dictionary (base_64) of the variables on the server so it can be passed as a single input parameter to the shortcut. Then from there we can decode it and transform it back into a dictionary ready for consumption within the callback shortcut. Here is an example of shortcut with the mentioned steps:

The key point is to add first the Get text from input action, specifying Shortcut Input as source. This will automatically add the Receive block on top. Note that it is perfectly fine and expected to leave the instruction as Receive No input from Nowhere: the text input coming from url schema will still be passed in.
I included in the repository a copy of the same shortcut screenshotted above for your convenience, you can download it here: Demo callback shortcut with input.shortcut, and inspect it or import it into your Shortcuts to have a starting point.

Shortcut input variables

After the decoding of the dictionary, you'll have your clear variables to access within your shortcut actions; the typing is the following (similar to the environment variables provided to the custom callback command, except for having to replace undefined - unsupported by shortcuts dictionaries - with false):

VariableTypeNotes
SHORTCUT_NAMEstringName of the run shortcut
SHORTCUT_STATUS"success" \| "error" \| "cancel"Cancel: manually stopped
SHORTCUT_RESULTstring \| falseOnly on success status
SHORTCUT_ERRORstring \| falseOnly on error status

Requirements

  • Supports macOS 12+ (Monterey or more recent)
  • The Apple Shortcuts you wish to control with this plugin must be executable from the machine where Homebridge is installed. I.e. the user running Homebridge must be logged into an iCloud account which has access to those Shortcuts.

Credits

This project is a fork of homebridge-shortcuts-buttons originally created by smj0x.

Special thanks to the original developer for creating the foundation of this plugin, which allows HomeKit buttons to trigger iOS shortcuts via Homebridge.

Development

Please feel free to open PRs from forked repo against the latest branch, I'll do my best to have a look asap. The plugin is pretty extensible and there are plenty of potential easy enhancements to make in case people find it useful.

Semantic release and conventional changelog

This repo uses semantic-release to publish github releases and npm packages. Among the other things, it perform commits analysis in order to determine when a new release is needed, so it's important that all commits messages follow the conventional-changelog syntax. To facilitate this, the repo enforces the use of commitizen locally, via husky prepare-commit-msg hook.