-
-
Notifications
You must be signed in to change notification settings - Fork 302
DBus service
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 [-a ACCOUNT] daemon --dbus
-
Send a message via dbus
signal-cli --dbus send -m "Message" [RECIPIENT [RECIPIENT ...]] [-a [ATTACHMENT [ATTACHMENT ...]]]
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)
Note that this will work only from a normal Macintosh desktop session.
To use the system bus:
export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/usr/local/var/run/dbus/system_bus_socket
This works either from a desktop session or an SSH session.
As mentioned, the session bus command lines above work only from a normal Macintosh desktop session, because launchctl
is not available via SSH.
To work around this problem, there are two cases:
Case 1: dbus is already running
You can determine if dbus is already running with the command:
ps auxw|grep dbus|grep $(whoami)|grep session
If it is running, you can rely on the notion that the most recent listener in /private/tmp is assigned to this version of dbus. (This might not be 100% reliable in the future, so proceed at your own risk.) Use the command:
export DBUS_LAUNCHD_SESSION_BUS_SOCKET=$(find /private/tmp -user $(whoami) -type s -name unix_domain_listener -print0 | xargs -0 ls -rt|tail -n 1)
Case 2: dbus is not running
If you have determined that dbus is not running, you can choose your own address and set DBUS_LAUNCHD_SESSION_BUS_SOCKET to match it. For example, to use $HOME/Library/Caches/dbus/bus (make sure the directory exists and has permissions 0700):
mkdir -p $HOME/Library/Caches/dbus
chmod 0700 $HOME/Library/Caches/dbus
DBUS_LAUNCHD_SESSION_BUS_SOCKET=$HOME/Library/Caches/dbus/bus
/usr/local/Cellar/dbus/1.12.20/bin/dbus-daemon --nofork --session --address=unix:path=$DBUS_LAUNCHD_SESSION_BUS_SOCKET
In order for dbus-send
to work correctly, it needs to either be started from a terminal within a normal Mac desktop session, or it needs to have the environment variable DBUS_SESSION_BUS_ADDRESS
set correctly.
The command to set the environment variable is:
export DBUS_SESSION_BUS_ADDRESS=unix:path=$DBUS_LAUNCHD_SESSION_BUS_SOCKET
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.
On MacOSX (which uses launchd, not systemd), the corresponding command is
cp data/org.asamk.Signal.conf /usr/local/etc/dbus-1/system.d/
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.
The groupId is handled as an array of bytes rather than a Base64 string. (See #272.)
The byte array can be obtained from a base64-encoded string (which looks like ixZI93QgqmjNpM8V+E0= and can be found in signal-cli's config file, by default in ~/.local/share/signal-cli/data/<PHONE_NUMBER>.d/group-cache/). Note that any underscore must be converted into a slash (/) character to provide a valid base64-encoded string. To decode it to byte array, you can use python:
python3 -c 'import base64; print(",".join(str(i) for i in base64.b64decode("ixZI93QgqmjNpM8V+E0=".replace("_","/"))))'
or, using Bash shell syntax:
echo "ixZI93QgqmjNpM8V+E0="|sed 's/_/\//g' | base64 -d |xxd -p -c1|while read i; do printf "%d " $((16#${i})); done|sed 's/ /,/g'|sed 's/,$/\n/g'
To reverse the process:
python3 -c 'import base64; print(base64.b64encode(bytearray([139,22,72,247,116,32,170,104,205,164,207,21,248,77])))'
... or using Bash ...
echo "139,22,72,247,116,32,170,104,205,164,207,21,248,77"|sed 's/,/ /g'|while read i; do printf "%02x" ${i}; done|sed 's/^/00000000: /g'|xxd -r -c 256|base64
In the examples above, attachments are identified by the first array:string:
argument (dbus-send
arguments must be in the correct order). The last argument can either be a single string:RECIPIENT
(as in the examples above) or an array:string:RECIPIENT1,RECIPIENT2,...
(for dbus-send
, an array argument consists of a comma-separated list).
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;
$ 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)
Failed to open connection to "session" message bus: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
Script started via Cron must export environment variable DBUS_SESSION_BUS_ADDRESS
before calling dbus-send
(Credits to Thomas)
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus