An Intro to Architecture: Alerts, Notifications & Emails

This is the third installment of my introduction to Reaction's architecture. In this post, I'll focus on the different ways we communicate with users and inform them on all the important things that happen in the app. If you missed any of my earlier posts, you can check them out here.

In our last installment, we looked at how events serve as one of the basic building blocks for Reaction's architecture. Today, we'll be looking at some of the ways those events inform users of important things that happen. Just as I mentioned in my previous posts, this series is driven by the flow chart available here. If the flow chart seems confusing, refer back to the introduction for a good explanation on how to read it.

I'm going to use the same Login Flow example from my last post to talk about alerts, notifications, and emails.

As you can see from the above diagram, we'll need to inform the user of a number of different events that occur during the Login Flow. I'm going to break these down into the following four categories:

  1. Inline form validation (not noted in the diagram)
  2. Alerts (red rectangle)
  3. In-app notifications (orange pointy shape)
  4. Emails (pink concave/convex rectangle)

In Reaction, these are the four ways we give feedback to whoever is using the app. I've arranged them in order of how frequently they are used, from least intrusive to most intrusive.

Validation and Visual Cues

Validation is built into every form element in Reaction. Providing visual cues and validating user input on the fly is one of the most useful—and least intrusive—ways to inform users. For instance, when a form is saved in real time, we use visual cues in our validation to let the user know that there's no need to go hunting around for the 'Save' button. That user's data has already been saved.

Validation is tied into our schema, and helps guide users away from inputting bad data that might lead to other problems down the road. Through visual cues, we make sure that it's obvious when there's an error in a form, such as a bad email, an invalid price, or a username that's already taken. This way, users will not only know that there's a problem in the form, they'll also know exactly where that problem is, resulting in instant, precise feedback on whether this data is valid or not—and if not, it explains why.

These concepts aren't represented in the flow chart diagram, but you'll find them throughout the app. They're baked into Reaction's core.

Alerts

Alerts, which are represented in the diagram as the red rectangle, instantly notify an active user about something that just happened. In the Login Flow example in the diagram above, three alerts are noted:

  1. Sign in failed - Indicating an error of some kind
  2. Password changed - Indicating success
  3. Registration failed - Indicating failure to create a new account

We use a few different kinds of alerts in Reaction.

Toast Alerts

For the most common alerts, eg. when a user successfully publishes a product, saves an update to a field, or adds a product to a cart, we use a toast-style alert. These are unobtrusive alert pop-ups that are automatically dismissed after a specific amount of time. Sometimes, users can take action from these alerts. For instance, they may be able to visit the cart they just added an item to. For the most part, however, toast alerts serve to quickly notify users of the success or failure of their most recent action without any further call to action.

Alerts.toast(message, "success");  

Search for Alerts.toast in our codebase to see more examples.

Inline Alerts

For contextual alerts, where the notification occurs in the same area of the user's screen, we use inline style alerts. These alerts are similar to the visual cues that occur during form validation. We use them when form submissions fail, or when there is an error with a specific section that needs to be addressed. A good example of this is when payment is submitted, but validating the credit card becomes an issue. We'll bring that error back and display it inline, in the checkout's payment section.

Alerts.inline("Sorry, this item is out of stock!", "error", {  
  placement: "productDetail",
  i18nKey: "productDetail.outOfStock",
  autoHide: 10000
});

Inline alerts are shown in a specific spot (a placement) in a UI component. In addition to creating new inline alerts, you can also create new placements. We have a React component for this called AlertContainer.

<AlertContainer placement="productManagement" />  

Search for Alerts.inline and AlertContainer in our codebase to see more examples.

Modal Alerts

For interrupting, modal-style alerts, we use SweetAlert2. These alerts can be automatically dismissed after some time. They may also require the user to take action or select a series of choices. When we need to interrupt the user's operational flow in order to confirm or push something to the forefront, we use a modal alert. These are the most obtrusive type of alert, but also the least likely to be dismissed without notice. You can run actions off of these alerts based on user action and also trigger additional alerts from within the original alert.

// confirm delete
Alerts.alert({  
  title: confirmTitle,
  type: "warning",
  showCancelButton: true,
  confirmButtonText: confirmButtonText
}, (isConfirm) => {
  if (isConfirm) {
    if (id) {
      Meteor.call("taxes/deleteRate", id);
      instance.state.set({
        isEditing: false,
        editingId: null
      });
    }
  }
});

Search for Alerts.alert in our code base to see more examples or see the SweetAlert2 Docs for full API documentation.

Notifications

Reaction features a built-in, in-app notification system, which is great for informing users about events that happen, even when they're not immediately connected to their recent input. In-app notifications also include events that were triggered by the actions of other users. Examples include notifying a shop owner that a new order has been placed, or notifying a customer that their order has shipped or been delivered. In general, we believe that at any time an email is sent, an in-app notification should also be triggered. However, this doesn't necessarily apply vice versa—there are many actions for which an in-app notification is sufficient and no email is necessary.

In the Login Flow, there are four notifications that get sent out: Reset Password Request Received, Password Changed, Email Address Verified, and New User Welcome.

We're planning on building a feature that permits users to decide for themselves which events to be notified about. Users will also be able to choose whether to be notified by email, in-app notification, or both.

Notifications are sent by calling a method notification/send, which you can review in our included notification plugin.

Here's an example of a notification that gets sent to a user when their order is cancelled: code on github

Meteor.call("notification/send", order.userId, "orderCancelled", url, sms, (err) => {  
  if (err) Logger.error(err);
});

Emails

Emails are a tricky subject. Send too many emails to a person and they'll start ignoring them, filtering them out automatically, or even worse—they might even report them as spam! Yikes! For this reason, it's super important to get transactional emails right. We've built Reaction to send emails only when necessary and to use other less intrusive methods of interacting with users such whenever possible.

When people want to take note of important actions, emails are expected. This includes registration and order confirmation, order updates, security, and a few others, including:

  • Default
  • Accounts - Invite Shop Member
  • Accounts - Reset Password
  • Accounts - Welcome Email
  • Accounts - Verify Account
  • Orders - New Order Placed (Order Confirmation)
  • Orders - Order Shipped
  • Orders - Order Refunded

Reaction currently provides 8 different email templates, all of them customizable, although this number will grow as we add more content. From the dashboard, you can customize the title, subject, and content of an email. You can also customize these emails in your own shop by navigating to the Templates section of the admin dashboard and editing the template you wish to customize.

If you need additional emails, you can register your own email templates as well.

We send all emails by assigning a job, which will attempt to send the email. If it fails, go ahead and retry it until it succeeds, up to 5 times.

If you need to send an email from a plugin you're writing, you can do so by using the Reaction.Email.send() method, like so:

Reaction.Email.send(  
  to: "to@email.example",
  from: Reaction.getShopEmail(), // or from Email Address
  subject: "Email Subject",
  html: "HTML Content"
  )

Learn more about this method by visiting our Docs. For an example of how we use it to send an existing template, click here. Or, if you need help setting up your transactional email service, peep our Email documentation.

Conclusion

In this article, we've touched on the different ways that you can keep users informed about what's going on in your Reaction app. You've learned how Reaction uses alerts, notifications and emails, as well as how to build your own extensions using Reaction's built-in APIs.

If you found this helpful, or if you have any questions, I'd love to hear from you. Post comments below or join our community in our Gitter chatroom.

comments powered by Disqus