diff --git a/src/api/api.go b/src/api/api.go index 832886b..ff4c322 100644 --- a/src/api/api.go +++ b/src/api/api.go @@ -454,6 +454,13 @@ func wsPing(ws *websocket.Conn, stop chan struct{}) { } } +func StringToBool(input string) bool { + if input == "true" { + return true + } + return false +} + // @Summary Receive Signal Messages. // @Tags Messages // @Description Receives Signal Messages from the Signal Network. If you are running the docker container in normal/native mode, this is a GET endpoint. In json-rpc mode this is a websocket endpoint. @@ -463,6 +470,8 @@ func wsPing(ws *websocket.Conn, stop chan struct{}) { // @Failure 400 {object} Error // @Param number path string true "Registered Phone Number" // @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)" // @Router /v1/receive/{number} [get] func (a *Api) Receive(c *gin.Context) { number := c.Param("number") @@ -486,7 +495,19 @@ func (a *Api) Receive(c *gin.Context) { return } - jsonStr, err := a.signalClient.Receive(number, timeoutInt) + 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'"}) + 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'"}) + return + } + + jsonStr, err := a.signalClient.Receive(number, timeoutInt, StringToBool(ignoreAttachments), StringToBool(ignoreStories)) if err != nil { c.JSON(400, Error{Msg: err.Error()}) return diff --git a/src/client/client.go b/src/client/client.go index 8f13a4c..2462f1a 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -595,12 +595,20 @@ func (s *SignalClient) SendV2(number string, message string, recps []string, bas return ×tamps, nil } -func (s *SignalClient) Receive(number string, timeout int64) (string, error) { +func (s *SignalClient) Receive(number string, timeout int64, ignoreAttachments bool, ignoreStories bool) (string, error) { if s.signalCliMode == JsonRpc { return "", errors.New("Not implemented") } else { command := []string{"--config", s.signalCliConfig, "--output", "json", "-a", number, "receive", "-t", strconv.FormatInt(timeout, 10)} + if ignoreAttachments { + command = append(command, "--ignore-attachments") + } + + if ignoreStories { + command = append(command, "--ignore-stories") + } + out, err := s.cliClient.Execute(true, command, "") if err != nil { return "", err diff --git a/src/docs/docs.go b/src/docs/docs.go index 926e2bb..453a35c 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -241,9 +241,7 @@ var doc = `{ } ], "responses": { - "200": { - "description": "" - }, + "200": {}, "400": { "description": "Bad Request", "schema": { @@ -283,9 +281,7 @@ var doc = `{ } ], "responses": { - "204": { - "description": "" - }, + "204": {}, "400": { "description": "Bad Request", "schema": { @@ -327,9 +323,7 @@ var doc = `{ } ], "responses": { - "204": { - "description": "" - }, + "204": {}, "400": { "description": "Bad Request", "schema": { @@ -371,9 +365,7 @@ var doc = `{ } ], "responses": { - "204": { - "description": "" - }, + "204": {}, "400": { "description": "Bad Request", "schema": { @@ -1156,6 +1148,18 @@ var doc = `{ "description": "Receive timeout in seconds (default: 1)", "name": "timeout", "in": "query" + }, + { + "type": "string", + "description": "Specify whether the attachments of the received message should be ignored", + "name": "ignore_attachments", + "in": "query" + }, + { + "type": "string", + "description": "Specify whether stories should be ignored when receiving messages", + "name": "ignore_stories", + "in": "query" } ], "responses": { @@ -1208,9 +1212,7 @@ var doc = `{ } ], "responses": { - "201": { - "description": "" - }, + "201": {}, "400": { "description": "Bad Request", "schema": { @@ -1482,9 +1484,7 @@ var doc = `{ } ], "responses": { - "204": { - "description": "" - }, + "204": {}, "400": { "description": "Bad Request", "schema": { @@ -1732,17 +1732,41 @@ var doc = `{ "data:\u003cMIME-TYPE\u003e;filename=\u003cFILENAME\u003e;base64\u003ccomma\u003e\u003cBASE64 ENCODED DATA\u003e" ] }, + "mentions": { + "type": "array", + "items": { + "$ref": "#/definitions/client.MessageMention" + } + }, "message": { "type": "string" }, "number": { "type": "string" }, + "quote_author": { + "type": "string" + }, + "quote_mentions": { + "type": "array", + "items": { + "$ref": "#/definitions/client.MessageMention" + } + }, + "quote_message": { + "type": "string" + }, + "quote_timestamp": { + "type": "integer" + }, "recipients": { "type": "array", "items": { "type": "string" } + }, + "sticker": { + "type": "string" } } }, @@ -1834,6 +1858,15 @@ var doc = `{ "build": { "type": "integer" }, + "capabilities": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, "mode": { "type": "string" }, @@ -1911,6 +1944,20 @@ var doc = `{ "type": "string" } } + }, + "client.MessageMention": { + "type": "object", + "properties": { + "author": { + "type": "string" + }, + "length": { + "type": "integer" + }, + "start": { + "type": "integer" + } + } } }, "tags": [ diff --git a/src/docs/swagger.json b/src/docs/swagger.json index 5d59150..d034529 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -225,9 +225,7 @@ } ], "responses": { - "200": { - "description": "" - }, + "200": {}, "400": { "description": "Bad Request", "schema": { @@ -267,9 +265,7 @@ } ], "responses": { - "204": { - "description": "" - }, + "204": {}, "400": { "description": "Bad Request", "schema": { @@ -311,9 +307,7 @@ } ], "responses": { - "204": { - "description": "" - }, + "204": {}, "400": { "description": "Bad Request", "schema": { @@ -355,9 +349,7 @@ } ], "responses": { - "204": { - "description": "" - }, + "204": {}, "400": { "description": "Bad Request", "schema": { @@ -1140,6 +1132,18 @@ "description": "Receive timeout in seconds (default: 1)", "name": "timeout", "in": "query" + }, + { + "type": "string", + "description": "Specify whether the attachments of the received message should be ignored", + "name": "ignore_attachments", + "in": "query" + }, + { + "type": "string", + "description": "Specify whether stories should be ignored when receiving messages", + "name": "ignore_stories", + "in": "query" } ], "responses": { @@ -1192,9 +1196,7 @@ } ], "responses": { - "201": { - "description": "" - }, + "201": {}, "400": { "description": "Bad Request", "schema": { @@ -1466,9 +1468,7 @@ } ], "responses": { - "204": { - "description": "" - }, + "204": {}, "400": { "description": "Bad Request", "schema": { @@ -1716,17 +1716,41 @@ "data:\u003cMIME-TYPE\u003e;filename=\u003cFILENAME\u003e;base64\u003ccomma\u003e\u003cBASE64 ENCODED DATA\u003e" ] }, + "mentions": { + "type": "array", + "items": { + "$ref": "#/definitions/client.MessageMention" + } + }, "message": { "type": "string" }, "number": { "type": "string" }, + "quote_author": { + "type": "string" + }, + "quote_mentions": { + "type": "array", + "items": { + "$ref": "#/definitions/client.MessageMention" + } + }, + "quote_message": { + "type": "string" + }, + "quote_timestamp": { + "type": "integer" + }, "recipients": { "type": "array", "items": { "type": "string" } + }, + "sticker": { + "type": "string" } } }, @@ -1818,6 +1842,15 @@ "build": { "type": "integer" }, + "capabilities": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, "mode": { "type": "string" }, @@ -1895,6 +1928,20 @@ "type": "string" } } + }, + "client.MessageMention": { + "type": "object", + "properties": { + "author": { + "type": "string" + }, + "length": { + "type": "integer" + }, + "start": { + "type": "integer" + } + } } }, "tags": [ diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 4e710bb..3b7965a 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -106,9 +106,7 @@ definitions: api.SendMessageV1: properties: base64_attachment: - example: ''''' OR ''data:;base64,'' OR ''data:;filename=;base64,''' + example: ''''' OR ''data:;base64,'' OR ''data:;filename=;base64,''' type: string is_group: type: boolean @@ -131,14 +129,30 @@ definitions: items: type: string type: array + mentions: + items: + $ref: '#/definitions/client.MessageMention' + type: array message: type: string number: type: string + quote_author: + type: string + quote_mentions: + items: + $ref: '#/definitions/client.MessageMention' + type: array + quote_message: + type: string + quote_timestamp: + type: integer recipients: items: type: string type: array + sticker: + type: string type: object api.TrustIdentityRequest: properties: @@ -197,6 +211,12 @@ definitions: properties: build: type: integer + capabilities: + additionalProperties: + items: + type: string + type: array + type: object mode: type: string version: @@ -248,6 +268,15 @@ definitions: status: type: string type: object + client.MessageMention: + properties: + author: + type: string + length: + type: integer + start: + type: integer + type: object info: contact: {} description: This is the Signal Cli REST API documentation. @@ -396,8 +425,7 @@ paths: produces: - application/json responses: - "200": - description: "" + "200": {} "400": description: Bad Request schema: @@ -424,8 +452,7 @@ paths: produces: - application/json responses: - "204": - description: "" + "204": {} "400": description: Bad Request schema: @@ -453,22 +480,19 @@ paths: produces: - application/json responses: - "204": - description: "" + "204": {} "400": description: Bad Request schema: $ref: '#/definitions/api.Error' - summary: Updates the info associated to a number on the contact list. If the - contact doesn’t exist yet, it will be added. + summary: Updates the info associated to a number on the contact list. If the contact doesn’t exist yet, it will be added. tags: - Contacts /v1/devices/{number}: post: consumes: - application/json - description: Links another device to this device. Only works, if this is the - master device. + description: Links another device to this device. Only works, if this is the master device. parameters: - description: Registered Phone Number in: path @@ -484,8 +508,7 @@ paths: produces: - application/json responses: - "204": - description: "" + "204": {} "400": description: Bad Request schema: @@ -857,8 +880,7 @@ paths: - Identities /v1/identities/{number}/trust/{numberToTrust}: put: - description: Trust an identity. When 'trust_all_known_keys' is set to' true', - all known keys of this user are trusted. **This is only recommended for testing.** + description: Trust an identity. When 'trust_all_known_keys' is set to' true', all known keys of this user are trusted. **This is only recommended for testing.** parameters: - description: Input Data in: body @@ -993,9 +1015,7 @@ paths: get: consumes: - application/json - description: Receives Signal Messages from the Signal Network. If you are running - the docker container in normal/native mode, this is a GET endpoint. In json-rpc - mode this is a websocket endpoint. + description: Receives Signal Messages from the Signal Network. If you are running the docker container in normal/native mode, this is a GET endpoint. In json-rpc mode this is a websocket endpoint. parameters: - description: Registered Phone Number in: path @@ -1006,6 +1026,14 @@ paths: in: query name: timeout type: string + - description: Specify whether the attachments of the received message should be ignored + in: query + name: ignore_attachments + type: string + - description: Specify whether stories should be ignored when receiving messages + in: query + name: ignore_stories + type: string produces: - application/json responses: @@ -1041,8 +1069,7 @@ paths: produces: - application/json responses: - "201": - description: "" + "201": {} "400": description: Bad Request schema: @@ -1089,8 +1116,7 @@ paths: get: consumes: - application/json - description: Check if one or more phone numbers are registered with the Signal - Service. + description: Check if one or more phone numbers are registered with the Signal Service. parameters: - collectionFormat: multi description: Numbers to check @@ -1208,9 +1234,7 @@ paths: post: consumes: - application/json - description: Disables push support for this device. **WARNING:** If *delete_account* - is set to *true*, the account will be deleted from the Signal Server. This - cannot be undone without loss. + description: Disables push support for this device. **WARNING:** If *delete_account* is set to *true*, the account will be deleted from the Signal Server. This cannot be undone without loss. parameters: - description: Registered Phone Number in: path @@ -1225,8 +1249,7 @@ paths: produces: - application/json responses: - "204": - description: "" + "204": {} "400": description: Bad Request schema: diff --git a/src/main.go b/src/main.go index 7abae63..4620238 100644 --- a/src/main.go +++ b/src/main.go @@ -280,14 +280,33 @@ func main() { log.Fatal("AUTO_RECEIVE_SCHEDULE: Couldn't parse accounts.json: ", err.Error()) } + + autoReceiveScheduleReceiveTimeout := utils.GetEnv("AUTO_RECEIVE_SCHEDULE_RECEIVE_TIMEOUT", "10") + autoReceiveScheduleIgnoreAttachments := utils.GetEnv("AUTO_RECEIVE_SCHEDULE_IGNORE_ATTACHMENTS", "false") + autoReceiveScheduleIgnoreStories := utils.GetEnv("AUTO_RECEIVE_SCHEDULE_IGNORE_STORIES", "false") + c := cron.New() c.Schedule(schedule, cron.FuncJob(func() { for _, account := range signalCliAccountConfigs.Accounts { + client := &http.Client{} + log.Debug("AUTO_RECEIVE_SCHEDULE: Calling receive for number ", account.Number) - resp, err := http.Get("http://127.0.0.1:" + port + "/v1/receive/" + account.Number) + req, err := http.NewRequest("GET", "http://127.0.0.1:" + port + "/v1/receive/" + account.Number, nil) if err != nil { log.Error("AUTO_RECEIVE_SCHEDULE: Couldn't call receive for number ", account.Number, ": ", err.Error()) } + + q := req.URL.Query() + q.Add("timeout", autoReceiveScheduleReceiveTimeout) + q.Add("ignore_attachments", autoReceiveScheduleIgnoreAttachments) + q.Add("ignore_stories", autoReceiveScheduleIgnoreStories) + req.URL.RawQuery = q.Encode() + + resp, err := client.Do(req) + if err != nil { + log.Error("AUTO_RECEIVE_SCHEDULE: Couldn't call receive for number ", account.Number, ": ", err.Error()) + } + if resp.StatusCode != 200 { jsonResp, err := ioutil.ReadAll(resp.Body) resp.Body.Close()