Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transactional Emails #39

Closed
michaelbromley opened this issue Nov 8, 2018 · 3 comments
Closed

Transactional Emails #39

michaelbromley opened this issue Nov 8, 2018 · 3 comments
Labels
design 📐 This issue deals with high-level design of a feature @vendure/core

Comments

@michaelbromley
Copy link
Member

michaelbromley commented Nov 8, 2018

There are a number of circumstances in which an ecommerce shop might want to generate and send an email to a customer, e.g:

  • Account creation / welcome
  • Email address verification
  • Order confirmation
  • Shipping confirmation
  • Cart abandonment
  • Request for feedback on an order

There are 3 aspects to transaction emails: events, email creation, and sending.

Events

An event would be some point in a process where listeners could be notified and then decide whether or not to create and send an email. Typical events would include: account created, order transitions to a certain state.

We already have hooks in those processes governed by the FiniteStateMachine, but this is not enough. For example, a cart abandonment email is not necessarily triggered by any kind of state transition, but perhaps an automated task that runs periodically.

Therefore it would make sense to have some kind of generic event bus service (#40), whereby various events are published and then the email handler can subscribe to any of these and thereby send an email at the right moment.

Email creation

This step occurs in response to an event and is concerned with generating the body of the email. It would use some kind of templating system such as Handlebars which could be passed pertinent information from the event object (e.g. the Order and Customer entities in the case of a hypothetical OrderStateTransitionEvent) and would use this data to interpolate into the template. The result would be typically a string of HTML.

Email sending (transport)

A "transport" is a method of actually sending the mail to the recipient.

SMTP is the most common way of sending an email. A business will either use their own SMTP server, or use a service such as Mandrill or SendGrid

Local - A local email server may be used such as sendmail may be used to directly send the email.

Other - For testing purposes a mock transport may be used which simply writes the email to a file on the local file system.

Nodemailer supports all of the above transport out of the box, and new transports can be written.

@michaelbromley michaelbromley added @vendure/core design 📐 This issue deals with high-level design of a feature labels Nov 8, 2018
@michaelbromley michaelbromley mentioned this issue Nov 8, 2018
@michaelbromley
Copy link
Member Author

Implementation proposal

email-component-diagram

  1. Various events are generated by the Vendure Server and published via the EventBus (Event Bus #40).
  2. EmailEventHandlers listen for a specific event and convert these events into EmailContext instances, which contain the information required to generate and send an email.
  3. The EmailGenerator takes an EmailContext object and uses the data to generate the body of the email based on a template. There will be standard, built-in templates but there must be a very simple way to provide custom templates since this will be needed by most shops.
  4. The output of the EmailGenerator is a GeneratedEmail instance, which is just the EmailContext with the addition of a body string.
  5. The GeneratedEmail is passed to the EmailTransport which actually sends the email to the recipient.

@michaelbromley
Copy link
Member Author

michaelbromley commented Nov 8, 2018

Templating

Templates should use a templating language to allow the actual data (customer name, order contents etc) to be interpolated when generating the HTML.

The specific quirks of designing emails (needs tables for layout, inline styles etc) suggest the use of a email framework. The main contenders are:

I like the look of MJML. However, it does not support templating features itself (interpolating variables, for loops) so we would need an additional templating layer which generates the MJML, which is then compiled into HTML. Handlebars is an obvious choice for the templating part.

michaelbromley added a commit that referenced this issue Nov 9, 2018
Relates to #39. This is mainly a proof-of-concept with a single type of email (order receipt). The general design seems to work fine though.
Still to do:

* Revisit config to make it as simple as possible
* Implement a full default set of email types
* Figure out the best format for the templates and implement templating
michaelbromley added a commit that referenced this issue Nov 13, 2018
Relates to #39. Still need to make the templates themselves for each of the defaul email types
michaelbromley added a commit that referenced this issue Nov 13, 2018
Relates to #39. The design could use some work but the basic functionality is there
@michaelbromley
Copy link
Member Author

Current status: The infrastructure is all there for transactional emails now. The only thing missing is the definition of all the email types (right now there is only "order confirmation" and "email verification".

The plan is to create config and templates for the other types as development of the rest of the UI / shopfront progresses. So I'll close this issue now since the foundation is complete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design 📐 This issue deals with high-level design of a feature @vendure/core
Projects
None yet
Development

No branches or pull requests

1 participant