prism/internal/signal/client.go

98 lines
2.1 KiB
Go

package signal
import (
"encoding/json"
"fmt"
"net"
"sync/atomic"
)
var rpcID int32
type Client struct {
socketPath string
}
func NewClient(socketPath string) *Client {
return &Client{socketPath: socketPath}
}
type RPCRequest struct {
JSONRPC string `json:"jsonrpc"`
ID int32 `json:"id"`
Method string `json:"method"`
Params map[string]interface{} `json:"params"`
}
type RPCResponse struct {
JSONRPC string `json:"jsonrpc"`
ID int32 `json:"id"`
Result json.RawMessage `json:"result,omitempty"`
Error *RPCError `json:"error,omitempty"`
}
type RPCError struct {
Code int `json:"code"`
Message string `json:"message"`
}
func (c *Client) Call(method string, params map[string]interface{}) (json.RawMessage, error) {
conn, err := net.Dial("unix", c.socketPath)
if err != nil {
return nil, fmt.Errorf("failed to connect: %w", err)
}
defer conn.Close()
request := RPCRequest{
JSONRPC: "2.0",
ID: atomic.AddInt32(&rpcID, 1),
Method: method,
Params: params,
}
if err := json.NewEncoder(conn).Encode(&request); err != nil {
return nil, fmt.Errorf("failed to encode request: %w", err)
}
var response RPCResponse
if err := json.NewDecoder(conn).Decode(&response); err != nil {
return nil, fmt.Errorf("failed to decode response: %w", err)
}
if response.Error != nil {
return nil, fmt.Errorf("signal-cli error: %s", response.Error.Message)
}
return response.Result, nil
}
func (c *Client) CallWithAccount(method string, params map[string]interface{}, account string) (json.RawMessage, error) {
if params == nil {
params = make(map[string]interface{})
}
params["account"] = account
return c.Call(method, params)
}
type AccountInfo struct {
Number string `json:"number"`
Name string `json:"name,omitempty"`
}
func (c *Client) GetLinkedAccount() (*AccountInfo, error) {
result, err := c.Call("listAccounts", nil)
if err != nil {
return nil, err
}
var accounts []AccountInfo
if err := json.Unmarshal(result, &accounts); err != nil {
return nil, err
}
if len(accounts) == 0 {
return nil, nil
}
return &accounts[0], nil
}