diff --git a/src/api/api.go b/src/api/api.go index e9816790..05fbcfac 100644 --- a/src/api/api.go +++ b/src/api/api.go @@ -123,6 +123,11 @@ type Error struct { Msg string `json:"error"` } +type SendMessageError struct { + Msg string `json:"error"` + ChallengeTokens []string `json:"challenge_tokens,omitempty"` +} + type CreateGroupResponse struct { Id string `json:"id"` } @@ -138,7 +143,7 @@ type TrustIdentityRequest struct { } type SendMessageResponse struct { - Timestamp string `json:"timestamp"` + Timestamp string `json:"timestamp"` } type TrustModeRequest struct { @@ -367,7 +372,7 @@ func (a *Api) Send(c *gin.Context) { // @Accept json // @Produce json // @Success 201 {object} SendMessageResponse -// @Failure 400 {object} Error +// @Failure 400 {object} SendMessageError // @Param data body SendMessageV2 true "Input Data" // @Router /v2/send [post] func (a *Api) SendV2(c *gin.Context) { @@ -401,15 +406,19 @@ func (a *Api) SendV2(c *gin.Context) { return } - timestamps, err := a.signalClient.SendV2( + data, err := a.signalClient.SendV2( req.Number, req.Message, req.Recipients, req.Base64Attachments, req.Sticker, req.Mentions, req.QuoteTimestamp, req.QuoteAuthor, req.QuoteMessage, req.QuoteMentions, req.TextMode, req.EditTimestamp) if err != nil { + if data != nil { + c.JSON(400, SendMessageError{Msg: err.Error(), ChallengeTokens: (*data)[0].ChallengeTokens}) + return + } c.JSON(400, Error{Msg: err.Error()}) return } - c.JSON(201, SendMessageResponse{Timestamp: strconv.FormatInt((*timestamps)[0].Timestamp, 10)}) + c.JSON(201, SendMessageResponse{Timestamp: strconv.FormatInt((*data)[0].Timestamp, 10)}) } func (a *Api) handleSignalReceive(ws *websocket.Conn, number string, stop chan struct{}) { diff --git a/src/client/client.go b/src/client/client.go index 6ad9b42b..8ac2f221 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -161,7 +161,8 @@ type SignalCliIdentityEntry struct { } type SendResponse struct { - Timestamp int64 `json:"timestamp"` + Timestamp int64 `json:"timestamp"` + ChallengeTokens []string `json:"challenge_tokens"` } type About struct { @@ -459,6 +460,15 @@ func (s *SignalClient) send(number string, message string, if strings.Contains(err.Error(), signalCliV2GroupError) { return nil, errors.New("Cannot send message to group - please first update your profile.") } + + switch errorType := err.(type) { + case *RateLimitErrorType: + rateLimitError := errors.New(err.Error() + ". Use the attached challenge tokens to lift the rate limit restrictions via the '/v1/accounts/{number}/rate-limit-challenge' endpoint.") + resp.ChallengeTokens = errorType.ChallengeTokens + return &resp, rateLimitError + default: + return nil, err + } return nil, err } } else { diff --git a/src/client/jsonrpc2.go b/src/client/jsonrpc2.go index c04c8c31..08a30009 100644 --- a/src/client/jsonrpc2.go +++ b/src/client/jsonrpc2.go @@ -7,7 +7,6 @@ import ( "net" "time" "sync" - "strings" "github.com/bbernhard/signal-cli-rest-api/utils" uuid "github.com/gofrs/uuid" @@ -45,6 +44,15 @@ type RateLimitResult struct { Token string `json:"token"` } +type RateLimitErrorType struct { + ChallengeTokens []string + Err error +} + +func (r *RateLimitErrorType) Error() string { + return r.Err.Error() +} + type JsonRpc2Client struct { conn net.Conn receivedResponsesById map[string]chan JsonRpc2MessageResponse @@ -151,7 +159,10 @@ func (r *JsonRpc2Client) getRaw(command string, account *string, args interface{ challengeTokens = append(challengeTokens, rateLimitResult.Token) } - return "", errors.New(resp.Err.Message + " Challenge Tokens: " + strings.Join(challengeTokens, ",")) + return "", &RateLimitErrorType{ + ChallengeTokens: challengeTokens, + Err : errors.New(resp.Err.Message), + } } return "", errors.New(resp.Err.Message) } diff --git a/src/docs/docs.go b/src/docs/docs.go index e982b40a..23652480 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -1905,7 +1905,7 @@ var doc = `{ "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/api.Error" + "$ref": "#/definitions/api.SendMessageError" } } } @@ -2089,6 +2089,20 @@ var doc = `{ } } }, + "api.SendMessageError": { + "type": "object", + "properties": { + "challenge_tokens": { + "type": "array", + "items": { + "type": "string" + } + }, + "error": { + "type": "string" + } + } + }, "api.SendMessageResponse": { "type": "object", "properties": { diff --git a/src/docs/swagger.json b/src/docs/swagger.json index 98d9c139..45cf5dae 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -1889,7 +1889,7 @@ "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/api.Error" + "$ref": "#/definitions/api.SendMessageError" } } } @@ -2073,6 +2073,20 @@ } } }, + "api.SendMessageError": { + "type": "object", + "properties": { + "challenge_tokens": { + "type": "array", + "items": { + "type": "string" + } + }, + "error": { + "type": "string" + } + } + }, "api.SendMessageResponse": { "type": "object", "properties": { diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index e26fdde9..3b0a4f6a 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -116,6 +116,15 @@ definitions: registered: type: boolean type: object + api.SendMessageError: + properties: + challenge_tokens: + items: + type: string + type: array + error: + type: string + type: object api.SendMessageResponse: properties: timestamp: @@ -1598,7 +1607,7 @@ paths: "400": description: Bad Request schema: - $ref: '#/definitions/api.Error' + $ref: '#/definitions/api.SendMessageError' summary: Send a signal message. tags: - Messages