Skip to content
John Freed edited this page Sep 7, 2021 · 50 revisions

See also: DBus man page.

signal-cli can run in daemon mode and provides an experimental dbus interface.

  • Run in daemon mode (dbus session bus)

    signal-cli [-u USERNAME] daemon
    
  • Send a message via dbus

    signal-cli --dbus send -m "Message" [RECIPIENT [RECIPIENT ...]] [-a [ATTACHMENT [ATTACHMENT ...]]]
    

MacOS

MacOS users can run the following commands if needed:

brew install dbus
brew services start dbus

The environment variable DBUS_LAUNCHD_SESSION_BUS_SOCKET needs to be set correctly. Normally, this is handled automatically upon login by the MacOS launchd system working with Homebrew. If the variable has not been set correctly, you will see error messages similar to those in the Troubleshooting section below. If that happens, issue this command:

export DBUS_LAUNCHD_SESSION_BUS_SOCKET=$(launchctl getenv DBUS_LAUNCHD_SESSION_BUS_SOCKET)

If the DBus service is not running at all, the environment variable will remain unset after issued this command. To test it:

printenv DBUS_LAUNCHD_SESSION_BUS_SOCKET

You should see a response like: /private/tmp/com.apple.launchd.DoArnyRzbQ/unix_domain_listener

If the response is empty, you must manually restart the DBus service and set the environment variable:

brew services restart dbus
export DBUS_LAUNCHD_SESSION_BUS_SOCKET=$(launchctl getenv DBUS_LAUNCHD_SESSION_BUS_SOCKET)

System bus

To run on the system bus you need to take some additional steps. It’s advisable to run signal-cli as a separate unix user, the following steps assume you created a user named signal-cli. To run a service on the system bus, a config file is needed to allow the signal-cli user to take a name on the system bus. An example config file can be found in data/org.asamk.Signal.conf. This file also configures that any user can talk with the signal-cli daemon. The data/org.asamk.Signal.service and data/signal-cli.service files configure a dbus activated systemd service for signal-cli, so the service is automatically started when the dbus service is requested.

These steps, executed as root, should work on all distributions using systemd.

cp data/org.asamk.Signal.conf /etc/dbus-1/system.d/
cp data/org.asamk.Signal.service /usr/share/dbus-1/system-services/
cp data/signal-cli.service /etc/systemd/system/
sed -i -e "s|%dir%|<INSERT_INSTALL_PATH>|" /etc/systemd/system/signal-cli.service
systemctl daemon-reload
systemctl enable signal-cli.service
systemctl reload dbus.service

Mind the fact that signal-cli.service executes the signal-cli with "--config /var/lib/signal-cli". If you registered with user signal-cli, remove the config option.

Make sure to use "--dbus-system" with the send command, the service will be autostarted by dbus the first time it is requested.

Send using dbus-send

To avoid the startup time of the JVM for the dbus client, you can use any dbus capable program to send messages via the signal-cli dbus daemon. Example with dbus-send:

dbus-send --session --type=method_call --print-reply --dest="org.asamk.Signal" /org/asamk/Signal org.asamk.Signal.sendMessage string:MessageText array:string: string:RECIPIENT

Example if you started the daemon without the optional USERNAME (exports all local users):

dbus-send --session --type=method_call --print-reply --dest="org.asamk.Signal" /org/asamk/Signal/_33123456789 org.asamk.Signal.sendMessage string:MessageText array:string: string:RECIPIENT

Keep in mind that if you use DBus as a system service and want to send a message using the dbus daemon, you must use --system instead of --session in the dbus send command.

For an example of sending a group message through the dbus interface, see #272.

Receive messages from signal-cli daemon

The signal-cli daemon publishes new messages to dbus.

Here's an example using python:

def msgRcv (timestamp, source, groupID, message, attachments):
   print ("Message", message, "received in group", signal.getGroupName (groupID))
   return

from pydbus import SystemBus
from gi.repository import GLib

bus = SystemBus()
loop = GLib.MainLoop()

signal = bus.get('org.asamk.Signal') 
# NOTE: when daemon was started without explicit `-u USERNAME`, replace the line above with
# signal = bus.get("org.asamk.Signal", "/org/asamk/Signal/_YOURPHONENUMBER")

signal.onMessageReceived = msgRcv
loop.run()

Here's an example using Perl:

#!/bin/perl

use Modern::Perl;

use Net::DBus;
use Net::DBus::Reactor;

sub msgRcv {
    my ($timestamp, $sender, $groupID, $message, $attachments) = @_;
    print "Message: $message\nSender: $sender\nTimestamp: $timestamp\nAttachments: $attachments\n";
    return;
}

my $bus = Net::DBus->system();
my $sig = $bus->get_service("org.asamk.Signal");
my $obj = $sig->get_object("/org/asamk/Signal","org.asamk.Signal");
my $sigid = $obj->connect_to_signal('MessageReceived', \&msgRcv);

my $reactor=Net::DBus::Reactor->main();
$reactor->run();

exit 0;

Troubleshooting

DBus exception when starting daemon

$ signal-cli daemon
org.freedesktop.dbus.exceptions.DBusException: Cannot Resolve Session Bus Address
	...

	--- OR --- 

org.freedesktop.dbus.exceptions.DBusException: Failed to connect to bus: No such file or directory
	...

Environment variable DBUS_SESSION_BUS_ADDRESS needs to be set. See #394 and links to other issues in it.

Under Mac OSX, the environment variable DBUS_LAUNCHD_SESSION_BUS_SOCKET needs to be set (see above). This can be done by issuing the command

export DBUS_LAUNCHD_SESSION_BUS_SOCKET=$(launchctl getenv DBUS_LAUNCHD_SESSION_BUS_SOCKET)

Clone this wiki locally