My way of using Signal-CLI-Rest-API to send Editable Messages in Home Assistant

There are multiple ways to send a Signal message in home assistant.
This post describes my way of sending Editable Signal messages using the signal-cli-rest-api.
I choose to use the REST integration to build a script that is able to send messages while can also edit sent messages.
The default way using notify does not allow you to edit messages, so this is a workaround to send messages that are updatable.

Prerequisites

A running signal-cli-rest-api instance. (preferably secured with a reverse proxy and authentication).

Changes in configuration.yaml

rest_command:
    signal_cli:
        url: "http://:signal-rest-api/v2/send"
        method: "POST"
        payload: "{{payload}}"
        username: "hass"
        password: ""
        content_type: "application/json"

Notice: The username and password are optional, but I choose to protect the signal-cli-rest-api with a reverse proxy and basic authentication.

Script

Create a new script in your home assistant.

alias: Signal Message
description: Send a message using the Signal CLI Rest API
fields:
  number:
    name: Number
    description: Phone Number to send message from
    required: true
    example: "+01123456789"
    selector:
      text: {}
  recipients:
    name: Recipients
    description: |
      List of recipients to add

      Need to be in the form of

      +01123456789
      group.123456789
    required: true
    selector:
      text:
        multiple: true
  message:
    name: Message (Optional)
    description: Message to send
    required: false
    example: Hello World
    selector:
      text:
        multiline: true
  attachments:
    name: Attachments (Optional)
    description: |
      Attachments to add

      Need to be in the form of

      <BASE64 ENCODED DATA>
      data:<MIME-TYPE>;base64<comma><BASE64 ENCODED DATA>
      data:<MIME-TYPE>;filename=<FILENAME>;base64<comma><BASE64 ENCODED DATA>
    required: false
    selector:
      text:
        multiple: true
  load_edit_timestamp_helper:
    name: Load Edit Timestamp from Helper (Optional)
    description: >-
      Load the Edit Timestamp value from the specified helper (This can be used
      to edit a previously sent message)
    required: false
    selector:
      entity:
        filter:
          domain: input_text
  save_edit_timestamp_helper:
    name: Save Timestamp to Helper (Optional)
    description: Set this helper to the Timestamp of the sent message
    required: false
    selector:
      entity:
        filter:
          domain: input_text
sequence:
  - variables:
      base_payload:
        recipients: "{{recipients}}"
      message_payload: |-
        {% if message and message != "" %}
          {"message": "{{message}}"}
        {% else %}
          {}
        {% endif %}
      attachments_payload: |-
        {% if attachments|length > 0 %}
          {"base64_attachments": {{attachments}}}
        {% else %}
          {}
        {% endif %}
      edit_timestamp_payload: |-
        {% if load_edit_timestamp_helper %}
          {"edit_timestamp": {{states(load_edit_timestamp_helper) | int}}}
        {% else %}
          {}
        {% endif %}
      payload: >
        {{ base_payload | combine({"number": number}) | combine(message_payload)
        | combine(attachments_payload) | combine(edit_timestamp_payload) }}
  - action: rest_command.signal_cli
    response_variable: response
    data:
      payload: "{{payload | to_json}}"
  - if:
      - condition: template
        value_template: "{{response['status'] != 201}}"
    then:
      - stop: Status was not 201
        error: true
  - if:
      - condition: template
        value_template: "{{ save_edit_timestamp_helper and save_edit_timestamp_helper != \"\"}}"
    then:
      - action: input_text.set_value
        metadata: {}
        target:
          entity_id: "{{ save_edit_timestamp_helper }}"
        data:
          value: "{{response['content']['timestamp']}}"
mode: single

Usage

From an automation or script you can call the script like this:

action: script.signal_message
metadata: {}
data:
  recipients:
    - group....
  number: "+0123456789"
  message: Hello World

Editing Messages

In order to edit a message you need to use the save_edit_timestamp_helper to save the timestamp of the sent message. When you call the script again you can use the load_edit_timestamp_helper to load the timestamp of the message you want to edit.

Example Automation:

alias: Send Signal Attachment
triggers: []
conditions: []
actions:
  - action: script.signal_message
    metadata: {}
    data:
      recipients:
        - group....
      number: "+123456789"
      message: Hello World
      save_edit_timestamp_helper: input_text.signal_edit_timestamp
    enabled: true
  - delay: "00:00:05"
  - action: script.signal_message
    metadata: {}
    data:
      recipients:
        - group....
      number: "+123456789"
      message: Hello Earth
      load_edit_timestamp_helper: input_text.signal_edit_timestamp
    enabled: true
mode: single

Attachments

A big caveat is that attachments cannot be updated!

You can add attachments to the message by using the attachments field. I wanted to send videos, so I a base64 command to the configuration.yaml:

shell_command:
  base64: "base64 "

Then I used following automation:

alias: Send Signal Attachment
triggers: []
conditions: []
actions:
  - action: shell_command.base64
    metadata: {}
    data:
      args: "-i /config/www/previews/cam2.20250526-102212.mp4"
    response_variable: response
  - if:
      - condition: template
        value_template: "{{response['returncode'] != 0 }}"
    then:
      - stop: Return code was not 0
        error: true
  - action: script.signal_message
    metadata: {}
    data:
      recipients:
        - group....
      number: "+123456789"
      message: CAM2 Preview
      attachments:
        - "{{response['stdout']}}"
    enabled: true
mode: single

Written by

Tobias Salzmann