Using Nodemailer, Localstack, and the Node AWS SDK to send an email I am getting various errors:
AWS_SES_ENDPOINT=localhost:4566
Error: connect ECONNREFUSED 127.0.0.1:80
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)
AWS_SES_ENDPOINT=127.0.0.1:4566
uncaughtException: Invalid URL
TypeError [ERR_INVALID_URL]: Invalid URL
at new NodeError (node:internal/errors:371:5)
at onParseError (node:internal/url:552:9)
at new URL (node:internal/url:628:5)
at parseUrl (/something/node_modules/@aws-sdk/url-parser/dist-cjs/index.js:6:60)
at resolveEndpointsConfig (/something/node_modules/@aws-sdk/config-resolver/dist-cjs/endpointsConfig/resolveEndpointsConfig.js
AWS_SES_ENDPOINT=http://localhost:4578 and AWS_SES_ENDPOINT=http://127.0.0.1:4578
Error: read ECONNRESET
at TCP.onStreamRead (node:internal/stream_base_commons:220:20
AWS_SES_ENDPOINT=http://localhost:4566 and AWS_SES_ENDPOINT=smtp://127.0.0.1:4566
UnknownError
at deserializeAws_querySendRawEmailCommandError (/something/node_modules/@aws-sdk/client-ses/dist-cjs/protocols/Aws_query.js:2779:24)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async /something/node_modules/@aws-sdk/middleware-serde/dist-cjs/deserializerMiddleware.js:7:24
at async /something/node_modules/@aws-sdk/middleware-signing/dist-cjs/middleware.js:11:20
at async StandardRetryStrategy.retry (/something/node_modules/@aws-sdk/middleware-retry/dist-cjs/StandardRetryStrategy.js:51:46)
at async /something/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:6:22
AWS_SES_ENDPOINT=smtp://127.0.0.1:4578
Error [TimeoutError]: socket hang up
at connResetException (node:internal/errors:691:14)
at Socket.socketOnEnd (node:_http_client:471:23)
at Socket.emit (node:events:402:35)
at endReadableNT (node:internal/streams/readable:1343:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
code: 'ECONNRESET',
SES for nodemailer is set up like:
const sesConfig: SESClientConfig = {
region: "us-east-1",
endpoint: AWS_SES_ENDPOINT,
};
const ses = new SES(sesConfig);
Localstack is set up in docker-compose.yml like:
services:
qatool-localstack:
container_name: "my-localstack"
image: localstack/localstack
ports:
- "127.0.0.1:4566:4566"
- "127.0.0.1:4572:4572"
- "127.0.0.1:4578:4578"
environment:
- SERVICES=sqs:4566,s3:4572,ses:4578
- DEFAULT_REGION=us-east-1
- DATA_DIR=${TMPDIR:-/tmp/}localstack/data
- HOST_TMP_FOLDER=${TMPDIR:-/tmp/}localstack
volumes:
- "${TMPDIR:-/tmp}/localstack:/tmp/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
- './localstackSetup.sh:/docker-entrypoint-initaws.d/make-s3.sh'
nodemailer and aws ses versions:
"@aws-sdk/client-ses": "^3.110.0",
"nodemailer": "^6.7.5",
The first two errors for
localhost:4566
and 127.0.0.1:4566
are because a protocol wasnt included. You can see AWS SES doesn't parse the config properly for example:
ses.config.endpoint().then((val) => { console.log(JSON.stringify(val)); });
gives:
{"hostname":"","protocol":"localhost:","path":"4566"}
Where localhost is the protocol instead of the hostname.
The connections to port 4578 didn't work for me.
Aafter doing (replace from-email):
aws ses verify-email-identity --email-address from-email@from.com --endpoint-url=http://localhost:4566
These endpoints worked:
http://127.0.0.1:4566
http://localhost:4566
smtp://localhost:4566
smtp://127.0.0.1:4566
You can verify the email was sent by going to :
http://localhost:4566/_localstack/ses
Localstack doesn't send the actual email in the free version.
You can verify SES is running by going to:
http://localhost:4566/health