+=== Control methods
+These methods are available if the daemon is started anonymously (without an explicit `-u USERNAME`).
+Requests are sent to `/org/asamk/Signal`; requests related to individual accounts are sent to
+`/org/asamk/Signal/_441234567890` where the + dialing code is replaced by an underscore (_).
+Only `version()` is activated in single-user mode; the rest are disabled.
+
+link() -> deviceLinkUri<s>::
+link(newDeviceName<s>) -> deviceLinkUri<s>::
+* newDeviceName : Name to give new device (defaults to "cli" if no name is given)
+* deviceLinkUri : URI of newly linked device
+
+Returns a URI of the form "sgnl://linkdevice?uuid=...". This can be piped to a QR encoder to create a display that
+can be captured by a Signal smartphone client. For example:
+
+`dbus-send --session --dest=org.asamk.Signal --type=method_call --print-reply /org/asamk/Signal org.asamk.Signal.link string:"My secondary client"|tr '\n' '\0'|sed 's/.*string //g'|sed 's/\"//g'|qrencode -s10 -tANSI256`
+
+Exceptions: Failure
+
+listAccounts() -> accountList<as>::
+* accountList : Array of all attached accounts in DBus object path form
+
+Exceptions: None
+
+register(number<s>, voiceVerification<b>) -> <>::
+* number : Phone number
+* voiceVerification : true = use voice verification; false = use SMS verification
+
+Exceptions: Failure, InvalidNumber, RequiresCaptcha
+
+registerWithCaptcha(number<s>, voiceVerification<b>, captcha<s>) -> <>::
+* number : Phone number
+* voiceVerification : true = use voice verification; false = use SMS verification
+* captcha : Captcha string
+
+Exceptions: Failure, InvalidNumber, RequiresCaptcha
+
+verify(number<s>, verificationCode<s>) -> <>::
+* number : Phone number
+* verificationCode : Code received from Signal after successful registration request
+
+Command fails if PIN was set after previous registration; use verifyWithPin instead.
+
+Exceptions: Failure, InvalidNumber
+
+verifyWithPin(number<s>, verificationCode<s>, pin<s>) -> <>::
+* number : Phone number
+* verificationCode : Code received from Signal after successful registration request
+* pin : PIN you set with setPin command after verifying previous registration
+
+Exceptions: Failure, InvalidNumber
+
+version() -> version<s>::
+* version : Version string of signal-cli
+
+Exceptions: None
+
+=== Group control methods
+The following methods listen to the recipient's object path, which is constructed as follows:
+"/org/asamk/Signal/" + DBusNumber
+* DBusNumber : recipient's phone number, with underscore (_) replacing plus (+)
+
+createGroup(groupName<s>, members<as>, avatar<s>) -> groupId<ay>::
+* groupName : String representing the display name of the group
+* members : String array of new members to be invited to group
+* avatar : Filename of avatar picture to be set for group (empty if none)
+* groupId : Byte array representing the internal group identifier
+
+Exceptions: AttachmentInvalid, Failure, InvalidNumber;
+
+getGroup(groupId<ay>) -> objectPath<o>::
+* groupId : Byte array representing the internal group identifier
+* objectPath : DBusPath for the group
+
+getGroupMembers(groupId<ay>) -> members<as>::
+* groupId : Byte array representing the internal group identifier
+* members : String array with the phone numbers of all active members of a group
+
+Exceptions: None, if the group name is not found an empty array is returned
+
+joinGroup(inviteURI<s>) -> <>::
+* inviteURI : String starting with https://signal.group/#
+
+Behavior of this method depends on the `requirePermission` parameter of the `enableLink` method. If permission is required, `joinGroup` adds you to the requesting members list. Permission may be granted based on the group's `PermissionAddMember` property (`ONLY_ADMINS` or `EVERY_MEMBER`). If permission is not required, `joinGroup` admits you immediately to the group.
+
+Exceptions: Failure
+
+listGroups() -> groups<a(oays)>::
+* groups : Array of Structs(objectPath, groupId, groupName)
+** objectPath : DBusPath
+** groupId : Byte array representing the internal group identifier
+** groupName : String representing the display name of the group
+
+sendGroupMessage(message<s>, attachments<as>, groupId<ay>) -> timestamp<x>::
+* message : Text to send (can be UTF8)
+* attachments : String array of filenames to send as attachments (passed as filename, so need to be readable by the user signal-cli is running under)
+* groupId : Byte array representing the internal group identifier
+* timestamp : Long, can be used to identify the corresponding Signal reply
+
+Exceptions: GroupNotFound, Failure, AttachmentInvalid, InvalidGroupId
+
+sendGroupMessageReaction(emoji<s>, remove<b>, targetAuthor<s>, targetSentTimestamp<x>, groupId<ay>) -> timestamp<x>::
+* emoji : Unicode grapheme cluster of the emoji
+* remove : Boolean, whether a previously sent reaction (emoji) should be removed
+* targetAuthor : String with the phone number of the author of the message to which to react
+* targetSentTimestamp : Long representing timestamp of the message to which to react
+* groupId : Byte array representing the internal group identifier
+* timestamp : Long, can be used to identify the corresponding signal reply
+
+Exceptions: Failure, InvalidNumber, GroupNotFound, InvalidGroupId
+
+sendGroupRemoteDeleteMessage(targetSentTimestamp<x>, groupId<ay>) -> timestamp<x>::
+* targetSentTimestamp : Long representing timestamp of the message to delete
+* groupId : Byte array with base64 encoded group identifier
+* timestamp : Long, can be used to identify the corresponding signal reply
+
+Exceptions: Failure, GroupNotFound, InvalidGroupId
+
+=== Group methods
+The following methods listen to the group's object path, which can be obtained from the listGroups() method and is constructed as follows:
+"/org/asamk/Signal/" + DBusNumber + "/Groups/" + DBusGroupId
+* DBusNumber : recipient's phone number, with underscore (_) replacing plus (+)
+* DBusGroupId : groupId in base64 format, with underscore (_) replacing plus (+), equals (=), or slash (/)
+
+Groups have the following (case-sensitive) properties:
+* Id<ay> (read-only) : Byte array representing the internal group identifier
+* Name<s> : Display name of the group
+* Description<s> : Description of the group
+* Avatar<s> (write-only) : Filename of the avatar
+* IsBlocked<b> : true=member will not receive group messages; false=not blocked
+* IsMember<b> (read-only) : always true (object path exists only for group members)
+* IsAdmin<b> (read-only) : true=member has admin privileges; false=not admin
+* MessageExpirationTimer<i> : int32 representing message expiration time for group
+* Members<as> (read-only) : String array of group members' phone numbers
+* PendingMembers<as> (read-only) : String array of pending members' phone numbers
+* RequestingMembers<as> (read-only) : String array of requesting members' phone numbers
+* Admins<as> (read-only) : String array of admins' phone numbers
+* PermissionAddMember<s> : String representing who has permission to add members
+** ONLY_ADMINS, EVERY_MEMBER
+* PermissionEditDetails<s> : String representing who may edit group details
+** ONLY_ADMINS, EVERY_MEMBER
+* PermissionSendMessage<s> : String representing who post messages to group
+** ONLY_ADMINS, EVERY_MEMBER (note that ONLY_ADMINS is equivalent to IsAnnouncementGroup)
+* GroupInviteLink<s> (read-only) : String of the invitation link (starts with https://signal.group/#)
+
+To get a property, use (replacing `--session` with `--system` if needed):
+`dbus-send --session --dest=org.asamk.Signal --print-reply $OBJECT_PATH org.freedesktop.DBus.Properties.Get string:org.asamk.Signal.Group string:$PROPERTY_NAME`
+
+To set a property, use:
+`dbus-send --session --dest=org.asamk.Signal --print-reply $OBJECT_PATH org.freedesktop.DBus.Properties.Set string:org.asamk.Signal.Group string:$PROPERTY_NAME variant:$PROPERTY_TYPE:$PROPERTY_VALUE`
+
+To get all properties, use:
+`dbus-send --session --dest=org.asamk.Signal --print-reply $OBJECT_PATH org.freedesktop.DBus.Properties.GetAll string:org.asamk.Signal.Group`
+
+addAdmins(recipients<as>) -> <>::
+* recipients : String array of phone numbers
+
+Grant admin privileges to recipients.
+
+Exceptions: Failure
+
+addMembers(recipients<as>) -> <>::
+* recipients : String array of phone numbers
+
+Add recipients to group if they are pending members; otherwise add recipients to list of requesting members.
+
+Exceptions: Failure
+
+disableLink() -> <>::
+
+Disables the group's invitation link.
+
+Exceptions: Failure
+
+enableLink(requiresApproval<b>) -> <>::
+* requiresApproval : true=add numbers using the link to the requesting members list
+
+Enables the group's invitation link.
+
+Exceptions: Failure
+
+quitGroup() -> <>::
+Exceptions: Failure, LastGroupAdmin
+
+removeAdmins(recipients<as>) -> <>::
+* recipients : String array of phone numbers
+
+Remove admin privileges from recipients.
+
+Exceptions: Failure
+
+removeMembers(recipients<as>) -> <>::
+* recipients : String array of phone numbers
+
+Remove recipients from group.
+
+Exceptions: Failure
+
+resetLink() -> <>::
+
+Resets the group's invitation link to a new random URL starting with https://signal.group/#
+
+Exceptions: Failure
+
+=== Deprecated group control methods
+The following deprecated methods listen to the recipient's object path, which is constructed as follows:
+"/org/asamk/Signal/" + DBusNumber
+* DBusNumber : recipient's phone number, with underscore (_) replacing plus (+)
+
+getGroupIds() -> groupList<aay>::
+groupList : Array of Byte arrays representing the internal group identifiers
+
+All groups known are returned, regardless of their active or blocked status. To query that use isMember() and isGroupBlocked()
+
+Exceptions: None
+
+getGroupName(groupId<ay>) -> groupName<s>::
+* groupId : Byte array representing the internal group identifier
+* groupName : The display name of the group
+
+Exceptions: None, if the group name is not found an empty string is returned
+
+isGroupBlocked(groupId<ay>) -> isGroupBlocked<b>::
+* groupId : Byte array representing the internal group identifier
+* isGroupBlocked : true=group is blocked; false=group is not blocked
+
+Dbus will not forward messages from a group when you have blocked it.
+
+Exceptions: InvalidGroupId, Failure
+
+isMember(groupId<ay>) -> isMember<b>::
+* groupId : Byte array representing the internal group identifier
+* isMember : true=you are a group member; false=you are not a group member
+
+Note that this method does not raise an Exception for a non-existing/unknown group but will simply return 0 (false)
+
+quitGroup(groupId<ay>) -> <>::
+* groupId : Byte array representing the internal group identifier
+
+Note that quitting a group will not remove the group from the getGroupIds command, but set it inactive which can be tested with isMember()
+
+Exceptions: GroupNotFound, Failure, InvalidGroupId
+
+setGroupBlocked(groupId<ay>, block<b>) -> <>::
+* groupId : Byte array representing the internal group identifier
+* block : false=remove block , true=blocked
+
+Messages from blocked groups will no longer be forwarded via DBus.
+
+Exceptions: GroupNotFound, InvalidGroupId
+