From efee49e7924028488ae1c7f672d57edf490c97e9 Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Wed, 13 Mar 2024 21:10:23 +0100 Subject: [PATCH] add API endpoints to list and add sticker packs see #398 --- src/api/api.go | 67 ++++++++++++++++++++++- src/client/client.go | 74 +++++++++++++++++++++++++ src/docs/docs.go | 122 +++++++++++++++++++++++++++++++++++++++++- src/docs/swagger.json | 122 +++++++++++++++++++++++++++++++++++++++++- src/docs/swagger.yaml | 80 +++++++++++++++++++++++++++ src/main.go | 9 ++++ 6 files changed, 471 insertions(+), 3 deletions(-) diff --git a/src/api/api.go b/src/api/api.go index e252821..e981679 100644 --- a/src/api/api.go +++ b/src/api/api.go @@ -175,7 +175,12 @@ type UpdateAccountSettingsRequest struct { } type SetUsernameRequest struct { - Username string `json:username" example:"test"` + Username string `json:"username" example:"test"` +} + +type AddStickerPackRequest struct { + PackId string `json:"pack_id" example:"9a32eda01a7a28574f2eb48668ae0dc4"` + PackKey string `json:"pack_key" example:"19546e18eba0ff69dea78eb591465289d39e16f35e58389ae779d4f9455aff3a"` } type Api struct { @@ -1823,3 +1828,63 @@ func (a *Api) RemoveUsername(c *gin.Context) { } c.Status(http.StatusNoContent) } + +// @Summary List Installed Sticker Packs. +// @Tags Sticker Packs +// @Description List Installed Sticker Packs. +// @Accept json +// @Produce json +// @Param number path string true "Registered Phone Number" +// @Success 204 +// @Failure 400 {object} Error +// @Success 200 {object} []client.ListInstalledStickerPacksResponse +// @Router /v1/sticker-packs/{number} [get] +func (a *Api) ListInstalledStickerPacks(c *gin.Context) { + number := c.Param("number") + if number == "" { + c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) + return + } + + installedStickerPacks, err := a.signalClient.ListInstalledStickerPacks(number) + if err != nil { + c.JSON(400, Error{Msg: err.Error()}) + return + } + + c.JSON(200, installedStickerPacks) +} + +// @Summary Add Sticker Pack. +// @Tags Sticker Packs +// @Description In order to add a sticker pack, browse to https://signalstickers.org/ and select the sticker pack you want to add. Then, press the "Add to Signal" button. If you look at the address bar in your browser you should see an URL in this format: https://signal.art/addstickers/#pack_id=XXX&pack_key=YYY, where XXX is the pack_id and YYY is the pack_key. +// @Accept json +// @Produce json +// @Param number path string true "Registered Phone Number" +// @Success 204 +// @Failure 400 {object} Error +// @Param data body AddStickerPackRequest true "Request" +// @Router /v1/sticker-packs/{number} [post] +func (a *Api) AddStickerPack(c *gin.Context) { + number := c.Param("number") + if number == "" { + c.JSON(400, Error{Msg: "Couldn't process request - number missing"}) + return + } + + var req AddStickerPackRequest + err := c.BindJSON(&req) + if err != nil { + c.JSON(400, Error{Msg: "Couldn't process request - invalid request"}) + return + } + + + err = a.signalClient.AddStickerPack(number, req.PackId, req.PackKey) + if err != nil { + c.JSON(400, Error{Msg: err.Error()}) + return + } + + c.Status(201) +} diff --git a/src/client/client.go b/src/client/client.go index ba0e51f..6ad9b42 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -182,6 +182,14 @@ type SetUsernameResponse struct { UsernameLink string `json:"username_link"` } +type ListInstalledStickerPacksResponse struct { + PackId string `json:"pack_id"` + Url string `json:"url"` + Installed bool `json:"installed"` + Title string `json:"title"` + Author string `json:"author"` +} + func cleanupTmpFiles(paths []string) { for _, path := range paths { os.Remove(path) @@ -1925,3 +1933,69 @@ func (s *SignalClient) UpdateAccountSettings(number string, discoverableByNumber return err } } + +func (s *SignalClient) ListInstalledStickerPacks(number string) ([]ListInstalledStickerPacksResponse, error) { + type ListInstalledStickerPacksSignalCliResponse struct { + PackId string `json:"packId"` + Url string `json:"url"` + Installed bool `json:"installed"` + Title string `json:"title"` + Author string `json:"author"` + } + + resp := []ListInstalledStickerPacksResponse{} + + var err error + var rawData string + if s.signalCliMode == JsonRpc { + jsonRpc2Client, err := s.getJsonRpc2Client() + if err != nil { + return resp, err + } + rawData, err = jsonRpc2Client.getRaw("listStickerPacks", &number, nil) + if err != nil { + return resp, err + } + } else { + cmd := []string{"--config", s.signalCliConfig, "-o", "json", "-a", number, "listStickerPacks"} + rawData, err = s.cliClient.Execute(true, cmd, "") + if err != nil { + return resp, err + } + } + + var signalCliResp []ListInstalledStickerPacksSignalCliResponse + err = json.Unmarshal([]byte(rawData), &signalCliResp) + if err != nil { + return resp, errors.New("Couldn't process request - invalid signal-cli response") + } + + for _, value := range signalCliResp { + resp = append(resp, ListInstalledStickerPacksResponse{PackId: value.PackId, Url: value.Url, + Installed: value.Installed, Title: value.Title, Author: value.Author}) + } + + return resp, nil +} + +func (s *SignalClient) AddStickerPack(number string, packId string, packKey string) error { + + stickerPackUri := fmt.Sprintf(`https://signal.art/addstickers/#pack_id=%s&pack_key=%s`, packId, packKey) + + if s.signalCliMode == JsonRpc { + type Request struct { + Uri string `json:"uri"` + } + request := Request{Uri: stickerPackUri} + jsonRpc2Client, err := s.getJsonRpc2Client() + if err != nil { + return err + } + _, err = jsonRpc2Client.getRaw("addStickerPack", &number, request) + return err + } else { + cmd := []string{"--config", s.signalCliConfig, "-o", "json", "-a", number, "addStickerPack", "--uri", stickerPackUri} + _, err := s.cliClient.Execute(true, cmd, "") + return err + } +} diff --git a/src/docs/docs.go b/src/docs/docs.go index ad2528c..e982b40 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -1656,6 +1656,88 @@ var doc = `{ } } }, + "/v1/sticker-packs/{number}": { + "get": { + "description": "List Installed Sticker Packs.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Sticker Packs" + ], + "summary": "List Installed Sticker Packs.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/client.ListInstalledStickerPacksResponse" + } + } + }, + "204": {}, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "post": { + "description": "In order to add a sticker pack, browse to https://signalstickers.org/ and select the sticker pack you want to add. Then, press the \"Add to Signal\" button. If you look at the address bar in your browser you should see an URL in this format: https://signal.art/addstickers/#pack_id=XXX\u0026pack_key=YYY, where XXX is the pack_id and YYY is the pack_key.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Sticker Packs" + ], + "summary": "Add Sticker Pack.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Request", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.AddStickerPackRequest" + } + } + ], + "responses": { + "204": {}, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, "/v1/typing-indicator/{number}": { "put": { "description": "Show Typing Indicator.", @@ -1839,6 +1921,19 @@ var doc = `{ } } }, + "api.AddStickerPackRequest": { + "type": "object", + "properties": { + "pack_id": { + "type": "string", + "example": "9a32eda01a7a28574f2eb48668ae0dc4" + }, + "pack_key": { + "type": "string", + "example": "19546e18eba0ff69dea78eb591465289d39e16f35e58389ae779d4f9455aff3a" + } + } + }, "api.ChangeGroupAdminsRequest": { "type": "object", "properties": { @@ -2092,7 +2187,8 @@ var doc = `{ "type": "object", "properties": { "username": { - "type": "string" + "type": "string", + "example": "test" } } }, @@ -2296,6 +2392,26 @@ var doc = `{ } } }, + "client.ListInstalledStickerPacksResponse": { + "type": "object", + "properties": { + "author": { + "type": "string" + }, + "installed": { + "type": "boolean" + }, + "pack_id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, "client.MessageMention": { "type": "object", "properties": { @@ -2362,6 +2478,10 @@ var doc = `{ { "description": "Search the Signal Service.", "name": "Search" + }, + { + "description": "List and Install Sticker Packs", + "name": "Sticker Packs" } ] }` diff --git a/src/docs/swagger.json b/src/docs/swagger.json index 116c8b6..98d9c13 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -1640,6 +1640,88 @@ } } }, + "/v1/sticker-packs/{number}": { + "get": { + "description": "List Installed Sticker Packs.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Sticker Packs" + ], + "summary": "List Installed Sticker Packs.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/client.ListInstalledStickerPacksResponse" + } + } + }, + "204": {}, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + }, + "post": { + "description": "In order to add a sticker pack, browse to https://signalstickers.org/ and select the sticker pack you want to add. Then, press the \"Add to Signal\" button. If you look at the address bar in your browser you should see an URL in this format: https://signal.art/addstickers/#pack_id=XXX\u0026pack_key=YYY, where XXX is the pack_id and YYY is the pack_key.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Sticker Packs" + ], + "summary": "Add Sticker Pack.", + "parameters": [ + { + "type": "string", + "description": "Registered Phone Number", + "name": "number", + "in": "path", + "required": true + }, + { + "description": "Request", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/api.AddStickerPackRequest" + } + } + ], + "responses": { + "204": {}, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/api.Error" + } + } + } + } + }, "/v1/typing-indicator/{number}": { "put": { "description": "Show Typing Indicator.", @@ -1823,6 +1905,19 @@ } } }, + "api.AddStickerPackRequest": { + "type": "object", + "properties": { + "pack_id": { + "type": "string", + "example": "9a32eda01a7a28574f2eb48668ae0dc4" + }, + "pack_key": { + "type": "string", + "example": "19546e18eba0ff69dea78eb591465289d39e16f35e58389ae779d4f9455aff3a" + } + } + }, "api.ChangeGroupAdminsRequest": { "type": "object", "properties": { @@ -2076,7 +2171,8 @@ "type": "object", "properties": { "username": { - "type": "string" + "type": "string", + "example": "test" } } }, @@ -2280,6 +2376,26 @@ } } }, + "client.ListInstalledStickerPacksResponse": { + "type": "object", + "properties": { + "author": { + "type": "string" + }, + "installed": { + "type": "boolean" + }, + "pack_id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, "client.MessageMention": { "type": "object", "properties": { @@ -2346,6 +2462,10 @@ { "description": "Search the Signal Service.", "name": "Search" + }, + { + "description": "List and Install Sticker Packs", + "name": "Sticker Packs" } ] } \ No newline at end of file diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index ba8543d..e26fdde 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -5,6 +5,15 @@ definitions: uri: type: string type: object + api.AddStickerPackRequest: + properties: + pack_id: + example: 9a32eda01a7a28574f2eb48668ae0dc4 + type: string + pack_key: + example: 19546e18eba0ff69dea78eb591465289d39e16f35e58389ae779d4f9455aff3a + type: string + type: object api.ChangeGroupAdminsRequest: properties: admins: @@ -173,6 +182,7 @@ definitions: api.SetUsernameRequest: properties: username: + example: test type: string type: object api.TrustIdentityRequest: @@ -305,6 +315,19 @@ definitions: status: type: string type: object + client.ListInstalledStickerPacksResponse: + properties: + author: + type: string + installed: + type: boolean + pack_id: + type: string + title: + type: string + url: + type: string + type: object client.MessageMention: properties: author: @@ -1410,6 +1433,61 @@ paths: summary: Send a signal message. tags: - Messages + /v1/sticker-packs/{number}: + get: + consumes: + - application/json + description: List Installed Sticker Packs. + parameters: + - description: Registered Phone Number + in: path + name: number + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/client.ListInstalledStickerPacksResponse' + type: array + "204": {} + "400": + description: Bad Request + schema: + $ref: '#/definitions/api.Error' + summary: List Installed Sticker Packs. + tags: + - Sticker Packs + post: + consumes: + - application/json + description: 'In order to add a sticker pack, browse to https://signalstickers.org/ and select the sticker pack you want to add. Then, press the "Add to Signal" button. If you look at the address bar in your browser you should see an URL in this format: https://signal.art/addstickers/#pack_id=XXX&pack_key=YYY, where XXX is the pack_id and YYY is the pack_key.' + parameters: + - description: Registered Phone Number + in: path + name: number + required: true + type: string + - description: Request + in: body + name: data + required: true + schema: + $ref: '#/definitions/api.AddStickerPackRequest' + produces: + - application/json + responses: + "204": {} + "400": + description: Bad Request + schema: + $ref: '#/definitions/api.Error' + summary: Add Sticker Pack. + tags: + - Sticker Packs /v1/typing-indicator/{number}: delete: consumes: @@ -1546,3 +1624,5 @@ tags: name: Reactions - description: Search the Signal Service. name: Search +- description: List and Install Sticker Packs + name: Sticker Packs diff --git a/src/main.go b/src/main.go index 003a7da..1439352 100644 --- a/src/main.go +++ b/src/main.go @@ -52,6 +52,9 @@ import ( // @tag.name Search // @tag.description Search the Signal Service. +// @tag.name Sticker Packs +// @tag.description List and Install Sticker Packs + // @BasePath / func main() { signalCliConfig := flag.String("signal-cli-config", "/home/.local/share/signal-cli/", "Config directory where signal-cli config is stored") @@ -222,6 +225,12 @@ func main() { attachments.GET(":attachment", api.ServeAttachment) } + stickerPacks := v1.Group("sticker-packs") + { + stickerPacks.GET(":number", api.ListInstalledStickerPacks) + stickerPacks.POST(":number", api.AddStickerPack) + } + profiles := v1.Group("profiles") { profiles.PUT(":number", api.UpdateProfile)