signal_cli#
Ruby API client for signal-cli JSON-RPC endpoint.
A direct port of pysignalclijsonrpc to Ruby.
Reference:
Installation#
Add this line to your application's Gemfile:
gem "signal_cli"
And then execute:
$ bundle install
Or install it yourself as:
$ gem install signal_cli
Usage#
Signal accounts can be specified in one of four formats:
- Phone Number: Standard international format, e.g.
+15551234567 - ACI: The stable signal user id that does not ever change. It is in UUID format. e.g.
f7e7c8c4-5294-4011-9912-091d172e45ed - PNI: The signal identifier tied to particular phone number. The user that is attached to this PNI can change if a new user registers with an old phone number. Prefix the UUID with "PNI:". e.g.
PNI:ff7e7c8c-5294-4011-9912-091d172e45ed - Username: The temporary handle the user has chosen for themselves. Internally, signal-cli resolves this to an ACI. Add "u:" prefix. e.g.
u:username.123
Setup#
require "signal_cli"
client = SignalCli::Api.new(
endpoint: "http://localhost:8080/api/v1/rpc",
account: "+49123456789"
)
Account lifecycle#
# Register your phone number with Signal
client.register
# Verify with the code received via SMS or voice call
client.verify(verification_code: "123-456")
# Check the signal-cli version
client.version # => "0.11.5.1"
Sending messages#
# Send a simple text message
client.send_message(
recipients: ["+49123456789"],
message: "Hello from signal_rb!"
)
# Send a message with an attachment from a file
client.send_message(
recipients: ["+49123456789"],
message: "Check this out",
attachments_as_files: ["/path/to/photo.jpg"]
)
# Send a message with an attachment from raw bytes
client.send_message(
recipients: ["+49123456789"],
message: "Here's a screenshot",
attachments_as_bytes: [screenshot_bytes]
)
# Send a message with a mention (@-mention)
client.send_message(
recipients: ["+49123456789"],
message: "Hey team!",
mention: "0:3:+49123456789"
)
# Clean up attachment files after sending
client.send_message(
recipients: ["+49123456789"],
message: "See attachment",
attachments_as_files: ["/tmp/photo.jpg"],
cleanup_attachments: true
)
Groups#
# List all groups you're a member of
client.list_groups
# => [{"id" => "group-id", "name" => "Family", ...}, ...]
# Get details for a specific group
client.get_group(group_id: "some-group-id")
# Create or update a group
client.update_group(
name: "Vacation Planning",
members: ["+49123456789", "+491987654321"],
description: "Planning our summer trip",
message_expiration_timer: 604800 # 1 week
)
# Join a group via an invite link
client.join_group(uri: "https://signal.group/#..." )
# Leave a group
client.quit_group(group_id: "some-group-id")
# Leave and delete a group
client.quit_group(group_id: "some-group-id", delete: true)
Reactions#
# React to a message
client.send_reaction(
recipient: "+49123456789",
emoji: "✅",
target_author: "+491987654321",
target_timestamp: 1749285600000
)
# Remove a reaction
client.send_reaction(
recipient: "+49123456789",
emoji: "✅",
target_author: "+491987654321",
target_timestamp: 1749285600000,
remove: true
)
Profile#
# Update your profile
client.update_profile(
given_name: "Alice",
family_name: "Smith",
about: "Available"
)
Error handling#
begin
client.send_message(
recipients: ["+49123456789"],
message: "Hello"
)
rescue SignalCli::JSONRPCError => e
puts "Signal error: #{e.message}"
end
Passing a custom request ID#
For correlating JSON-RPC requests with responses in logs or tracing:
client.version(request_id: "my-custom-id")
Development#
After checking out the repo, run bin/setup to install dependencies. Then, run bundle exec rake test to run the tests.
License#
The gem is available as open source under the terms of the MIT License.