Setup Open Whisper Systems Signal messenger for use with OH2 via scripts

Tags: #<Tag:0x00007efec1300450> #<Tag:0x00007efec1300360> #<Tag:0x00007efec1300298>

This tutorial is about setting up OpenHab to send messages via Signal messenger. It is based on this (german) and this Java client. (Please forgive and correct any linux specific errors - I am only a basic linux guy :slightly_smiling_face:)

Notes/Prerequisites

  • I used a raspberry based on Raspbian Jessie (paths can vary on other systems) with OpenHab 2.2 stable and Zulu JRE
  • You need a free phone number to send messages including the international prefix. (e.g. +491231234567 - I used my landline)
  • You will need the exec binding to run scripts from openhab

Install Signal client
The steps to install the signal client are described on github. The following steps are based on the version available at this time (0.6.2):

  1. Prepare directory: mkdir /var/lib/signal-cli
  2. Download & install
    cd /tmp
    curl -L  https://github.com/AsamK/signal-cli/releases/download/v0.6.2/signal-cli-0.6.2.tar.gz
    tar xf signal-cli-0.6.2.tar.gz -C /opt
    ln -sf /opt/signal-cli-0.6.2/bin/signal-cli /usr/local/bin/
    
  3. configure JRE with unlimited strength crypto (If you do not do this, you will receive an InvalidKeyException when sending a message.
    • For the Zulu JRE (recommended by Openhab) download the policies from here and unzip to /usr/lib/jvm/zulu-embedded-8-armhf/jre/lib/security/
    • For the Oracle JRE follow the steps from Stackoverflow
  4. Register a phone number (you need the full number including international prefix). You will receive a call where a voice tells you a verification code, which you need to write down.
    sudo signal-cli --config /var/lib/signal-cli -u <PHONE NUMBER> register --voice
  5. Verify your account
    sudo signal-cli --config /var/lib/signal-cli -u <PHONE NUMBER> verify <VERIFICATION CODE>
  6. change permissions to the config file, so that any user on the system can send messages
    sudo chmod a+rw /var/lib/signal-cli/data/*
  7. Test Signal client (you need a destination phone number to send a message to)
    signal-cli --config /var/lib/signal-cli -u <PHONE NUMBER> send -m "Hello from Signal ;-)" <DESTINATION PHONE NUMBER>
    • If you get an InvalidKeyException follow step 3 and check your JRE.

Create script to run from openhab
This tutorial uses the exec binding to run the script.

  1. create a script file named send-signal.sh in the openhab script directory (I assume /etc/openhab2/scripts) with the following content (replace <phone number> with your number)
    #!/bin/bash
    # Usage: send-signal.sh <recipient number> 'message to send'
    /usr/local/bin/signal-cli --config /var/lib/signal-cli -u <PHONE NUMBER> send -m "$2" $1
    
  2. allow execution of script file
    chmod +x send-signal.sh

Integrate in openhab
I use a string item and a rule which sends a message when the item is changed - a script binding would also be possible.

  • Item:
    String SendMessage
  • Rule
   rule "Send message via signal"
       when
           Item SendMessage received command
       then
           if(SendMessage.state !== null)
           {
               var String command = '/etc/openhab2/scripts/signal.sh '
               executeCommandLine(command + "<DESTINATION PHONE> '" + SendMessage.state.toString + "'", 60000)
           }
   end
4 Likes

Hello @DOliana

thanks for sharing this. Question: am I right that I need a plain new number for this? It seems to me that I cannot send a signal message to my own phone number (i.e., sender and receiver are the same number)? Or is it just an issue with my installation?

Thanks and take care!

Hi there,

Yes you are correct - that’s what I meant in the prerequisites:

It does not have to be a mobile number though - so you could use any phone that you can receive a call on to verify the number (e.g. home landline, office, …)

Sorry for a possible necroposting/thread hijacking which is not intended.

Any clever guy wishing to transform that java client the OP refers to an openHab action ? (and a possible binding but an action is what is needed to have the functional equivalent we have with Telegram now, where a bot avoids having the extra phone number)

Regards

Thanks for sharing your instructions to use openhab2 and signal-cli. After setting up signal-cli on my computer, I took a slightly different approach to send the messages. I wanted to be able to send messages to Signal Groups and not Signal Users so I defined an item for each Signal Group and added those items to a group.

File: Signal-Cli.items

Group gSignalMessageGroups
String sendSignalMessageToOpenHABUpdates  (gSignalMessageGroups)
String sendSignalMessageToAlarmUpdates (gSignalMessageGroups)
String sendSignalMessageToAlarmAlerts (gSignalMessageGroups)
String sendSignalMessageToOpenHABAlerts (gSignalMessageGroups)

Then I have a rule that detects something I want to be notified about. In this case, whenever a member of gDeviceTamper is tampered with I post an update to one of the SignalGroup items.

rule "Device Tamper"
when 
  Member of gDeviceTamper changed from OFF to ON
then
	logInfo("water-rules", "The item " + triggeringItem.name + " changed state from " + previousState + " to " + triggeringItem.state)
	sendSignalMessageToOpenHABUpdates.postUpdate("Device Tamper  reported by  " + triggeringItem.label)
 end

Finally, I have the rule that sends the signal message. This rule is triggered when a member of gSignalMessageGroups is updated and it uses the tiggeringitem.name to decide which signal group should receive the message. This rule uses the stringBuilder to create the command line string to send the message.

rule "Send Group message via signal"
  when
    Member of gSignalMessageGroups received update
  then
    var pathToSignalCli = "/usr/local/bin/signal-cli"
    var pathToSignalCliConfig = "/var/lib/signal-cli"
    var sendFromSignalUser = "<<signal-cli user number>>"

    var sendToSignalGroupID = ""
    var sendToSignalGroupDesc = ""

    switch triggeringItem.name {
      case "sendSignalMessageToOpenHABUpdates" : {
        sendToSignalGroupID = "<<insert Signal Group ID>>"
        sendToSignalGroupDesc = "OpenHAB Updates"
      }
      case "sendSignalMessageToOpenHABAlerts" : {
        sendToSignalGroupID = "<<insert Signal Group ID>>"
        sendToSignalGroupDesc = "OpenHAB Alerts"
      }
  
      case "sendSignalMessageTAlarmUpdates" : {
        sendToSignalGroupID = "<<insert Signal Group ID>>"
        sendToSignalGroupDesc = "Alarm Updates"
      }

     case "sendSignalMessageTAlarmAlerts" : {
        sendToSignalGroupID = "<<insert Signal Group ID>>"
        sendToSignalGroupDesc = "Alarm Alerts"
      }
  
      default : {
        sendToSignalGroupID = "<<insert Signal Group ID>>"
        sendToSignalGroupDesc = "OpenHAB Updates"
      }
    }
               
    logInfo("signal-rules", "Send Message via Signal " + triggeringItem.state.toString)
    if(triggeringItem.state !== null)
      {
        val StringBuilder myCommand = new StringBuilder
        myCommand.append(pathToSignalCli)
        myCommand.append("@@--config@@")
        myCommand.append(pathToSignalCliConfig)
        myCommand.append("@@-u@@")
        myCommand.append(sendFromSignalUser)
        myCommand.append("@@send@@-m@@")
        myCommand.append(triggeringItem.state.toString)
        myCommand.append("@@-g@@")
        myCommand.append(sendToSignalGroupID)
        var signalResult = executeCommandLine(myCommand.toString, 10000)
        logInfo("signal-rules", signalResult + ": " + sendToSignalGroupDesc + " - " + triggeringItem.state.toString)
      }
end
1 Like

All works well for a single user with little slowness on pi 4 . One warning for the android library but looks fix will come in the next release.

but for a group how to get the group ID ?
using -g
sudo signal-cli --config /var/lib/signal-cli -u +xxxxxxxxx send -m “Hello from Signal ;-)” -g
<group_ID>

Tried here in config file /var/lib/signal-cli/ xxxxxxxx But Group Id Is Null
“groupStore” : {
“groups” : [ ]
},

sudo signal-cli --config /var/lib/signal-cli -u +xxxxxxxxx listGroups

If are using dbus-send then the Group ID must be converted as described in this issue: How to send group messages via dbus-send? · Issue #272 · AsamK/signal-cli · GitHub

This is a thing you would have to clarify with the maintainer of the CLI - probably on github

I can only say that I use two items (two people living at home) so that I can notify separately and if required, I send two notifications.

Hi and thank you for sharing.
Will this also work for OH3?

sure - why not?

Hi,

because the Zulu Java security folder changed. For example:
/usr/lib/jvm/zulu-embedded-8-armhf/jre/lib/security/
to
/opt/jdk/zulu11.43.88-ca-jdk11.0.9-linux_aarch32hf/lib/security/

And it looks like there is a bug with libzkgroup:
OpenJDK Client VM warning: You have loaded library /tmp/resource4543626946395898730.so which might have disabled stack guard. The VM will try to fix the stack guard now. It's highly recommended that you fix the library with 'execstack -c <libfile>', or link it with '-z noexecstack'. [main] WARN org.asamk.signal.Main - WARNING: Support for new group V2 is disabled, because the required native library dependency is missing: libzkgroup [main] ERROR org.asamk.signal.Main - Error loading state file: /var/lib/signal-cli/data/+49xxxxxx

I have need to further investigate on the above as i didn’t compile on the machine rather using the precompiled version.

I had the warning too and if I remember correctly, you can ignore it (I cannot find the github issue where it was stated). If you try sending/receiving messages it should work as it is. In general if you have issues/questions with the cli you should check that with the maintainer on github.

Nonetheless I am working on a docker image that exposes signal via MQTT so that different Java versions should also not be an issue. Right now it works by using the cli by AsamK but can only send/receive messages to single contacts and also works rather slow (especially receiving). I am blocked currently since I would prefer to use a library instead of a cli but my knowledge of Rust is very rusty…

Update: i saw that you are using Java 11, so cli version >= 7.0. The 7.0 release had a comment about the requirement to self compile library support - see here: Provide native lib for libsignal · AsamK/signal-cli Wiki (github.com)

To anybody reading this: If you have knowledge of Rust (that’s the language of the available signal-libraries) or would like to help developing & maintaining a signal-mqtt image let me know!

That is correct. I found the tickets already and for some this bug is comestic. Will post the solution here once resolved.

I cannot confirm that sending/receiving is slow, it works more or less instantly on my Raspi.

The only thing is, that i have to use SUDO to send and receive which is, i beleive, a ownership problem.