Documentation
¶
Overview ¶
Package signalcli provides Go bindings for signal-cli's JSON-RPC API.
signal-cli is a command-line interface for Signal that exposes a JSON-RPC API when run in daemon mode. This package provides a type-safe Go client for that API.
Example:
client := signalcli.NewClient("http://localhost:8080", "+1234567890")
err := client.Send(ctx, signalcli.SendParams{
Recipient: "recipient-uuid",
Message: "Hello!",
})
Index ¶
- type Address
- type AnswerMessage
- type Attachment
- type BlockParams
- type BusyMessage
- type CallMessage
- type Client
- func (c *Client) Account() string
- func (c *Client) BaseURL() string
- func (c *Client) Block(ctx context.Context, params BlockParams) error
- func (c *Client) Call(ctx context.Context, method string, params any) (json.RawMessage, error)
- func (c *Client) GetProfile(ctx context.Context, recipient string) (*Profile, error)
- func (c *Client) ListContacts(ctx context.Context) ([]Contact, error)
- func (c *Client) ListGroups(ctx context.Context) ([]Group, error)
- func (c *Client) MarkRead(ctx context.Context, recipient string, timestamps []int64) error
- func (c *Client) React(ctx context.Context, params ReactParams) error
- func (c *Client) Send(ctx context.Context, params SendParams) (*SendResult, error)
- func (c *Client) SendTyping(ctx context.Context, params TypingParams) error
- func (c *Client) SetExpiration(ctx context.Context, recipient string, seconds int) error
- func (c *Client) Unblock(ctx context.Context, params BlockParams) error
- func (c *Client) UpdateProfile(ctx context.Context, params UpdateProfileParams) error
- func (c *Client) WithHTTPClient(client *http.Client) *Client
- type Contact
- type Daemon
- func (d *Daemon) BaseURL() string
- func (d *Daemon) Error() error
- func (d *Daemon) IsReachable(ctx context.Context) bool
- func (d *Daemon) IsRunning() bool
- func (d *Daemon) MemoryUsage(ctx context.Context) (uint64, error)
- func (d *Daemon) Restart(ctx context.Context) error
- func (d *Daemon) Start(ctx context.Context) error
- func (d *Daemon) Stop() error
- func (d *Daemon) Wait() error
- func (d *Daemon) Watch(ctx context.Context, cfg WatchConfig) error
- type DaemonConfig
- type DataMessage
- type Envelope
- type EnvelopeHandler
- type Group
- type GroupInfo
- type HangupMessage
- type Listener
- type Mention
- type MentionInfo
- type MessageEnvelope
- type OfferMessage
- type Profile
- type Quote
- type QuoteInfo
- type RPCError
- type RPCRequest
- type RPCResponse
- type ReactParams
- type Reaction
- type ReadMessage
- type ReceiptMessage
- type RecipientResult
- type SendParams
- type SendResult
- type SentMessage
- type Sticker
- type SyncMessage
- type TypingMessage
- type TypingParams
- type UpdateProfileParams
- type WatchConfig
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Address ¶
type Address struct {
UUID string `json:"uuid,omitempty"`
Number string `json:"number,omitempty"`
Username string `json:"username,omitempty"`
}
Address represents a Signal address.
type AnswerMessage ¶
type AnswerMessage struct {
ID int64 `json:"id"`
}
type Attachment ¶
type Attachment struct {
ContentType string `json:"contentType"`
Filename string `json:"filename"`
ID string `json:"id"`
Size int64 `json:"size"`
Width int `json:"width"`
Height int `json:"height"`
Caption string `json:"caption"`
UploadTimestamp int64 `json:"uploadTimestamp"`
}
Attachment represents a file attachment.
type BlockParams ¶
type BlockParams struct {
Recipient string `json:"recipient,omitempty"`
GroupID string `json:"groupId,omitempty"`
}
BlockParams contains parameters for blocking/unblocking.
type BusyMessage ¶
type BusyMessage struct {
ID int64 `json:"id"`
}
type CallMessage ¶
type CallMessage struct {
OfferMessage *OfferMessage `json:"offerMessage"`
AnswerMessage *AnswerMessage `json:"answerMessage"`
HangupMessage *HangupMessage `json:"hangupMessage"`
BusyMessage *BusyMessage `json:"busyMessage"`
}
CallMessage represents a call event.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client handles JSON-RPC communication with signal-cli.
func NewClient ¶
NewClient creates a new signal-cli client.
baseURL is the signal-cli REST API URL (e.g., "http://localhost:8080"). account is the phone number or UUID of the account to use.
func (*Client) Block ¶
func (c *Client) Block(ctx context.Context, params BlockParams) error
Block blocks a recipient or group.
func (*Client) GetProfile ¶
GetProfile retrieves a user's profile.
func (*Client) ListContacts ¶
ListContacts retrieves all contacts for the configured account.
func (*Client) ListGroups ¶
ListGroups retrieves all groups for the configured account.
func (*Client) React ¶
func (c *Client) React(ctx context.Context, params ReactParams) error
React sends a reaction to a message.
func (*Client) Send ¶
func (c *Client) Send(ctx context.Context, params SendParams) (*SendResult, error)
Send sends a message.
func (*Client) SendTyping ¶
func (c *Client) SendTyping(ctx context.Context, params TypingParams) error
SendTyping sends a typing indicator.
func (*Client) SetExpiration ¶
SetExpiration sets the disappearing message timer for a conversation.
func (*Client) Unblock ¶
func (c *Client) Unblock(ctx context.Context, params BlockParams) error
Unblock unblocks a recipient or group.
func (*Client) UpdateProfile ¶
func (c *Client) UpdateProfile(ctx context.Context, params UpdateProfileParams) error
UpdateProfile updates the profile for the configured account.
type Contact ¶
type Contact struct {
Number string `json:"number"`
UUID string `json:"uuid"`
Name string `json:"name"`
IsBlocked bool `json:"isBlocked"`
Color string `json:"color"`
Address Address `json:"address"`
}
Contact represents a Signal contact.
type Daemon ¶
type Daemon struct {
// contains filtered or unexported fields
}
Daemon manages the signal-cli daemon subprocess.
func (*Daemon) IsReachable ¶
IsReachable checks if signal-cli daemon is responding at the configured URL.
func (*Daemon) MemoryUsage ¶
MemoryUsage returns the resident set size (RSS) of the signal-cli process in bytes. It returns an error if the daemon is not running or its memory cannot be sampled.
signal-cli runs on the JVM and is prone to gradually ballooning memory; use this together with Watch to bound its footprint.
The RSS sampling is platform-specific (see memory_*.go): Linux reads /proc/<pid>/statm, macOS shells out to ps, and it is unsupported on Windows.
func (*Daemon) Restart ¶
Restart gracefully stops the daemon and starts it again.
Stop waits for signal-cli to exit so it can flush local state, and messages that arrive while the daemon is down are queued by the Signal servers and redelivered on reconnect — so no messages are dropped. A Listener started against this daemon reconnects automatically once the daemon is back up.
func (*Daemon) Start ¶
Start starts the signal-cli daemon if not already running. It blocks until the daemon is ready to accept connections.
func (*Daemon) Watch ¶
func (d *Daemon) Watch(ctx context.Context, cfg WatchConfig) error
Watch samples the daemon's memory on an interval and restarts it when RSS stays above the configured limit for ConsecutiveHits samples. It blocks until ctx is cancelled (returning ctx.Err()) and is safe to run in its own goroutine alongside a Listener, which reconnects automatically across restarts.
type DaemonConfig ¶
type DaemonConfig struct {
// CLIPath is the path to the signal-cli binary.
CLIPath string
// Account is the phone number to use (e.g., "+1234567890").
Account string
// HTTPHost is the host to bind to (default "127.0.0.1").
HTTPHost string
// HTTPPort is the port to bind to (default 8080).
HTTPPort int
// ReceiveMode sets the receive mode (default "on-connection").
ReceiveMode string
// IgnoreAttachments skips downloading attachments.
IgnoreAttachments bool
// IgnoreStories skips story messages.
IgnoreStories bool
// SendReadReceipts sends read receipts automatically.
SendReadReceipts bool
// JavaMaxHeapMB caps the signal-cli JVM max heap via -Xmx (passed as
// JAVA_OPTS to the subprocess). 0 means don't set it (JVM default, usually
// ~1/4 of host RAM). When using Watch, this is auto-derived from the
// watchdog limit if left 0. Set explicitly to cap the initial process too.
JavaMaxHeapMB int
}
DaemonConfig holds configuration for the signal-cli daemon.
type DataMessage ¶
type DataMessage struct {
Timestamp int64 `json:"timestamp"`
Message string `json:"message"`
ExpiresInSeconds int `json:"expiresInSeconds"`
ViewOnce bool `json:"viewOnce"`
GroupInfo *GroupInfo `json:"groupInfo"`
Quote *QuoteInfo `json:"quote"`
Attachments []Attachment `json:"attachments"`
Mentions []MentionInfo `json:"mentions"`
Reaction *Reaction `json:"reaction"`
Sticker *Sticker `json:"sticker"`
}
DataMessage contains a regular text message.
type Envelope ¶
type Envelope struct {
Source string `json:"source"`
SourceNumber string `json:"sourceNumber"`
SourceUUID string `json:"sourceUuid"`
SourceName string `json:"sourceName"`
SourceDevice int `json:"sourceDevice"`
Timestamp int64 `json:"timestamp"`
ServerReceivedAt int64 `json:"serverReceivedTimestamp"`
ServerDeliveredAt int64 `json:"serverDeliveredTimestamp"`
DataMessage *DataMessage `json:"dataMessage"`
SyncMessage *SyncMessage `json:"syncMessage"`
TypingMessage *TypingMessage `json:"typingMessage"`
ReceiptMessage *ReceiptMessage `json:"receiptMessage"`
CallMessage *CallMessage `json:"callMessage"`
}
Envelope is the top-level message envelope from signal-cli.
type EnvelopeHandler ¶
EnvelopeHandler is called for each received envelope.
type Group ¶
type Group struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
IsMember bool `json:"isMember"`
IsBlocked bool `json:"isBlocked"`
Members []string `json:"members"`
PendingMembers []string `json:"pendingMembers"`
RequestingMembers []string `json:"requestingMembers"`
Admins []string `json:"admins"`
PermissionAddMember string `json:"permissionAddMember"`
PermissionEditDetails string `json:"permissionEditDetails"`
PermissionSendMessages string `json:"permissionSendMessage"`
GroupInviteLink string `json:"groupInviteLink"`
}
Group represents a Signal group.
type HangupMessage ¶
type HangupMessage struct {
ID int64 `json:"id"`
}
type Listener ¶
type Listener struct {
// contains filtered or unexported fields
}
Listener handles Server-Sent Events from signal-cli for receiving messages.
func NewListener ¶
NewListener creates a new SSE listener.
type Mention ¶
type Mention struct {
Start int `json:"start"`
Length int `json:"length"`
UUID string `json:"uuid"`
}
Mention represents a user mention.
type MentionInfo ¶
type MentionInfo struct {
Start int `json:"start"`
Length int `json:"length"`
UUID string `json:"uuid"`
}
MentionInfo represents a user mention in a message.
type MessageEnvelope ¶
MessageEnvelope wraps the envelope with account info.
type OfferMessage ¶
type Profile ¶
type Profile struct {
Address Address `json:"address"`
Name string `json:"name"`
IsBlocked bool `json:"isBlocked"`
ExpiresIn int `json:"messageExpirationTime"`
}
Profile represents a Signal user profile.
type Quote ¶
type Quote struct {
Timestamp int64 `json:"timestamp"`
Author string `json:"author"`
Message string `json:"message,omitempty"`
}
Quote represents a quoted/replied message.
type QuoteInfo ¶
type QuoteInfo struct {
ID int64 `json:"id"`
Author string `json:"author"`
AuthorUUID string `json:"authorUuid"`
Text string `json:"text"`
Attachments []Attachment `json:"attachments"`
}
QuoteInfo contains a quoted message.
type RPCError ¶
type RPCError struct {
Code int `json:"code"`
Message string `json:"message"`
Data json.RawMessage `json:"data,omitempty"`
}
RPCError represents a JSON-RPC error.
type RPCRequest ¶
type RPCRequest struct {
JSONRPC string `json:"jsonrpc"`
Method string `json:"method"`
Params any `json:"params,omitempty"`
ID string `json:"id"`
}
RPCRequest represents a JSON-RPC request.
type RPCResponse ¶
type RPCResponse struct {
JSONRPC string `json:"jsonrpc"`
Result json.RawMessage `json:"result,omitempty"`
Error *RPCError `json:"error,omitempty"`
ID string `json:"id"`
}
RPCResponse represents a JSON-RPC response.
type ReactParams ¶
type ReactParams struct {
Recipient string `json:"recipient"` // Recipient UUID or phone
Emoji string `json:"emoji"` // Emoji to react with
TargetAuthor string `json:"targetAuthor"` // Author of target message
TargetTimestamp int64 `json:"targetTimestamp"` // Timestamp of target message
Remove bool `json:"remove,omitempty"` // Remove reaction instead of add
GroupID string `json:"groupId,omitempty"` // For group messages
}
ReactParams contains parameters for sending a reaction.
type Reaction ¶
type Reaction struct {
Emoji string `json:"emoji"`
TargetAuthor string `json:"targetAuthor"`
TargetAuthorUUID string `json:"targetAuthorUuid"`
TargetTimestamp int64 `json:"targetSentTimestamp"`
IsRemove bool `json:"isRemove"`
}
Reaction contains reaction info.
type ReadMessage ¶
ReadMessage indicates a message was read.
type ReceiptMessage ¶
type ReceiptMessage struct {
Type string `json:"type"` // "DELIVERY" or "READ"
Timestamps []int64 `json:"timestamps"`
}
ReceiptMessage indicates message receipt status.
type RecipientResult ¶
type RecipientResult struct {
RecipientAddress Address `json:"recipientAddress"`
Type string `json:"type"` // "SUCCESS", "UNREGISTERED_FAILURE", etc.
NetworkFailure bool `json:"networkFailure,omitempty"`
UnregisteredFailure bool `json:"unregisteredFailure,omitempty"`
}
RecipientResult contains the result for a single recipient.
type SendParams ¶
type SendParams struct {
Recipient string `json:"recipient,omitempty"` // Single recipient (UUID or phone)
Recipients []string `json:"recipients,omitempty"` // Multiple recipients
GroupID string `json:"groupId,omitempty"` // Group ID for group messages
Message string `json:"message"`
Attachments []string `json:"attachments,omitempty"` // Paths to attachment files
Quote *Quote `json:"quote,omitempty"` // Quote/reply
Mentions []Mention `json:"mentions,omitempty"` // @mentions
}
SendParams contains parameters for sending a message.
type SendResult ¶
type SendResult struct {
Timestamp int64 `json:"timestamp"`
Results []RecipientResult `json:"results"`
}
SendResult contains the result of sending a message.
type SentMessage ¶
type SentMessage struct {
Destination string `json:"destination"`
DestinationUUID string `json:"destinationUuid"`
Timestamp int64 `json:"timestamp"`
Message string `json:"message"`
ExpiresInSeconds int `json:"expiresInSeconds"`
GroupInfo *GroupInfo `json:"groupInfo"`
Attachments []Attachment `json:"attachments"`
}
SentMessage is a message sent from another device.
type SyncMessage ¶
type SyncMessage struct {
SentMessage *SentMessage `json:"sentMessage"`
ReadMessages []ReadMessage `json:"readMessages"`
}
SyncMessage contains a sync message (sent from another device).
type TypingMessage ¶
type TypingMessage struct {
Action string `json:"action"` // "STARTED" or "STOPPED"
Timestamp int64 `json:"timestamp"`
GroupID string `json:"groupId,omitempty"`
}
TypingMessage indicates typing status.
type TypingParams ¶
type TypingParams struct {
Recipient string `json:"recipient"`
GroupID string `json:"groupId,omitempty"`
Stop bool `json:"stop,omitempty"`
}
TypingParams contains parameters for sending typing indicator.
type UpdateProfileParams ¶
type UpdateProfileParams struct {
Name string `json:"name,omitempty"`
About string `json:"about,omitempty"`
AboutEmoji string `json:"aboutEmoji,omitempty"`
Avatar string `json:"avatar,omitempty"` // Path to avatar file
}
UpdateProfileParams contains parameters for updating the user profile.
type WatchConfig ¶
type WatchConfig struct {
// MemoryLimit is the RSS threshold in bytes. When exceeded for
// ConsecutiveHits samples the daemon is restarted. Required (> 0).
MemoryLimit uint64
// Interval is how often memory is sampled (default 30s).
Interval time.Duration
// ConsecutiveHits is the number of back-to-back over-limit samples
// required before restarting, to ride out transient spikes (default 3).
ConsecutiveHits int
// OnRestart, if set, is called just before a restart is triggered with the
// RSS that tripped the limit.
OnRestart func(rss uint64)
// OnError, if set, is called when sampling or restarting fails. The watch
// loop continues regardless.
OnError func(err error)
}
WatchConfig configures the memory watchdog.