Use Signal Messenger for Notifications

I use this web API to send Signal notifications:

It is an HTTP API that is running on top of the Official API. It is super simple to use with the REST Notification component. They have step-by-step instructions on the web (see the WhatsApp instructions). It is the same just changing the URL.

1 Like

I note version 0.39 of the container (which resolves native mode on arm64) is published, when will the addons repo be updated to allow this version to be installed?

Not sure if you aware that this “service” has all your message content in plain text. You literally loose the whole end-to-end encryption which makes signal worth using the site you linked (btw. they don’t provide any information who is running this “service” for you…)…

hello @mbitard hope you are doing well.

Just upgraded my ha from 2021.5.x to 2021.6.3 and your signal integration suddenly stopped working.

The log spits this out:

 Platform error: notify - Integration 'signalmessenger' not found. 

despite I didn’t changed anything and it was working for the last year just perfectly fine.

The folder /config/custom_components/signalmessenger is also present:
image
(files are up2date, just two newer files (manifest.json and services.yaml) were missing - I added them now but config check still fails:
image
Any idea what’s going wrong on my side?

From the release notes:
“As mentioned in every release since 2021.3, custom integrations will require a version key in their manifest file.”

Did you put the version number in?

I did a second ha restart now and signal works again :rocket:

Hi @orange-assistant, I’m fine, I hope you are too!

Sorry I was away all weekend without access to my computer. I’m glad it worked on the second restart, that’s strange though. Will it help if I did the extra effort to put the custom integration into hacs?

Would be very nice actually. Your component is the only one in my setup added manually - the rest for me is available in hacs :rocket:

I started here: Integrate signalmessenger to hacs by MichaelBitard · Pull Request #29 · agileek/hassio-addons · GitHub

I had no idea it will be so complicated :smiley:

1 Like

Hello!

Regarding the issue of having to have a spare mobile number for using Signal in Home Assistant…

I was also in the case where I did not have a spare mobile number to use, and I was pretty bummed about it.

I did not want to use a “virtual” phone number because the options out there seemed pretty sketchy, plus I wanted to retain control on what phone number was used over time.

Somewhere on the Internet (sorry, I don’t remember where), I saw that it was possible to make it so instead of relying on an SMS, it was possible to receive a call from Signal with the much sought-after confirmation code.

So what I did is use my house landline number, and I got a voice message that I could read through my ISP’s interface, which in turn I could use for ending the onboarding process.

That way I retain control on what phone number is sending messages, without relying on dubious services.

In my case all this summed up to running this command (after having gotten a Captcha)

curl -X POST -H "Content-Type: application/json" 'http://<IP>:<PORT>/v1/register/<LAND_LINE_PHONE_NUMBER_WITH_PLUS>' -d '{"captcha":"<CAPTCHA_HERE>", "use_voice": true}'

the last option here is the key to all of this.

Once you get the code (three digits followed by a dash followed by three digits) you can run

curl -X POST -H "Content-Type: application/json" 'http://<IP>:<PORT>/v1/register/<LAND_LINE_PHONE_NUMBER_WITH_PLUS>/verify/<123-123>"'

where “<123-123>” is whatever confirmation code you got from Signal.

This worked for me, and I’m happy!

I hope this can help!

1 Like

Hi all,

Looking forward to trying this out but I can’t get java running in home assistant OS.

I’ve downloaded various versions of the jdk as tar’s and unpacked them.
When running the ‘java’ I just get

-bash: /opt/jdk-11.0.13+8-jre/bin/java: No such file or directory

I looked online and a suggestion to run ‘ldd’ on the binary produces:

Error relocating /opt/jdk-11.0.13+8-jre/bin/../lib/jli/libjli.so: __strdup: symbol not found
Error relocating /opt/jdk-11.0.13+8-jre/bin/../lib/jli/libjli.so: __rawmemchr: symbol not found

Anyone got any tips please?

I am doing all this by ssh’ing to home assistant with the ssh add-on.

Thanks all

Duh, didn’t realise the add-on includes signal-cli. I thought step 1 involved installing signal-cli in home assistant.
Did the set up on my desktop which has java and then copied the data dir to the home assistant config dir.

All working now.

Thank you to all involved and @mbitard with the docker work. It was a bit of a challenge to register my phone my number with signal, but I can see here that I was not the only one.

If interested on one approach for receiving messages. Here is the approach that I have taken, but first lets have a look at the payload to understand the code used:

[
{
  "envelope":{
    "source":"+<number>",
    "sourceNumber":"+<number>",
    "sourceUuid":"<Uuid number>",
    "sourceName":"Philippe Eveleigh",
    "sourceDevice":2,
    "timestamp":1635705623098,
    "dataMessage":{
      "timestamp":1635705623098,
      "message":"Hello World1",
      "expiresInSeconds":0,
      "viewOnce":false,
      "mentions":[],
      "attachments":[],
      "contacts":[]
    }
  }
},{
  "envelope":{
    "source":"+<number>",
    "sourceNumber":"+<number>",
    "sourceUuid":"<Uuid number>",
    "sourceName":"Philippe Eveleigh",
    "sourceDevice":2,
    "timestamp":1635705632553,
    "dataMessage":{
      "timestamp":1635705632553,
      "message":"Hello World2",
      "expiresInSeconds":0,
      "viewOnce":false,
      "mentions":[],
      "attachments":[],
      "contacts":[]
    }
  }
}
]

What should be understood from the payload is it can contain multiple messages (envelope). Here is a payload with no messages:

Here is the code that I use to retrieve the payload:

  - resource: 'http://services20:8085/v1/receive/+<number>'
    scan_interval: 60
    headers:
      User-Agent: "Home Assistant"
      Content-Type: "application/json"
    sensor:
      - name: signal_notification_inside_lights
        json_attributes_path: "$"
        value_template: >-
          {% set ns = namespace(signal_notification_inside_lights_state = 'unavailable') %}
          {% if value_json is defined %}
            {% set ns.signal_notification_inside_lights_state = 'none' %}
            {% if (value_json | length) > 0 %}
              {# Change the payload order #}
              {% set value_json = value_json | sort(attribute='envelope.timestamp', reverse = True) %}
              {# jinja does not allow to break out of a loop making things a little challenging. I use the variable state instead #}
              {% for i in value_json %}
                {# Source Number #}
                {% if i['envelope']['sourceNumber'] in ['+<source number1>','+<source number2>','+<source number3>','+<source number4>'] %}
                  {# Message intercepted #}
                  {% if ns.signal_notification_inside_lights_state == 'none' and 
                        'turn on inside light' in (i['envelope']['dataMessage']['message'] | lower) %}
                    {% set ns.signal_notification_inside_lights_state = 'on' %}
                  {% elif ns.signal_notification_inside_lights_state == 'none' and 
                          'turn off inside light' in (i['envelope']['dataMessage']['message'] | lower) %}
                    {% set ns.signal_notification_inside_lights_state = 'off' %}
                  {% endif %}
                {% endif %}
              {% endfor %}
            {% endif %}
          {% endif %}
          {{ ns.signal_notification_inside_lights_state }}
      - name: signal_notification_inside_lights_source_number
        json_attributes_path: "$"
        value_template: >-
          {% set ns = namespace(signal_notification_source_number = 'unavailable') %}
          {% if value_json is defined %}
            {% set ns.signal_notification_source_number = 'none' %}
            {% if (value_json | length) > 0 %}
              {# Change the payload order #}
              {% set value_json = value_json | sort(attribute='envelope.timestamp', reverse = True) %}
              {# jinja does not allow to break out of a loop making things a little challenging. I use the variable state instead #}
              {% for i in value_json %}
                {# Source Number #}
                {% if i['envelope']['sourceNumber'] in ['+<source number1>,'+<source number2>','+<source number3>','+<source number4>'] %}
                  {% if ns.signal_notification_source_number == 'none' and 
                        ('turn on inside light' in (i['envelope']['dataMessage']['message'] | lower) or 
                         'turn off inside light' in (i['envelope']['dataMessage']['message'] | lower)) %}
                    {% set ns.signal_notification_source_number = (i['envelope']['sourceNumber']) %}
                  {% endif %}
                {% endif %}
              {% endfor %}
            {% endif %}
          {% endif %}
          {{ ns.signal_notification_source_number }}

The above ‘sensor.signal_notification_inside_lights’ state will change to ‘on’ or ‘off’. If it finds ‘turn on inside light’ or ‘turn off inside light’ message.

The payload is traversed by descending time to intercept the last message that matches the above search criteria: ‘turn on inside light’ or ‘turn off inside light’.

In regards to the speed performance for receiving messages. I have noticed that it can be be as fast as three seconds but I have also wittiness taking fifteen seconds. For my needs I have set the scan_interval to 60 seconds.

Since the notification runs every 60 seconds and no feedback to the success of the request. I have added another ‘sensor.signal_notification_inside_lights_source_number’ that I use to reply back to the requester, confirming if it was successful executing the request. For you to decide if you need this sensor or not.

The payload is deleted from the signal servers once retrieved. If you need to add a second request such as ‘turn on/off outside light’ the sensor will need to be added above with the appropriate changes.

1 Like

Has anyone had success running the docker in the following mode: MODE=json-rpc?
I get the following error upon retrieval:

[root@services20 ~]# curl -X GET -H "Content-Type: application/json" 'http://127.0.0.1:8085/v1/receive/+1<number>'
Bad Request
{"error":"websocket: the client is not using the websocket protocol: 'upgrade' token not found in 'Connection' header"}
[root@services20 ~]#

My assumption is that my request is wrong. But I have not been able to find the right format for the call? I tried this but no success.

curl -X GET -H "Content-Type: application/json" 'ws://127.0.0.1:8085/v1/receive/+1<number>'
1 Like

Hi all,

I am currently switching from HA-app notifications to signal. Sending notifications works.
However, I have troubles sending images and might have a problem in the syntax I don’t see.
This block:

service: notify.signal
data:
message: Movement office
data:
  file: /config/www/office.jpg

does not send the image, but the message is delivered correctly. Any suggestions?

Thanks!

You have to refer to “attachments” when using Signal, not “file”. Working example for attaching two pictures to the same message:


service: notify.signal_lutz
data:
  message: test
  data:
    attachments:
      - /media/Pictures/yabbycam.jpg
      - /media/Pictures/snapshot_possum_cam.jpg

I’m having the same issue as hd001. Notification send ok without attachment but when you add attachment it does not work. Getting these errors in the log.

service: notify.signal_greg
data:
  message: Test
  data:
    attachments: 
      - /local/tmp/drivewaysnapshot.jpg

Thanks Lutz, that did it!

1 Like

Hi Greg,
I spent the last hours to get my notification with an attachment working.
It seems that you have to remove your first slash “/” like this:

    attachments: 
      - local/tmp/drivewaysnapshot.jpg

Without slash my message was successfully sent, with that “/” I got an “unknown error”.

What a nice integration. I am trying to get it working. I was able to send messages and also to send images from my camera. But now I am facing some trouble. It seems that I hit a rate limit. In HA everything seems fine and the initial logging of Signal also:

[GIN] 2022/02/14 - 15:19:01 | 200 |      60.578µs |  192.168.x.x| GET      "/v1/about"                     
[GIN] 2022/02/4 - 15:19:02 | 201 |  1.136573345s |  192.168.x.x | POST     "/v2/send"   

But when I look in /var/log/signal-cli-json-rpc-1/out.log I see a rate limit being hit

# tail -f /var/log/signal-cli-json-rpc-1/out.log                           
WARN SendHelper - Sending failed due to rate limiting from the signal server: [413] Rate limit exceeded: 413    
WARN SendHelper - Sending failed due to rate limiting from the signal server: [413] Rate limit exceeded: 413    
WARN SendHelper - Sending failed due to rate limiting from the signal server: [413] Rate limit exceeded: 413    
WARN SendHelper - Sending failed due to rate limiting from the signal server: [413] Rate limit exceeded: 413    
WARN SendHelper - Sending failed due to rate limiting from the signal server: [413] Rate limit exceeded: 413    
WARN SendHelper - Sending failed due to rate limiting from the signal server: [413] Rate limit exceeded: 413    
WARN SendHelper - Sending failed due to rate limiting from the signal server: [413] Rate limit exceeded: 413    
WARN SendHelper - Sending failed due to rate limiting from the signal server: [413] Rate limit exceeded: 413    
WARN SendHelper - Sending failed due to rate limiting from the signal server: [413] Rate limit exceeded: 413    
WARN SendHelper - Sending failed due to rate limiting from the signal server: [413] Rate limit exceeded: 413

I am just testing a couple of automations, not really a lot of messages. Does anyone knows what the ratelimit is? I get it already by sending like 3 messages in a row as a test.

I am running a different container for Signal and running this in json-rpc mode.

@mbitard have you maybe experienced this more often?