From 379ff16ca66ff949ad57294dd7e04ff159a65f4c Mon Sep 17 00:00:00 2001 From: Dan Gabel Date: Wed, 11 Feb 2026 21:40:20 -0600 Subject: [PATCH 1/5] direct uuid contact search --- src/client/client.go | 79 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 13 deletions(-) diff --git a/src/client/client.go b/src/client/client.go index 9ec41f8..63770e6 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -2601,8 +2601,6 @@ func (s *SignalClient) AddStickerPack(number string, packId string, packKey stri return err } } - -func (s *SignalClient) ListContacts(number string) ([]ListContactsResponse, error) { type SignalCliProfileResponse struct { LastUpdateTimestamp int64 `json:"lastUpdateTimestamp"` GivenName string `json:"givenName"` @@ -2610,8 +2608,7 @@ func (s *SignalClient) ListContacts(number string) ([]ListContactsResponse, erro About string `json:"about"` HasAvatar bool `json:"hasAvatar"` } - - type ListContactsSignlCliResponse struct { +type ListContactsSignlCliResponse struct { Number string `json:"number"` Uuid string `json:"uuid"` Name string `json:"name"` @@ -2628,8 +2625,15 @@ func (s *SignalClient) ListContacts(number string) ([]ListContactsResponse, erro NickFamilyName string `json:"nickFamilyName"` } +func (s *SignalClient) ListContacts(number string) ([]ListContactsResponse, error) { resp := []ListContactsResponse{} - + type Request struct { + + AllRecipients bool `json:"allRecipients"` + } + + req :=Request{ AllRecipients: true} + var err error var rawData string @@ -2638,7 +2642,7 @@ func (s *SignalClient) ListContacts(number string) ([]ListContactsResponse, erro if err != nil { return nil, err } - rawData, err = jsonRpc2Client.getRaw("listContacts", &number, nil) + rawData, err = jsonRpc2Client.getRaw("listContacts", &number, req) if err != nil { return resp, err } @@ -2684,19 +2688,68 @@ func (s *SignalClient) ListContacts(number string) ([]ListContactsResponse, erro return resp, nil } -func (s *SignalClient) ListContact(number string, uuid string) (ListContactsResponse, error) { - contacts, err := s.ListContacts(number) +func (s *SignalClient) ListContact(number string, uuid string) ([]ListContactsResponse, error) { + + resp := []ListContactsResponse{} + type Request struct { + Recipient string `json:"recipient"` + AllRecipients bool `json:"allRecipients"` + } + + req :=Request{ Recipient: uuid, AllRecipients: true} + + var err error + var rawData string + + if s.signalCliMode == JsonRpc { + jsonRpc2Client, err := s.getJsonRpc2Client() + if err != nil { + return nil, err + } + rawData, err = jsonRpc2Client.getRaw("listContacts", &number, req) + if err != nil { + return resp, err + } + } else { + cmd := []string{"--config", s.signalCliConfig, "-o", "json", "-a", number, "listContacts"} + rawData, err = s.cliClient.Execute(true, cmd, "") + if err != nil { + return resp, err + } + } + + var signalCliResp []ListContactsSignlCliResponse + err = json.Unmarshal([]byte(rawData), &signalCliResp) if err != nil { - return ListContactsResponse{}, err + log.Error("Couldn't list contacts", err.Error()) + return resp, errors.New("Couldn't process request - invalid signal-cli response") } - for _, contact := range contacts { - if contact.Uuid == uuid { - return contact, nil + for _, value := range signalCliResp { + entry := ListContactsResponse{ + Number: value.Number, + Uuid: value.Uuid, + Name: value.Name, + ProfileName: value.ProfileName, + Username: value.Username, + Color: value.Color, + Blocked: value.Blocked, + MessageExpiration: value.MessageExpiration, + Note: value.Note, + GivenName: value.GivenName, } + entry.Profile.About = value.Profile.About + entry.Profile.HasAvatar = value.Profile.HasAvatar + entry.Profile.LastUpdatedTimestamp = value.Profile.LastUpdateTimestamp + entry.Profile.GivenName = value.Profile.GivenName + entry.Profile.FamilyName = value.Profile.FamilyName + entry.Nickname.Name = value.Nickname + entry.Nickname.GivenName = value.NickGivenName + entry.Nickname.FamilyName = value.NickFamilyName + resp = append(resp, entry) } - return ListContactsResponse{}, &NotFoundError{Description: "No contact with that id (" + uuid + ") found"} + return resp, err } func (s *SignalClient) SetPin(number string, registrationLockPin string) error { From 6ec6e198d7aad4672ec9072de2fcc5decbe10efe Mon Sep 17 00:00:00 2001 From: Dan Gabel Date: Thu, 12 Feb 2026 15:36:42 -0600 Subject: [PATCH 2/5] Adds --all-recipient handling for ListContact endpoints --- src/api/api.go | 18 +++++++-- src/client/client.go | 91 +++++++++++++++++++++++-------------------- src/docs/docs.go | 71 ++++++++++++++++++++------------- src/docs/swagger.json | 71 ++++++++++++++++++++------------- src/docs/swagger.yaml | 50 ++++++++++++++---------- 5 files changed, 179 insertions(+), 122 deletions(-) diff --git a/src/api/api.go b/src/api/api.go index c4c0731..f286979 100644 --- a/src/api/api.go +++ b/src/api/api.go @@ -2408,6 +2408,7 @@ func (a *Api) AddStickerPack(c *gin.Context) { // @Produce json // @Success 200 {object} []client.ListContactsResponse // @Param number path string true "Registered Phone Number" +// @Param all_recipients query string false "Include all known recipients, not only contacts." (default: false)" // @Router /v1/contacts/{number} [get] func (a *Api) ListContacts(c *gin.Context) { number, err := url.PathUnescape(c.Param("number")) @@ -2421,8 +2422,12 @@ func (a *Api) ListContacts(c *gin.Context) { return } - contacts, err := a.signalClient.ListContacts(number) - + allRecipients := c.DefaultQuery("all_recipients", "false") + if allRecipients != "true" && allRecipients != "false" { + c.JSON(400, Error{Msg: "Couldn't process request - all_recipients parameter needs to be either 'true' or 'false'"}) + return + } + contacts, err := a.signalClient.ListContacts(number, StringToBool(allRecipients)) if err != nil { c.JSON(400, Error{Msg: err.Error()}) return @@ -2437,6 +2442,7 @@ func (a *Api) ListContacts(c *gin.Context) { // @Produce json // @Success 200 {object} client.ListContactsResponse // @Param number path string true "Registered Phone Number" +// @Param all_recipients query string false "Include all known recipients, not only contacts." (default: false)" // @Router /v1/contacts/{number}/{uuid} [get] func (a *Api) ListContact(c *gin.Context) { number, err := url.PathUnescape(c.Param("number")) @@ -2456,7 +2462,13 @@ func (a *Api) ListContact(c *gin.Context) { return } - contact, err := a.signalClient.ListContact(number, uuid) + allRecipients := c.DefaultQuery("all_recipients", "false") + if allRecipients != "true" && allRecipients != "false" { + c.JSON(400, Error{Msg: "Couldn't process request - all_recipients parameter needs to be either 'true' or 'false'"}) + return + } + + contact, err := a.signalClient.ListContact(number, uuid, StringToBool(allRecipients)) if err != nil { switch err.(type) { case *client.NotFoundError: diff --git a/src/client/client.go b/src/client/client.go index 63770e6..3c882b3 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -2625,19 +2625,17 @@ type ListContactsSignlCliResponse struct { NickFamilyName string `json:"nickFamilyName"` } -func (s *SignalClient) ListContacts(number string) ([]ListContactsResponse, error) { +func (s *SignalClient) ListContacts(number string, allRecipients bool) ([]ListContactsResponse, error) { resp := []ListContactsResponse{} - type Request struct { - - AllRecipients bool `json:"allRecipients"` - } - - req :=Request{ AllRecipients: true} - + var err error var rawData string if s.signalCliMode == JsonRpc { + type Request struct { + AllRecipients bool `json:"allRecipients"` + } + req :=Request{ AllRecipients: allRecipients } jsonRpc2Client, err := s.getJsonRpc2Client() if err != nil { return nil, err @@ -2648,6 +2646,9 @@ func (s *SignalClient) ListContacts(number string) ([]ListContactsResponse, erro } } else { cmd := []string{"--config", s.signalCliConfig, "-o", "json", "-a", number, "listContacts"} + if !allRecipients { + cmd = append(cmd, "--all-recipients") + } rawData, err = s.cliClient.Execute(true, cmd, "") if err != nil { return resp, err @@ -2688,23 +2689,21 @@ func (s *SignalClient) ListContacts(number string) ([]ListContactsResponse, erro return resp, nil } -func (s *SignalClient) ListContact(number string, uuid string) ([]ListContactsResponse, error) { +func (s *SignalClient) ListContact(number string, uuid string, allRecipients bool) (ListContactsResponse, error) { + var resp ListContactsResponse + + var err error + var rawData string - resp := []ListContactsResponse{} + if s.signalCliMode == JsonRpc { type Request struct { Recipient string `json:"recipient"` AllRecipients bool `json:"allRecipients"` } - - req :=Request{ Recipient: uuid, AllRecipients: true} - - var err error - var rawData string - - if s.signalCliMode == JsonRpc { + req :=Request{ Recipient: uuid, AllRecipients: allRecipients } jsonRpc2Client, err := s.getJsonRpc2Client() if err != nil { - return nil, err + return resp, err } rawData, err = jsonRpc2Client.getRaw("listContacts", &number, req) if err != nil { @@ -2712,6 +2711,10 @@ func (s *SignalClient) ListContact(number string, uuid string) ([]ListContactsRe } } else { cmd := []string{"--config", s.signalCliConfig, "-o", "json", "-a", number, "listContacts"} + if allRecipients { + cmd = append(cmd, "--all-recipients") + } + cmd = append(cmd, uuid) rawData, err = s.cliClient.Execute(true, cmd, "") if err != nil { return resp, err @@ -2725,31 +2728,33 @@ func (s *SignalClient) ListContact(number string, uuid string) ([]ListContactsRe return resp, errors.New("Couldn't process request - invalid signal-cli response") } - for _, value := range signalCliResp { - entry := ListContactsResponse{ - Number: value.Number, - Uuid: value.Uuid, - Name: value.Name, - ProfileName: value.ProfileName, - Username: value.Username, - Color: value.Color, - Blocked: value.Blocked, - MessageExpiration: value.MessageExpiration, - Note: value.Note, - GivenName: value.GivenName, - } - entry.Profile.About = value.Profile.About - entry.Profile.HasAvatar = value.Profile.HasAvatar - entry.Profile.LastUpdatedTimestamp = value.Profile.LastUpdateTimestamp - entry.Profile.GivenName = value.Profile.GivenName - entry.Profile.FamilyName = value.Profile.FamilyName - entry.Nickname.Name = value.Nickname - entry.Nickname.GivenName = value.NickGivenName - entry.Nickname.FamilyName = value.NickFamilyName - resp = append(resp, entry) - } - - return resp, err + if len(signalCliResp) == 0 { + return resp, &NotFoundError{Description: "No user with that id (" + uuid + ") found"} + } + + var value = signalCliResp[0] + contact := ListContactsResponse{ + Number: value.Number, + Uuid: value.Uuid, + Name: value.Name, + ProfileName: value.ProfileName, + Username: value.Username, + Color: value.Color, + Blocked: value.Blocked, + MessageExpiration: value.MessageExpiration, + Note: value.Note, + GivenName: value.GivenName, + } + contact.Profile.About = value.Profile.About + contact.Profile.HasAvatar = value.Profile.HasAvatar + contact.Profile.LastUpdatedTimestamp = value.Profile.LastUpdateTimestamp + contact.Profile.GivenName = value.Profile.GivenName + contact.Profile.FamilyName = value.Profile.FamilyName + contact.Nickname.Name = value.Nickname + contact.Nickname.GivenName = value.NickGivenName + contact.Nickname.FamilyName = value.NickFamilyName + + return contact, nil } func (s *SignalClient) SetPin(number string, registrationLockPin string) error { diff --git a/src/docs/docs.go b/src/docs/docs.go index f4fdbf7..3bf19e9 100644 --- a/src/docs/docs.go +++ b/src/docs/docs.go @@ -573,6 +573,12 @@ const docTemplate = `{ "name": "number", "in": "path", "required": true + }, + { + "type": "string", + "description": "Include all known recipients, not only contacts.", + "name": "all_recipients", + "in": "query" } ], "responses": { @@ -682,6 +688,12 @@ const docTemplate = `{ "name": "number", "in": "path", "required": true + }, + { + "type": "string", + "description": "Include all known recipients, not only contacts.", + "name": "all_recipients", + "in": "query" } ], "responses": { @@ -2653,7 +2665,7 @@ const docTemplate = `{ "type": "string" }, "permissions": { - "$ref": "#/definitions/api.GroupPermissions" + "$ref": "#/definitions/data.GroupPermissions" } } }, @@ -2727,32 +2739,6 @@ const docTemplate = `{ } } }, - "api.GroupPermissions": { - "type": "object", - "properties": { - "add_members": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - }, - "edit_group": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - }, - "send_messages": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - } - } - }, "api.LoggingConfiguration": { "type": "object", "properties": { @@ -3085,7 +3071,7 @@ const docTemplate = `{ "type": "string" }, "permissions": { - "$ref": "#/definitions/api.GroupPermissions" + "$ref": "#/definitions/data.GroupPermissions" } } }, @@ -3230,6 +3216,9 @@ const docTemplate = `{ "items": { "type": "string" } + }, + "permissions": { + "$ref": "#/definitions/data.GroupPermissions" } } }, @@ -3359,6 +3348,32 @@ const docTemplate = `{ } } }, + "data.GroupPermissions": { + "type": "object", + "properties": { + "add_members": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + }, + "edit_group": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + }, + "send_messages": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + } + } + }, "data.LinkPreviewType": { "type": "object", "properties": { diff --git a/src/docs/swagger.json b/src/docs/swagger.json index e509ae1..8e10645 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -570,6 +570,12 @@ "name": "number", "in": "path", "required": true + }, + { + "type": "string", + "description": "Include all known recipients, not only contacts.", + "name": "all_recipients", + "in": "query" } ], "responses": { @@ -679,6 +685,12 @@ "name": "number", "in": "path", "required": true + }, + { + "type": "string", + "description": "Include all known recipients, not only contacts.", + "name": "all_recipients", + "in": "query" } ], "responses": { @@ -2650,7 +2662,7 @@ "type": "string" }, "permissions": { - "$ref": "#/definitions/api.GroupPermissions" + "$ref": "#/definitions/data.GroupPermissions" } } }, @@ -2724,32 +2736,6 @@ } } }, - "api.GroupPermissions": { - "type": "object", - "properties": { - "add_members": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - }, - "edit_group": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - }, - "send_messages": { - "type": "string", - "enum": [ - "only-admins", - "every-member" - ] - } - } - }, "api.LoggingConfiguration": { "type": "object", "properties": { @@ -3082,7 +3068,7 @@ "type": "string" }, "permissions": { - "$ref": "#/definitions/api.GroupPermissions" + "$ref": "#/definitions/data.GroupPermissions" } } }, @@ -3227,6 +3213,9 @@ "items": { "type": "string" } + }, + "permissions": { + "$ref": "#/definitions/data.GroupPermissions" } } }, @@ -3356,6 +3345,32 @@ } } }, + "data.GroupPermissions": { + "type": "object", + "properties": { + "add_members": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + }, + "edit_group": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + }, + "send_messages": { + "type": "string", + "enum": [ + "only-admins", + "every-member" + ] + } + } + }, "data.LinkPreviewType": { "type": "object", "properties": { diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 7e7ee54..48c00b5 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -61,7 +61,7 @@ definitions: name: type: string permissions: - $ref: '#/definitions/api.GroupPermissions' + $ref: '#/definitions/data.GroupPermissions' type: object api.CreateGroupResponse: properties: @@ -110,24 +110,6 @@ definitions: error: type: string type: object - api.GroupPermissions: - properties: - add_members: - enum: - - only-admins - - every-member - type: string - edit_group: - enum: - - only-admins - - every-member - type: string - send_messages: - enum: - - only-admins - - every-member - type: string - type: object api.LoggingConfiguration: properties: Level: @@ -349,7 +331,7 @@ definitions: name: type: string permissions: - $ref: '#/definitions/api.GroupPermissions' + $ref: '#/definitions/data.GroupPermissions' type: object api.UpdateProfileRequest: properties: @@ -445,6 +427,8 @@ definitions: items: type: string type: array + permissions: + $ref: '#/definitions/data.GroupPermissions' type: object client.IdentityEntry: properties: @@ -528,6 +512,24 @@ definitions: username_link: type: string type: object + data.GroupPermissions: + properties: + add_members: + enum: + - only-admins + - every-member + type: string + edit_group: + enum: + - only-admins + - every-member + type: string + send_messages: + enum: + - only-admins + - every-member + type: string + type: object data.LinkPreviewType: properties: base64_thumbnail: @@ -928,6 +930,10 @@ paths: name: number required: true type: string + - description: Include all known recipients, not only contacts. + in: query + name: all_recipients + type: string produces: - application/json responses: @@ -978,6 +984,10 @@ paths: name: number required: true type: string + - description: Include all known recipients, not only contacts. + in: query + name: all_recipients + type: string produces: - application/json responses: From 5fcaa2ca2ca6a65812e8d832eaffc4a300ab5fa1 Mon Sep 17 00:00:00 2001 From: Dan Gabel Date: Thu, 12 Feb 2026 15:51:21 -0600 Subject: [PATCH 3/5] type cleanup, fix typo --- src/client/client.go | 52 +++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/client/client.go b/src/client/client.go index 3c882b3..2e59ca7 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -214,6 +214,31 @@ type ContactProfile struct { LastUpdatedTimestamp int64 `json:"last_updated_timestamp"` } +type SignalCliProfileResponse struct { + LastUpdateTimestamp int64 `json:"lastUpdateTimestamp"` + GivenName string `json:"givenName"` + FamilyName string `json:"familyName"` + About string `json:"about"` + HasAvatar bool `json:"hasAvatar"` +} + +type ListContactsSignalCliResponse struct { + Number string `json:"number"` + Uuid string `json:"uuid"` + Name string `json:"name"` + ProfileName string `json:"profileName"` + Username string `json:"username"` + Color string `json:"color"` + Blocked bool `json:"blocked"` + MessageExpiration string `json:"messageExpiration"` + Note string `json:"note"` + GivenName string `json:"givenName"` + Profile SignalCliProfileResponse `json:"profile"` + Nickname string `json:"nickName"` + NickGivenName string `json:"nickGivenName"` + NickFamilyName string `json:"nickFamilyName"` +} + type Nickname struct { Name string `json:"name"` GivenName string `json:"given_name"` @@ -2601,29 +2626,6 @@ func (s *SignalClient) AddStickerPack(number string, packId string, packKey stri return err } } - type SignalCliProfileResponse struct { - LastUpdateTimestamp int64 `json:"lastUpdateTimestamp"` - GivenName string `json:"givenName"` - FamilyName string `json:"familyName"` - About string `json:"about"` - HasAvatar bool `json:"hasAvatar"` - } -type ListContactsSignlCliResponse struct { - Number string `json:"number"` - Uuid string `json:"uuid"` - Name string `json:"name"` - ProfileName string `json:"profileName"` - Username string `json:"username"` - Color string `json:"color"` - Blocked bool `json:"blocked"` - MessageExpiration string `json:"messageExpiration"` - Note string `json:"note"` - GivenName string `json:"givenName"` - Profile SignalCliProfileResponse `json:"profile"` - Nickname string `json:"nickName"` - NickGivenName string `json:"nickGivenName"` - NickFamilyName string `json:"nickFamilyName"` - } func (s *SignalClient) ListContacts(number string, allRecipients bool) ([]ListContactsResponse, error) { resp := []ListContactsResponse{} @@ -2655,7 +2657,7 @@ func (s *SignalClient) ListContacts(number string, allRecipients bool) ([]ListCo } } - var signalCliResp []ListContactsSignlCliResponse + var signalCliResp []ListContactsSignalCliResponse err = json.Unmarshal([]byte(rawData), &signalCliResp) if err != nil { log.Error("Couldn't list contacts", err.Error()) @@ -2721,7 +2723,7 @@ func (s *SignalClient) ListContact(number string, uuid string, allRecipients boo } } - var signalCliResp []ListContactsSignlCliResponse + var signalCliResp []ListContactsSignalCliResponse err = json.Unmarshal([]byte(rawData), &signalCliResp) if err != nil { log.Error("Couldn't list contacts", err.Error()) From eece5f4e925c5cdd04272aeca6ad43e2161114af Mon Sep 17 00:00:00 2001 From: Dan Gabel Date: Thu, 12 Feb 2026 21:52:22 -0600 Subject: [PATCH 4/5] remove ListContact, extended ListContacts to accept uuid --- src/api/api.go | 6 +-- src/client/client.go | 90 ++++++++++---------------------------------- 2 files changed, 22 insertions(+), 74 deletions(-) diff --git a/src/api/api.go b/src/api/api.go index f286979..4b3bdbb 100644 --- a/src/api/api.go +++ b/src/api/api.go @@ -2427,7 +2427,7 @@ func (a *Api) ListContacts(c *gin.Context) { c.JSON(400, Error{Msg: "Couldn't process request - all_recipients parameter needs to be either 'true' or 'false'"}) return } - contacts, err := a.signalClient.ListContacts(number, StringToBool(allRecipients)) + contacts, err := a.signalClient.ListContacts(number, StringToBool(allRecipients), "") if err != nil { c.JSON(400, Error{Msg: err.Error()}) return @@ -2468,7 +2468,7 @@ func (a *Api) ListContact(c *gin.Context) { return } - contact, err := a.signalClient.ListContact(number, uuid, StringToBool(allRecipients)) + contacts, err := a.signalClient.ListContacts(number, StringToBool(allRecipients), uuid) if err != nil { switch err.(type) { case *client.NotFoundError: @@ -2480,7 +2480,7 @@ func (a *Api) ListContact(c *gin.Context) { } } - c.JSON(200, contact) + c.JSON(200, contacts[0]) } // @Summary Returns the avatar of a contact diff --git a/src/client/client.go b/src/client/client.go index 2e59ca7..6ca6726 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -2627,7 +2627,7 @@ func (s *SignalClient) AddStickerPack(number string, packId string, packKey stri } } -func (s *SignalClient) ListContacts(number string, allRecipients bool) ([]ListContactsResponse, error) { +func (s *SignalClient) ListContacts(number string, allRecipients bool, recipient string) ([]ListContactsResponse, error) { resp := []ListContactsResponse{} var err error @@ -2635,9 +2635,17 @@ func (s *SignalClient) ListContacts(number string, allRecipients bool) ([]ListCo if s.signalCliMode == JsonRpc { type Request struct { - AllRecipients bool `json:"allRecipients"` + AllRecipients bool `json:"allRecipients,omitempty"` + Recipient string `json:"recipient,omitempty"` + } + req := Request{} + if allRecipients { + req.AllRecipients = allRecipients + } + if recipient != "" { + req.Recipient = recipient } - req :=Request{ AllRecipients: allRecipients } + jsonRpc2Client, err := s.getJsonRpc2Client() if err != nil { return nil, err @@ -2648,9 +2656,12 @@ func (s *SignalClient) ListContacts(number string, allRecipients bool) ([]ListCo } } else { cmd := []string{"--config", s.signalCliConfig, "-o", "json", "-a", number, "listContacts"} - if !allRecipients { + if allRecipients { cmd = append(cmd, "--all-recipients") } + if recipient != "" { + cmd = append(cmd, recipient) + } rawData, err = s.cliClient.Execute(true, cmd, "") if err != nil { return resp, err @@ -2664,6 +2675,10 @@ func (s *SignalClient) ListContacts(number string, allRecipients bool) ([]ListCo return resp, errors.New("Couldn't process request - invalid signal-cli response") } + if recipient != "" && len(signalCliResp) == 0 { + return resp, &NotFoundError{Description: "No user with that id (" + recipient + ") found"} + } + for _, value := range signalCliResp { entry := ListContactsResponse{ Number: value.Number, @@ -2691,73 +2706,6 @@ func (s *SignalClient) ListContacts(number string, allRecipients bool) ([]ListCo return resp, nil } -func (s *SignalClient) ListContact(number string, uuid string, allRecipients bool) (ListContactsResponse, error) { - var resp ListContactsResponse - - var err error - var rawData string - - if s.signalCliMode == JsonRpc { - type Request struct { - Recipient string `json:"recipient"` - AllRecipients bool `json:"allRecipients"` - } - req :=Request{ Recipient: uuid, AllRecipients: allRecipients } - jsonRpc2Client, err := s.getJsonRpc2Client() - if err != nil { - return resp, err - } - rawData, err = jsonRpc2Client.getRaw("listContacts", &number, req) - if err != nil { - return resp, err - } - } else { - cmd := []string{"--config", s.signalCliConfig, "-o", "json", "-a", number, "listContacts"} - if allRecipients { - cmd = append(cmd, "--all-recipients") - } - cmd = append(cmd, uuid) - rawData, err = s.cliClient.Execute(true, cmd, "") - if err != nil { - return resp, err - } - } - - var signalCliResp []ListContactsSignalCliResponse - err = json.Unmarshal([]byte(rawData), &signalCliResp) - if err != nil { - log.Error("Couldn't list contacts", err.Error()) - return resp, errors.New("Couldn't process request - invalid signal-cli response") - } - - if len(signalCliResp) == 0 { - return resp, &NotFoundError{Description: "No user with that id (" + uuid + ") found"} - } - - var value = signalCliResp[0] - contact := ListContactsResponse{ - Number: value.Number, - Uuid: value.Uuid, - Name: value.Name, - ProfileName: value.ProfileName, - Username: value.Username, - Color: value.Color, - Blocked: value.Blocked, - MessageExpiration: value.MessageExpiration, - Note: value.Note, - GivenName: value.GivenName, - } - contact.Profile.About = value.Profile.About - contact.Profile.HasAvatar = value.Profile.HasAvatar - contact.Profile.LastUpdatedTimestamp = value.Profile.LastUpdateTimestamp - contact.Profile.GivenName = value.Profile.GivenName - contact.Profile.FamilyName = value.Profile.FamilyName - contact.Nickname.Name = value.Nickname - contact.Nickname.GivenName = value.NickGivenName - contact.Nickname.FamilyName = value.NickFamilyName - - return contact, nil -} func (s *SignalClient) SetPin(number string, registrationLockPin string) error { if s.signalCliMode == JsonRpc { From 59f9cd3140009b14364975a41c165eb3920be5fe Mon Sep 17 00:00:00 2001 From: Dan Gabel Date: Thu, 12 Feb 2026 22:00:42 -0600 Subject: [PATCH 5/5] revert moving list contact types around --- src/client/client.go | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/client/client.go b/src/client/client.go index 6ca6726..d6c41ed 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -214,31 +214,6 @@ type ContactProfile struct { LastUpdatedTimestamp int64 `json:"last_updated_timestamp"` } -type SignalCliProfileResponse struct { - LastUpdateTimestamp int64 `json:"lastUpdateTimestamp"` - GivenName string `json:"givenName"` - FamilyName string `json:"familyName"` - About string `json:"about"` - HasAvatar bool `json:"hasAvatar"` -} - -type ListContactsSignalCliResponse struct { - Number string `json:"number"` - Uuid string `json:"uuid"` - Name string `json:"name"` - ProfileName string `json:"profileName"` - Username string `json:"username"` - Color string `json:"color"` - Blocked bool `json:"blocked"` - MessageExpiration string `json:"messageExpiration"` - Note string `json:"note"` - GivenName string `json:"givenName"` - Profile SignalCliProfileResponse `json:"profile"` - Nickname string `json:"nickName"` - NickGivenName string `json:"nickGivenName"` - NickFamilyName string `json:"nickFamilyName"` -} - type Nickname struct { Name string `json:"name"` GivenName string `json:"given_name"` @@ -2628,6 +2603,31 @@ func (s *SignalClient) AddStickerPack(number string, packId string, packKey stri } func (s *SignalClient) ListContacts(number string, allRecipients bool, recipient string) ([]ListContactsResponse, error) { + type SignalCliProfileResponse struct { + LastUpdateTimestamp int64 `json:"lastUpdateTimestamp"` + GivenName string `json:"givenName"` + FamilyName string `json:"familyName"` + About string `json:"about"` + HasAvatar bool `json:"hasAvatar"` + } + + type ListContactsSignalCliResponse struct { + Number string `json:"number"` + Uuid string `json:"uuid"` + Name string `json:"name"` + ProfileName string `json:"profileName"` + Username string `json:"username"` + Color string `json:"color"` + Blocked bool `json:"blocked"` + MessageExpiration string `json:"messageExpiration"` + Note string `json:"note"` + GivenName string `json:"givenName"` + Profile SignalCliProfileResponse `json:"profile"` + Nickname string `json:"nickName"` + NickGivenName string `json:"nickGivenName"` + NickFamilyName string `json:"nickFamilyName"` + } + resp := []ListContactsResponse{} var err error