Skip to content

Commit b8e204e

Browse files
committed
Add ability to merge by email or user id
1 parent 49ae0bc commit b8e204e

2 files changed

Lines changed: 62 additions & 18 deletions

File tree

cmd/users/merge.go

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,43 @@ import (
99

1010
// MergeCmd represents the merge command for users
1111
var MergeCmd = &cobra.Command{
12-
Use: "merge",
13-
Short: "Merge two users",
14-
Args: cobra.ExactArgs(2),
15-
Example: "iterablectl users merge <source_email> <destination_email>",
12+
Use: "merge",
13+
Short: "Merge two users",
14+
Example: `iterablectl users merge --from-email <source email> --to-email <destination email>
15+
iterablectl users merge --from-user-id <source user id> --to-email <destination email>
16+
iterablectl users merge --from-user-id <source user id> --to-user-id <destination user id>
17+
iterablectl users merge --from-email <source > --to-user-id <destination user id>
18+
`,
1619
RunE: func(cmd *cobra.Command, args []string) error {
1720
apiKey, _ := cmd.Flags().GetString("api-key")
1821
client := iterable.NewClient(apiKey)
1922

20-
sourceEmail := args[0]
21-
if sourceEmail == "" {
22-
return fmt.Errorf("source email is required")
23+
// Get flag values
24+
fromEmail, _ := cmd.Flags().GetString("from-email")
25+
fromUserID, _ := cmd.Flags().GetString("from-user-id")
26+
toEmail, _ := cmd.Flags().GetString("to-email")
27+
toUserID, _ := cmd.Flags().GetString("to-user-id")
28+
29+
// Validate that exactly one source identifier is provided
30+
if (fromEmail == "" && fromUserID == "") || (fromEmail != "" && fromUserID != "") {
31+
return fmt.Errorf("exactly one of --source-email or --source-user-id must be specified")
2332
}
24-
destinationEmail := args[1]
25-
if destinationEmail == "" {
26-
return fmt.Errorf("destination email is required")
33+
if (toEmail == "" && toUserID == "") || (toEmail != "" && toUserID != "") {
34+
return fmt.Errorf("exactly one of --to-email or --to-user-id must be specified")
2735
}
2836

29-
response, err := client.MergeUsers(sourceEmail, destinationEmail)
37+
var response *iterable.APIError
38+
var err error
39+
40+
response, err = client.MergeUsers(iterable.MergeUsersOpts{
41+
SrcEmail: fromEmail,
42+
DstEmail: toEmail,
43+
44+
SrcID: fromUserID,
45+
DstID: toUserID,
46+
})
3047
if err != nil {
31-
return fmt.Errorf("error merging users: %v", err)
48+
return fmt.Errorf("error merging users: %w", err)
3249
}
3350

3451
if response.Code != "Success" {
@@ -38,3 +55,10 @@ var MergeCmd = &cobra.Command{
3855
return nil
3956
},
4057
}
58+
59+
func init() {
60+
MergeCmd.Flags().String("from-email", "", "Email address of the source user to merge")
61+
MergeCmd.Flags().String("from-user-id", "", "User ID of the source user to merge")
62+
MergeCmd.Flags().String("to-email", "", "Email address of the destination profile to merge into")
63+
MergeCmd.Flags().String("to-user-id", "", "User ID of the destination profile to merge into")
64+
}

pkg/iterable/client.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func (c *Client) do(req *http.Request, v any) error {
114114
if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusBadRequest {
115115
var apiErr APIError
116116
if err = json.NewDecoder(resp.Body).Decode(&apiErr); err != nil {
117-
return fmt.Errorf("API request failed with status %d: %v", resp.StatusCode, err)
117+
return fmt.Errorf("API request failed with status %d: %w", resp.StatusCode, err)
118118
}
119119
return &apiErr
120120
}
@@ -128,12 +128,29 @@ func (c *Client) do(req *http.Request, v any) error {
128128
return nil
129129
}
130130

131-
// MergeUsers merges two Iterable users
132-
func (c *Client) MergeUsers(src, dst string) (*APIError, error) {
131+
type MergeUsersOpts struct {
132+
SrcEmail string
133+
DstEmail string
134+
SrcID string
135+
DstID string
136+
}
137+
138+
// MergeUsers merges two Iterable users by their email addresses
139+
func (c *Client) MergeUsers(opts MergeUsersOpts) (*APIError, error) {
133140
path := "users/merge"
134-
body := map[string]string{
135-
"destinationEmail": dst,
136-
"sourceEmail": src,
141+
body := map[string]string{}
142+
143+
if opts.DstEmail != "" {
144+
body["destinationEmail"] = opts.DstEmail
145+
}
146+
if opts.SrcEmail != "" {
147+
body["sourceEmail"] = opts.SrcEmail
148+
}
149+
if opts.SrcID != "" {
150+
body["sourceUserId"] = opts.SrcID
151+
}
152+
if opts.DstID != "" {
153+
body["destinationUserId"] = opts.DstID
137154
}
138155
req, err := c.newRequest("POST", path, body)
139156
if err != nil {
@@ -145,6 +162,9 @@ func (c *Client) MergeUsers(src, dst string) (*APIError, error) {
145162
if err != nil {
146163
return nil, err
147164
}
165+
if response.Code != "Success" {
166+
return nil, fmt.Errorf("failed to update user: %v", response)
167+
}
148168

149169
return &response, nil
150170
}

0 commit comments

Comments
 (0)