Compare commits

..

8 Commits

Author SHA1 Message Date
Stephan Richter
fa17535a90
Merge 7e1b98f0c2163bceaa159d89816b2b6c2d0cb2d1 into ddc5aa55df34229f7cc2c452275ef3014b820361 2026-03-07 14:59:42 +01:00
Bernhard B
ddc5aa55df remove netcat-openbsd
* not needed anymore
2026-03-07 14:08:09 +01:00
Bernhard B
00bbfca878 updated signal-cli-native to 0.14.0+5 2026-03-07 14:08:09 +01:00
Bernhard B.
884582a71e
Merge pull request #807 from EvanHahn/debug-log-level-env-variable-docs
Mention `LOG_LEVEL` environment variable in debug docs
2026-03-06 17:38:45 +01:00
Evan Hahn
e3d503c746 Mention LOG_LEVEL environment variable in debug docs
This updates the debug docs to mention the `LOG_LEVEL` environment
variable.
2026-03-06 08:13:13 -06:00
Bernhard B
af34a0881c fixed small bug in json-rpc reconnect mechanism
* after we successfully reconnected, wait for new data
2026-03-05 20:50:42 +01:00
Bernhard B
c7cb9ab13e improved json-rpc reconnection logic
* when the connection the signal-cli daemon is lost in json-rpc mode,
  the open connection will be closed and a new connection attempt will
  be made. If after 15 connection attempts we are unable to connect to
  the signal-cli daemon, we give up and abort.
2026-03-05 20:43:22 +01:00
Bernhard B
af18c7aea8 switched to signal-cli daemon mode
* this gets rid off the ugly netcat workaround and should improve
  the general stability of the connection to the signal-cli binary
  in json-rpc mode.
2026-03-05 20:41:17 +01:00
6 changed files with 38 additions and 19 deletions

View File

