aws / aws-sdk

Landing page for the AWS SDKs on GitHub
https://aws.amazon.com/tools/
Other
68 stars 13 forks source link

BUG with UpdateContactCommand @aws-sdk/client-sesv2 #579

Closed Meags27 closed 2 months ago

Meags27 commented 11 months ago

Checkboxes for prior research

Describe the bug

If I create a new contact with some attributes in the SES Contact List and then later run UpdateContactCommand to update the Topic Preferences for the contact and don't pass in "AttributesData" (which says in the docs is not required), the UpdateContactCommand will then ultimately override/wipe/delete the AttributesData.

I wanted to be able to update a contact's topic preferences without having to pass in the AttributesData again (like name, location etc.)

//not passing in AttributesData
      const input = {
            ContactListName: ContactListNameHere,
            EmailAddress: email,
            TopicPreferences: [{
            TopicName: "Marketing",
            SubscriptionStatus: "OPT_IN",
        }]

const response = await sesClient.send(new UpdateContactCommand(input));   
        };

SDK version number

@aws-sdk/client-sesv2@3.387.0

Which JavaScript Runtime is this issue in?

Node.js

Details of the browser/Node.js/ReactNative version

v18.14.2

Reproduction Steps

Some CLI commands to run (same issue happens with SDK) - you'l just have to add your credentials at the end to run them. Feel free to change the region too

//create contact list

aws sesv2 create-contact-list --contact-list-name testContactListName --topics "[{\"TopicName\":\"Marketing\",\"DisplayName\":\"Marketing\",\"Description\":\"MarketingTopic\",\"DefaultSubscriptionStatus\":\"OPT_OUT\"},{\"TopicName\":\"News\",\"DisplayName\":\"News\",\"Description\":\"NewsTopic\",\"DefaultSubscriptionStatus\":\"OPT_OUT\"}]" --region us-west-2

//create contact

aws sesv2 create-contact --contact-list-name playersEmailList --email-address example@gmail.com --region us-west-2 --attributes-data {\"Name\":\"TestName\"} --topic-preferences "[{\"TopicName\":\"Marketing\",\"SubscriptionStatus\":\"OPT_OUT\"},{\"TopicName\":\"News\",\"SubscriptionStatus\":\"OPT_IN\"}]"

//get contact

aws sesv2 get-contact --contact-list-name playersEmailList --email-address example@gmail.com --region us-west-2

//update contact

aws sesv2 update-contact --contact-list-name playersEmailList --email-address example@gmail.com --region us-west-2 --topic-preferences "[{\"TopicName\":\"Marketing\",\"SubscriptionStatus\":\"OPT_OUT\"},{\"TopicName\":\"News\",\"SubscriptionStatus\":\"OPT_OUT\"}]"

//get contact

aws sesv2 get-contact --contact-list-name playersEmailList --email-address example@gmail.com --region us-west-2

Observed Behavior

With get contact, the first time is shows the AttributeData, the second time it doesn't. I assume it's overiding the AttributeData?

Expected Behavior

I expected the AttributeData to still be there when only updating the Topic Preferences.

Possible Solution

No response

Additional Information/Context

No response

RanVaknin commented 11 months ago

Hi @Meags27 ,

Thanks for reporting this issue.

I can confirm this behavior as well:

Reproduction code:

import { SESv2Client, CreateContactCommand, UpdateContactCommand, GetContactCommand }  from "@aws-sdk/client-sesv2"

const sesClient = new SESv2Client({ region: "us-west-2" });

const contactListName = "foo";
const emailAddress = "example@gmail.com";

async function main() {
    try {
        await sesClient.send(new CreateContactCommand({
            ContactListName: contactListName,
            EmailAddress: emailAddress,
            AttributesData: '{"Name":"TestName"}',
            TopicPreferences: [
                {
                    TopicName: "Marketing",
                    SubscriptionStatus: "OPT_OUT"
                },
                {
                    TopicName: "News",
                    SubscriptionStatus: "OPT_IN"
                }
            ]
        }));

        console.log(await sesClient.send(new GetContactCommand({
            ContactListName: contactListName,
            EmailAddress: emailAddress
        })));

        const updateContactInput = {
            ContactListName: contactListName,
            EmailAddress: emailAddress,
            // AttributesData: '{"Name":"TestName"}',
            TopicPreferences: [
                {
                    TopicName: "Marketing",
                    SubscriptionStatus: "OPT_OUT"
                },
                {
                    TopicName: "News",
                    SubscriptionStatus: "OPT_OUT"
                }
            ]
        };
        await sesClient.send(new UpdateContactCommand(updateContactInput));

        console.log(await sesClient.send(new GetContactCommand({
            ContactListName: contactListName,
            EmailAddress: emailAddress
        })));

    } catch (error) {
        console.error("Error:", error);
    }
}
main();

Output:

{
  '$metadata': {
    httpStatusCode: 200,
    requestId: 'REDACTED',
    extendedRequestId: undefined,
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  },
  AttributesData: '{"Name":"TestName"}',
  ContactListName: 'foo',
  CreatedTimestamp: 2023-08-11T01:08:18.626Z,
  EmailAddress: 'example@gmail.com',
  LastUpdatedTimestamp: 2023-08-11T01:08:18.626Z,
  TopicPreferences: [
    { SubscriptionStatus: 'OPT_OUT', TopicName: 'Marketing' },
    { SubscriptionStatus: 'OPT_IN', TopicName: 'News' }
  ],
  UnsubscribeAll: false
}
{
  '$metadata': {
    httpStatusCode: 200,
    requestId: 'REDACTED',
    extendedRequestId: undefined,
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  },
  ContactListName: 'foo',
  CreatedTimestamp: 2023-08-11T01:08:18.626Z,
  EmailAddress: 'example@gmail.com',
  LastUpdatedTimestamp: 2023-08-11T01:08:18.763Z,
  TopicPreferences: [
    { SubscriptionStatus: 'OPT_OUT', TopicName: 'Marketing' },
    { SubscriptionStatus: 'OPT_OUT', TopicName: 'News' }
  ],
  UnsubscribeAll: false
}

This clearly shows that the returned results do not include the AttributeData set initially.

Unfortunately this is service-side behavior and not a bug in the SDK as this is reproducible through other SDKs and the CLI. I have opened an internal ticket with the SES team about this but I wouldn't hold my breath on a change. This behavior might be justified for a service reason / limitations that we are not aware of.

In the meantime, it sounds like specifying the Attribute Data with every update request is the only workaround.

Please check this ticket periodically to see if we heard back. Thanks, Ran~

P96611258

RanVaknin commented 2 months ago

Hi,

I heard back from the service team. This is the intentional behavior. They have updated their API docs to reflect this:

UpdateContactCommand

Updates a contact's preferences for a list.

You must specify all existing topic preferences in the TopicPreferences object, not just the ones that need updating; otherwise, all your existing preferences will be removed.

Thanks, Ran~

github-actions[bot] commented 2 months ago

This issue is now closed.

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.