Sending iMessage notifications with Home Assistant

Even though Apple iMessage does not offer API for home users, there is a way to send iMessage using the built-in osascript tool. I will show how to use Home Assistant to send messages using your Mac.

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 "[email protected]"'

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' [email protected] "/Users/your_username/Documents/SendMessage.sh [email protected] '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' [email protected] "/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.

Total
0
Shares
1 comment
  1. Thanks for this, very handy. Looks like I figured out a way to use a shell command. Still testing, but this appears to work: The shell script is based on yours.

    shell_command:
    imessage_shell: >
    bash /config/scripts/imessage.sh {{ target }} “{{ message }}”

    And then call it:

    – service: shell_command.imessage_shell
    data:
    message: Message Here
    target: PHONENUMBERHERE

Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Article

Creating Home Assistant status dashboard

We use cookies to improve your experience on our site and to show you relevant advertising. To find out more, please refer to our privacy policy.