Add support for SES implementation sending mail to a local SMTP server - #10203
Add support for SES implementation sending mail to a local SMTP server#10203the-gabe wants to merge 7 commits into
Conversation
…over SMTP Off unless set. Lets a moto server hand every accepted SES send to a real SMTP endpoint (a Mailpit/MailHog-style catcher) so emails sent through the SES API can be inspected, without moto growing a data plane of its own.
…TP when configured - Message keeps both Text and Html body parts (previously only one 'body'). - send_email builds a multipart/alternative MIME message; send_templated_email renders the template first; send_raw_email forwards the raw bytes verbatim. - Envelope recipients are To+Cc+Bcc (as SES delivers); Bcc is not written to the headers. The envelope sender is the bare address parsed from Source. - Relay is best-effort: any SMTP error is logged to stderr and the SES call still succeeds, so a missing catcher can never break the API under test.
SESv1 SendEmail and SESv2 SendEmail (Simple content) previously kept only one of the two body parts. Thread both through so the stored message and the SMTP relay carry exactly what the caller sent.
Monkeypatch smtplib.SMTP with a recorder and assert envelope + MIME for simple, text-only, raw, templated and SESv2 sends; relay is off by default; a relay failure never fails the SES call.
Checked against API_SendEmail, API_SendRawEmail, API_SendTemplatedEmail (SES v1), SESv2 API_SendEmail and the developer guide's 'Amazon SES header fields' page: - Date is set in UTC and Message-ID to <MessageId@region.amazonses.com>; both override whatever the caller supplied, raw messages included (SES documents exactly this). - Raw: Bcc is stripped before delivery; the caller's Return-Path is not what recipients see, so it is dropped too; Destinations + header recipients are delivered once each. - Text-only or HTML-only bodies are a single text/* part; both together are multipart/alternative (previously always multipart). - ReplyToAddresses -> Reply-To; ReturnPath (v2: FeedbackForwardingEmailAddress) is the envelope sender. Neither was parsed by moto before, so both were silently dropped. - Subject/Text/Html Charset honoured, falling back to UTF-8 when the data cannot be encoded in it; non-ASCII subjects go out as RFC 2047 encoded-words. - Templated sends now carry Cc and Reply-To, and are built by the same path as Simple sends via a shared (subject, text, html) renderer. - MOTO_SES_SMTP_RELAY=host (no port) defaults to 25 instead of raising.
…ailAddress Custom headers are applied to the assembled message. Names SES sets itself (BCC, CC, Content-Disposition, Content-Type, Date, From, Message-ID, MIME-Version, Reply-To, Return-Path, Subject, To - the list from 'Amazon SES header fields') are refused with BadRequestException, as the service does.
Message-ID/Date override, single-part vs multipart/alternative, Reply-To, ReturnPath envelope, charsets and encoded-word subjects, raw Bcc strip + dedupe + attachment fidelity, templated Cc/Reply-To, SESv2 headers (accepted and refused), host-only relay target, off-by-default, relay failure never fails the call.
|
I'm generally not in favor of PRs that try to add "real" functionality to Moto's mocking library, both because they're not really aligned with project's mission (mocking the AWS API responses) and because they can be a maintenance challenge going forward. So, for those reasons, I probably wouldn't merge this. @bblommers Any thoughts? |
|
We currently use this to test drive our applications locally, and its proven to be quite helpful to enable people to test plain/html email independently. Do you have a more project aligned means you would see fit to enable this? |
|
Agreed @bpandola - I understand that it can be incredibly useful, but this is out of scope for Moto. There is a (long-running) feature request to add extensions to Moto, which would be a great fit for an SMTP server, but there hasn't been any movement in design or development. |
I use this to send into MailPit on my local dev env.