From 53d6f52f574d48f1db2d341e06ba2d62b4aca31a Mon Sep 17 00:00:00 2001 From: developersteve Date: Thu, 24 Aug 2023 21:02:13 +1000 Subject: [PATCH 1/5] Update README.md added details about the port env var being set --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8ae4c9b..9181adc 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,8 @@ There are a bunch of environmental variables that can be set inside the docker c * `SWAGGER_IP`: The IP that's used in the Swagger UI for the interactive examples. Defaults to the container ip. +* `PORT`: Defaults to port `8080` unless this env var is set to tell it otherwise. + ## Clients & Libraries | Name | Client | Library | Language | Maintainer | From 936e1c3dd83a1e20d17b07d183b694e413b0b488 Mon Sep 17 00:00:00 2001 From: guangwu Date: Thu, 31 Aug 2023 09:55:18 +0800 Subject: [PATCH 2/5] fix: regularly typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8ae4c9b..37c6786 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ This launches a instance of the REST service accessible under http://localhost:9 > :warning: This setting is only needed in normal/native mode! -[signal-cli](https://github.com/AsamK/signal-cli), which this REST API wrapper is based on, recommends to call `receive` on a regular basis. So, if you are not already calling the `receive` endpoint regularily, it is recommended to set the `AUTO_RECEIVE_SCHEDULE` parameter in the docker-compose.yml file. The `AUTO_RECEIVE_SCHEDULE` accepts cron schedule expressions and automatically calls the `receive` endpoint at the given time. e.g: `0 22 * * *` calls `receive` daily at 10pm. If you are not familiar with cron schedule expressions, you can use this [website](https://crontab.guru). +[signal-cli](https://github.com/AsamK/signal-cli), which this REST API wrapper is based on, recommends to call `receive` on a regular basis. So, if you are not already calling the `receive` endpoint regularly, it is recommended to set the `AUTO_RECEIVE_SCHEDULE` parameter in the docker-compose.yml file. The `AUTO_RECEIVE_SCHEDULE` accepts cron schedule expressions and automatically calls the `receive` endpoint at the given time. e.g: `0 22 * * *` calls `receive` daily at 10pm. If you are not familiar with cron schedule expressions, you can use this [website](https://crontab.guru). **WARNING** Calling `receive` will fetch all the messages for the registered Signal number from the Signal Server! So, if you are using the REST API for receiving messages, it's _not_ a good idea to use the `AUTO_RECEIVE_SCHEDULE` parameter, as you might lose some messages that way. From c26d83583b011a88ba0e6a38cd732e036b7c4dde Mon Sep 17 00:00:00 2001 From: Kostia Rybnikov Date: Thu, 31 Aug 2023 10:36:36 +0300 Subject: [PATCH 3/5] Upgrade signal cli to 0.12.1 --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index d72f9b4..96fe257 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ -ARG SIGNAL_CLI_VERSION=0.12.0 +ARG SIGNAL_CLI_VERSION=0.12.1 ARG LIBSIGNAL_CLIENT_VERSION=0.30.0 -ARG SIGNAL_CLI_NATIVE_PACKAGE_VERSION=0.12.0-1 +ARG SIGNAL_CLI_NATIVE_PACKAGE_VERSION=0.12.1-1 ARG SWAG_VERSION=1.6.7 ARG GRAALVM_JAVA_VERSION=17 From 068a124a1a12b18da0319e7f2dc3f0de9f3f14d1 Mon Sep 17 00:00:00 2001 From: Kostia Rybnikov Date: Thu, 31 Aug 2023 10:36:52 +0300 Subject: [PATCH 4/5] Accept max_messages param --- src/api/api.go | 14 +++++++++++--- src/client/client.go | 19 ++++++++++++------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/api/api.go b/src/api/api.go index 44d5813..f105f4c 100644 --- a/src/api/api.go +++ b/src/api/api.go @@ -473,6 +473,7 @@ func StringToBool(input string) bool { // @Param timeout query string false "Receive timeout in seconds (default: 1)" // @Param ignore_attachments query string false "Specify whether the attachments of the received message should be ignored" (default: false)" // @Param ignore_stories query string false "Specify whether stories should be ignored when receiving messages" (default: false)" +// @Param max_messages query string false "Specify the maximum number of messages to receive (default: unlimited)". Not available in json-rpc mode. // @Router /v1/receive/{number} [get] func (a *Api) Receive(c *gin.Context) { number := c.Param("number") @@ -496,19 +497,26 @@ func (a *Api) Receive(c *gin.Context) { return } + maxMessages := c.DefaultQuery("max_messages", "0") + maxMessagesInt, err := strconv.ParseInt(maxMessages, 10, 32) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - max_messages needs to be numeric!"}) + return + } + ignoreAttachments := c.DefaultQuery("ignore_attachments", "false") if ignoreAttachments != "true" && ignoreAttachments != "false" { - c.JSON(400, Error {Msg: "Couldn't process request - ignore_attachments parameter needs to be either 'true' or 'false'"}) + c.JSON(400, Error{Msg: "Couldn't process request - ignore_attachments parameter needs to be either 'true' or 'false'"}) return } ignoreStories := c.DefaultQuery("ignore_stories", "false") if ignoreStories != "true" && ignoreStories != "false" { - c.JSON(400, Error {Msg: "Couldn't process request - ignore_stories parameter needs to be either 'true' or 'false'"}) + c.JSON(400, Error{Msg: "Couldn't process request - ignore_stories parameter needs to be either 'true' or 'false'"}) return } - jsonStr, err := a.signalClient.Receive(number, timeoutInt, StringToBool(ignoreAttachments), StringToBool(ignoreStories)) + jsonStr, err := a.signalClient.Receive(number, timeoutInt, StringToBool(ignoreAttachments), StringToBool(ignoreStories), maxMessagesInt) if err != nil { c.JSON(400, Error{Msg: err.Error()}) return diff --git a/src/client/client.go b/src/client/client.go index cb9b57c..beb5e6d 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -474,12 +474,12 @@ func (s *SignalClient) send(number string, message string, func (s *SignalClient) About() About { about := About{ - SupportedApiVersions: []string{"v1", "v2"}, - BuildNr: 2, - Mode: getSignalCliModeString(s.signalCliMode), - Version: utils.GetEnv("BUILD_VERSION", "unset"), - Capabilities: map[string][]string{"v2/send": []string{"quotes", "mentions"}}, - } + SupportedApiVersions: []string{"v1", "v2"}, + BuildNr: 2, + Mode: getSignalCliModeString(s.signalCliMode), + Version: utils.GetEnv("BUILD_VERSION", "unset"), + Capabilities: map[string][]string{"v2/send": []string{"quotes", "mentions"}}, + } return about } @@ -610,7 +610,7 @@ func (s *SignalClient) SendV2(number string, message string, recps []string, bas return ×tamps, nil } -func (s *SignalClient) Receive(number string, timeout int64, ignoreAttachments bool, ignoreStories bool) (string, error) { +func (s *SignalClient) Receive(number string, timeout int64, ignoreAttachments bool, ignoreStories bool, maxMessages int64) (string, error) { if s.signalCliMode == JsonRpc { return "", errors.New("Not implemented") } else { @@ -624,6 +624,11 @@ func (s *SignalClient) Receive(number string, timeout int64, ignoreAttachments b command = append(command, "--ignore-stories") } + if maxMessages > 0 { + command = append(command, "--max-messages") + command = append(command, strconv.FormatInt(maxMessages, 10)) + } + out, err := s.cliClient.Execute(true, command, "") if err != nil { return "", err From 7aa1fddcd8f25ce25af39462547094e60e8c7b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Sep 2023 16:03:34 +0200 Subject: [PATCH 5/5] fix: include $stdin in server response on error Motivation ---------- The way how I fixed this is that both `Stdout` and `Stderr` are responded back to the client. I don't think it's good practice to discard `$stderr` on success and to discard `$stdout` on error. Let me know what you think. I'm still very new to Golang. How to test ----------- 1. First of all you must be able to reproduce "CAPTCHA proof required" error (I guess you need to send a lot of messages to the same number) 2. Execute: ``` curl -X POST -H "Content-Type: application/json" 'http://localhost:8080/v2/send' \ -d '{"message": "Test via Signal API!", "number": "", "recipients": [ "" ]} ' ``` 3. See in the JSON response: ``` {"error":"Failed to send (some) messages:\n+49176xxxxxxxx: CAPTCHA proof required for sending to \"+49176xxxxxxxx\", available options \"RECAPTCHA, PUSH_CHALLENGE\" with challenge token \"1f209ee0-d487-4efc-xxxx-xxxxxxxxxxxx\", or wait \"86400\" seconds.\nTo get the captcha token, go to https://signalcaptchas.org/challenge/generate.html\nCheck the developer tools (F12) console for a failed redirect to signalcaptcha://\nEverything after signalcaptcha:// is the captcha token.\nUse the following command to submit the captcha token:\nsignal-cli submitRateLimitChallenge --challenge CHALLENGE_TOKEN --captcha CAPTCHA_TOKEN\nxxxxxxxxxxxxx\nFailed to send message\n"} ``` fix #403 --- src/client/cli.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/client/cli.go b/src/client/cli.go index 991963f..2aeb19f 100644 --- a/src/client/cli.go +++ b/src/client/cli.go @@ -83,10 +83,9 @@ func (s *CliClient) Execute(wait bool, args []string, stdin string) (string, err cmd.Stdin = strings.NewReader(stdin) } if wait { - var errBuffer bytes.Buffer - var outBuffer bytes.Buffer - cmd.Stderr = &errBuffer - cmd.Stdout = &outBuffer + var combinedOutput bytes.Buffer + cmd.Stdout = &combinedOutput + cmd.Stderr = &combinedOutput err := cmd.Start() if err != nil { @@ -106,11 +105,11 @@ func (s *CliClient) Execute(wait bool, args []string, stdin string) (string, err return "", errors.New("process killed as timeout reached") case err := <-done: if err != nil { - return "", errors.New(errBuffer.String()) + return "", errors.New(combinedOutput.String()) } } - return outBuffer.String(), nil + return combinedOutput.String(), nil } else { stdout, err := cmd.StdoutPipe() if err != nil {