@ -1,6 +1,6 @@
ARG SIGNAL_CLI_VERSION=0.14.0
ARG LIBSIGNAL_CLIENT_VERSION=0.87.4
ARG SIGNAL_CLI_NATIVE_PACKAGE_VERSION=0.14.0+morph027+3
ARG SIGNAL_CLI_NATIVE_PACKAGE_VERSION=0.14.0+morph027+5
ARG SWAG_VERSION=1.16.4
ARG GRAALVM_VERSION=25.0.2
@ -185,7 +185,7 @@ ENV SIGNAL_CLI_REST_API_PLUGIN_SHARED_OBJ_DIR=/usr/bin/
RUN dpkg-reconfigure debconf --frontend=noninteractive \
&& apt-get update \
&& apt-get install -y --no-install-recommends util-linux supervisor netcat-openbsd openjdk-25-jre curl locales \
&& apt-get install -y --no-install-recommends util-linux supervisor openjdk-25-jre curl locales \
&& rm -rf /var/lib/apt/lists/*
COPY --from=buildcontainer /tmp/signal-cli-rest-api-src/signal-cli-rest-api /usr/bin/signal-cli-rest-api

View File

@ -4,6 +4,8 @@ This can be done by putting the docker container into debug mode with the follow
```curl -X POST -H "Content-Type: application/json" -d '{"logging": {"level": "debug"}}' 'http://127.0.0.1:8080/v1/configuration'```
Alternatively, you can set the `LOG_LEVEL` environment variable.
Once the docker container is in debug mode, execute the REST API command you want to debug.
e.g Let's assume we are experiencing some problems with sending messages. So, let's send a Signal message with

View File

@ -410,7 +410,7 @@ func (s *SignalClient) GetSignalCliMode() SignalCliMode {
return s.signalCliMode
}
func (s *SignalClient) Init() error {
func (s *SignalClient) Init(maxRetries int) error {
s.signalCliApiConfig = utils.NewSignalCliApiConfig()
err := s.signalCliApiConfig.Load(s.signalCliApiConfigPath)
if err != nil {
@ -427,7 +427,7 @@ func (s *SignalClient) Init() error {
tcpPortsNumberMapping := s.jsonRpc2ClientConfig.GetTcpPortsForNumbers()
for number, tcpPort := range tcpPortsNumberMapping {
s.jsonRpc2Clients[number] = NewJsonRpc2Client(s.signalCliApiConfig, number)
err := s.jsonRpc2Clients[number].Dial("127.0.0.1:" + strconv.FormatInt(tcpPort, 10))
err := s.jsonRpc2Clients[number].Dial("127.0.0.1:"+strconv.FormatInt(tcpPort, 10), maxRetries)
if err != nil {
return err
}

View File

@ -2,14 +2,14 @@ package client
import (
"bufio"
"bytes"
"encoding/json"
"errors"
"net"
"net/http"
"strconv"
"sync"
"time"
"net/http"
"bytes"
"strconv"
"github.com/bbernhard/signal-cli-rest-api/utils"
uuid "github.com/gofrs/uuid"
@ -60,11 +60,11 @@ type JsonRpc2Client struct {
conn net.Conn
receivedResponsesById map[string]chan JsonRpc2MessageResponse
receivedMessagesChannels map[string]chan JsonRpc2ReceivedMessage
lastTimeErrorMessageSent time.Time
signalCliApiConfig *utils.SignalCliApiConfig
number string
receivedMessagesMutex sync.Mutex
receivedResponsesMutex sync.Mutex
address string
}
func NewJsonRpc2Client(signalCliApiConfig *utils.SignalCliApiConfig, number string) *JsonRpc2Client {
@ -76,10 +76,24 @@ func NewJsonRpc2Client(signalCliApiConfig *utils.SignalCliApiConfig, number stri
}
}
func (r *JsonRpc2Client) Dial(address string) error {
func (r *JsonRpc2Client) Dial(address string, maxRetries int) error {
var err error
r.conn, err = net.Dial("tcp", address)
if err != nil {
r.address = address
connected := false
for i := 0; i < maxRetries; i++ {
r.conn, err = net.Dial("tcp", address)
if err != nil {
log.Info("Waiting for signal-cli to start up in daemon mode...")
time.Sleep(2 * time.Second)
continue
}
connected = true
log.Info("Successfully connected to signal-cli in daemon mode")
break
}
if !connected {
return err
}
@ -207,11 +221,14 @@ func (r *JsonRpc2Client) ReceiveData(number string, receiveWebhookUrl string) {
for {
str, err := connbuf.ReadString('\n')
if err != nil {
elapsed := time.Since(r.lastTimeErrorMessageSent)
if (elapsed) > time.Duration(5*time.Minute) { //avoid spamming the log file and only log the message at max every 5 minutes
log.Error("Couldn't read data for number ", number, ": ", err.Error(), ". Is the number properly registered?")
r.lastTimeErrorMessageSent = time.Now()
log.Error("Lost connection to signal-cli...attempting to reconnect (", err.Error(), ")")
r.conn.Close()
err = r.Dial(r.address, 15)
if err != nil {
log.Fatal("Unable to reconnect to signal-cli: ", err.Error(), "...aborting")
}
connbuf = bufio.NewReader(r.conn)
log.Info("Successfully reconnected to signal-cli")
continue
}
log.Debug("json-rpc received data: ", str)
@ -248,7 +265,7 @@ func (r *JsonRpc2Client) ReceiveData(number string, receiveWebhookUrl string) {
}
}
} else {
log.Error("Received unparsable message: ", str)
log.Warn("Received unparsable message: ", str)
}
}
}

View File

@ -163,7 +163,7 @@ func main() {
jsonRpc2ClientConfigPathPath := *signalCliConfig + "/jsonrpc2.yml"
signalCliApiConfigPath := *signalCliConfig + "/api-config.yml"
signalClient := client.NewSignalClient(*signalCliConfig, *attachmentTmpDir, *avatarTmpDir, signalCliMode, jsonRpc2ClientConfigPathPath, signalCliApiConfigPath, webhookUrl)
err = signalClient.Init()
err = signalClient.Init(15)
if err != nil {
log.Fatal("Couldn't init Signal Client: ", err.Error())
}

View File

@ -14,7 +14,7 @@ import (
const supervisorctlConfigTemplate = `
[program:%s]
process_name=%s
command=bash -c "nc -l -p %d <%s | signal-cli --output=json --config %s%s jsonRpc%s%s >%s"
command=signal-cli --output=json --config %s%s daemon %s%s --tcp 127.0.0.1:%d
autostart=true
autorestart=true
startretries=10
@ -96,7 +96,7 @@ func main() {
supervisorctlConfigFilename := "/etc/supervisor/conf.d/" + "signal-cli-json-rpc-1.conf"
supervisorctlConfig := fmt.Sprintf(supervisorctlConfigTemplate, supervisorctlProgramName, supervisorctlProgramName,
tcpPort, fifoPathname, signalCliConfigDir, trustNewIdentities, signalCliIgnoreAttachments, signalCliIgnoreStories, fifoPathname,
signalCliConfigDir, trustNewIdentities, signalCliIgnoreAttachments, signalCliIgnoreStories, tcpPort,
supervisorctlProgramName, supervisorctlProgramName)
err = ioutil.WriteFile(supervisorctlConfigFilename, []byte(supervisorctlConfig), 0644)