aws-sdk-js-v3 icon indicating copy to clipboard operation
aws-sdk-js-v3 copied to clipboard

Email serialization happening incorrectly in SES.SendEmailCommand

Open IamFlowZ opened this issue 2 years ago • 2 comments

Checkboxes for prior research

Describe the bug

Just trying to send an email.
The source email is confirmed in SES.
The docs are super unclear about what values you're suppose to provide to the SESClient class.
Note code snippet for usage example.
Note error that is logged.
Played around with debugger, and discovered that the params are being serialized to below value before being sent.

Note: the values are properly encoded, I'm just removing the email's so as to not disclose them.

"[email protected]&[email protected]&Message.Subject.Data=CMS%20Backup&Action=SendEmail&Version=2010-12-01"

Should look like

"[email protected]&[email protected]&Message.Subject.Data=CMS%20Backup&Message.Body.Text=Backed up CMS db at ${new Date()} to ${bucketName}.&Action=SendEmail&Version=2010-12-01"


    try {
      const emailConfig = {region: 'us-east-1'}
      const client = new SESClient(emailConfig);
      const input = {
        Destination: {
          ToAddresses: [
            '[email protected]'
          ]
        },
        Source: '[email protected]',
        Message: {
          Subject: {
            Data: 'CMS Backup'
          },
          Body: {
            Text: `Backed up CMS db at ${new Date()} to ${bucketName}.`
          }
        }
      };
      const command = new SendEmailCommand(input);
      console.log(JSON.stringify(command, null ,2));
      results['emailResp'] = await client.send(command);
    } catch (err2) {
      console.error('email error', err2);
    }
console.error
    Email error SESServiceException [ValidationError]: 1 validation error detected: Value null at 'message.body' failed to satisfy constraint: Member must not be null
        at throwDefaultError (/"project directory"/node_modules/@aws-sdk/smithy-client/dist-cjs/default-error-handler.js:8:22)
        at deserializeAws_querySendEmailCommandError (/"project directory"/node_modules/@aws-sdk/client-ses/dist-cjs/protocols/Aws_query.js:2564:51)
        at processTicksAndRejections (node:internal/process/task_queues:96:5)
        at /"project directory"/node_modules/@aws-sdk/middleware-serde/dist-cjs/deserializerMiddleware.js:7:24
        at /"project directory"/node_modules/@aws-sdk/middleware-signing/dist-cjs/middleware.js:11:20
        at StandardRetryStrategy.retry (/"project directory"/node_modules/@aws-sdk/middleware-retry/dist-cjs/StandardRetryStrategy.js:51:46)
        at /"project directory"/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:6:22
        at 0 0 * * MON (/"project directory"/cron-tasks.js:65:30)
        at Object.<anonymous> (/"project directory"/test/cron-tasks.test.js:7:23) {
      '$fault': 'client',
      '$metadata': {
        httpStatusCode: 400,
        requestId: 'cbca55f5-321f-4ca3-8e8e-e371682d3914',
        extendedRequestId: undefined,
        cfId: undefined,
        attempts: 1,
        totalRetryDelay: 0
      },
      Type: 'Sender',
      Code: 'ValidationError'
    }

SDK version number

"@aws-sdk/client-ses": "^3.163.0",

Which JavaScript Runtime is this issue in?

Node.js

Details of the browser/Node.js/ReactNative version

v16.15.0

Reproduction Steps

Use the attached sample script in the description. ran locally using this jest test

const cron = require('../cron-tasks');

jest.setTimeout(2000000);
describe('backup to s3', () => {
    it('should backup to s3', async() => {
        const backupMethod = cron['0 0 * * MON'];

       const result = await backupMethod({});
       const metadata = result['$metadata'];
       expect(metadata.httpStatusCode).toBe(200);
    });
});

Observed Behavior

Throwing error due to message body not being correctly serialized. See description

Expected Behavior

Message body is attached and email gets sent.

Possible Solution

Investigation into why serialization is going awry. Updated docs to be more clear about how to send an email.

Additional Information/Context

No response

IamFlowZ avatar Sep 03 '22 17:09 IamFlowZ

Hi @IamFlowZ, thanks for opening this issue. After looking into the sample code you provided I found that the issue is that you are providing the parameter body as string and the type should be Content as described here. The definition for Content is here.

A working example should look as follow:

import {SendEmailCommand, SESClient} from "@aws-sdk/client-ses";

const client = new SESClient({
    region: 'REGION'
});

const command = new SendEmailCommand({
    Destination: {
        ToAddresses: [
            "[email protected]"
        ]
    },
    Source: "[email protected]",
    Message: {
        Subject: {
            Data: "This is a test subject"
        },
        Body: {
            Text: {
                Data: "This is a test body"
            }
        }
    }
});
const response = await client.send(command);

console.log('Response: ', response);

Thanks!

yenfryherrerafeliz avatar Sep 16 '22 15:09 yenfryherrerafeliz

This issue has not received a response in 1 week. If you still think there is a problem, please leave a comment to avoid the issue from automatically closing.

github-actions[bot] avatar Sep 24 '22 00:09 github-actions[bot]

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.

github-actions[bot] avatar Oct 12 '22 00:10 github-actions[bot]