MacOS setup
In order for this to work, you will need a Mac computer that is logged-in to iCloud and has SSH access enabled (under Settings > Sharing > Remote Login). If the Mac goes to sleep, it won’t be reachable via SSH, so it’s best to keep it always on. For example, a Mac Mini is a good option for a small home server since it has a very low power consumption.
The syntax for sending messages using MacOS is the following:
osascript -e 'tell application "Messages" to send "Test Message" to buddy "someone@gmail.com"'
You can try this command in the MacOS Terminal to make sure it works.
Next, let’s create a script that we will trigger from a remote Home Assistant machine. The reason I like using a script instead of calling osascript directly is that it makes the shell command from Home Assistant simpler and avoids potential mistakes with quotation marks. Save the following file as SendMessage.sh, put it in your Documents folder and make it executable (chmod 755 SendMessage.sh):
#!/bin/sh
recipient="${1}"
message="${*:2}"
cat<<EOF | osascript - "${recipient}" "${message}"
on run {targetBuddyPhone, targetMessage}
tell application "Messages"
set targetService to 1st service whose service type = iMessage
set targetBuddy to buddy targetBuddyPhone of targetService
send targetMessage to targetBuddy
end tell
end run
EOF
Home Assistant shell setup
First, let’s make sure we can log in to your remote Mac from Home Assistant SSH (you can use the built-in SSH Add-on). In my case, I will be using a key-based authentication, but you can also use a password. For a tutorial on Home Assistant shell, please refer to this article.
Second, let’s make sure we can execute the script by running the following command from Home Assistant shell:
ssh -i /config/.ssh/id_rsa -o 'StrictHostKeyChecking=no' someone@192.168.X.X "/Users/your_username/Documents/SendMessage.sh someone@gmail.com 'Test from Home Assistant'"
If this test worked, I recommend creating the following script in Home Assistant (e.g., in /config/scripts folder). This is again to make the calls from Home Assistant as simple as possible and avoid any syntax errors. We will call it imessage.sh:
#!bash
ssh -i /config/.ssh/id_rsa -o 'StrictHostKeyChecking=no' someone@192.168.X.X "/Users/your_username/Documents/SendMessage.sh $1 '$2'"
Home Assistant configuration
Finally, we will need to configure two items in Home Assistant. Unfortunately, I did not find a way to create a notification configuration using shell that would be able to pass variables. Therefore, we we will need to create a small workaround.
First, in your configuration.yaml, create the following shell_command:
shell_command:
imessage: >
bash /config/scripts/imessage.sh {{ target }} "{{ message }}"
Next, let’s create the notification configuration. We will use the REST notification that will call back the Home Assistant shell_command that we created in the previous script and pass the target and message variables. You can simply paste the following configuration, just include your Home Assistant IP address under resource. You will also need to generate a new long-term token and store it as “Bearer XXXXXXXX” in your secrets.yaml file.
notify:
- name: imessage
platform: rest
resource: 'http://X.X.X.X:8123/api/services/shell_command/imessage'
method: POST_JSON
headers:
authorization: !secret imessage_rest
content-type: 'application/json'
message_param_name: message
target_param_name: target
After the next Home Assistant restart, you will have a new notify.imessage entity that can pass message and target variables over to your Mac and send iMessages.
This might not be the simplest setup to get to this result, so if you discovered an easier route, please let me know.