Contact Us

Building an Email Subscription and Broadcasting System with React and AWS SNS


By abdulmumin yaqeen

on May 14, 2024



img

Introduction

AWS Simple Notification Service (SNS) is a fully managed messaging service provided by Amazon Web Services. It allows you to decouple and scale applications by following a publish/subscribe (pub/sub) model.

With SNS, you can create topics and subscribe various endpoints (email addresses, AWS Lambda functions, HTTP/HTTPS web servers, etc.) to receive messages published to those topics. SNS supports multiple delivery protocols, including email, SMS, HTTP/HTTPS, and mobile push notifications.

In this tutorial, we'll be using SNS to build an email subscription and broadcasting system. Specifically, we'll:

  1. Create an SNS topic to represent our email list.
  2. Build a React component that allows users to subscribe their email addresses to the SNS topic.
  3. Build another React component that allows us to broadcast emails to all subscribers of the SNS topic.

By the end of the tutorial, you'll have a basic application that can manage email subscriptions and send mass emails using the SNS service, without having to worry about the underlying messaging infrastructure.

SNS is a powerful service that enables event-driven architectures, fanout messaging patterns, and real-time communication between distributed systems. While we'll focus on email use cases in this tutorial, SNS can be utilized for a wide range of messaging scenarios, such as mobile push notifications, IoT applications, and serverless workflows.

Prerequisites

Before we start, make sure you have the following:

Our final project will look like this:

Step 1: Set up a new React project

Open your terminal and run the following command to create a new React project:

npx create-react-app email-subscription

Navigate into the project directory:

cd email-subscription

Step 2: Install AWS SDK for JavaScript

We'll use the AWS SDK for JavaScript to interact with the SNS service. Install it by running the following command:

npm install aws-sdk

Step 3: Configure AWS Credentials

Create a file aws.config.js in your src .

You can store your AWS credentials in a .env file and import it here.

// aws.config.js import AWS from 'aws-sdk'; AWS.config.update({ accessKeyId: 'YOUR_AWS_ACCESS_KEY_ID', secretAccessKey: 'YOUR_AWS_SECRET_ACCESS_KEY', region: 'YOUR_AWS_REGION'// us-east-1 for example , }); export const sns = new AWS.SNS();

In this step, we import the aws-sdk library and configure our AWS credentials. We create a new file aws.config.js to store our AWS credentials and set up the SNS client.

Before moving to the next step though, we should head over to our AWS console to create a SNS topic.

We’re going to need the topic’s ARN.

Step 5: Create a Subscription Form Component

// SubscriptionForm.js import React, { useState } from 'react'; import { sns } from './aws.config'; const SubscriptionForm = () => { const [email, setEmail] = useState(''); const [subscribed, setSubscribed] = useState(false); const handleSubmit = async (e) => { e.preventDefault(); try { const params = { Protocol: 'email', TopicArn: 'YOUR_SNS_TOPIC_ARN', Endpoint: email, }; await sns.subscribe(params).promise(); setSubscribed(true); setEmail(''); } catch (error) { console.error('Error subscribing to topic:', error); } }; return ( <div> {subscribed ? ( <p>Thank you for subscribing!</p> ) : ( <form onSubmit={handleSubmit}> <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Enter your email" required /> <button type="submit">Subscribe</button> </form> )} </div> ); }; export default SubscriptionForm;

In this component, we import the sns instance from our aws.config.js file. We also use the useState hook to manage the component's state: email to store the user's email input, and subscribed to track whether the user has subscribed or not.

The handleSubmit function is an asynchronous function that is called when the form is submitted. Here's what happens:

  1. e.preventDefault() is called to prevent the default form submission behavior.
  2. We create an object params with the necessary parameters for the sns.subscribe method:
    • Protocol: We specify 'email' as the protocol for the subscription.
    • TopicArn: This is the Amazon Resource Name (ARN) of the SNS topic we created earlier. You need to replace 'YOUR_SNS_TOPIC_ARN' with the actual ARN of your topic.
    • Endpoint: This is the email address entered by the user, stored in the email state variable.
  3. We call sns.subscribe(params).promise() to subscribe the user's email to the SNS topic. The .promise() method returns a Promise that resolves when the subscription is successful.
  4. If the subscription is successful, we update the subscribed state to true and clear the email state.
  5. If an error occurs during the subscription process, we catch the error and log it to the console.

The rendering code (omitted for brevity) displays either a form for the user to enter their email address (if subscribed is false), or a success message (if subscribed is true).

We can test this to see if it works:

This message should appear if it was successful:

We should get a confirmation email:

Step 8: Broadcasting Emails

// BroadcastEmail.js import React, { useState } from 'react'; import { sns } from './aws.config'; const BroadcastEmail = () => { const [subject, setSubject] = useState(''); const [message, setMessage] = useState(''); const handleSubmit = async (e) => { e.preventDefault(); try { const params = { Subject: subject, Message: message, TopicArn: 'YOUR_SNS_TOPIC_ARN', }; await sns.publish(params).promise(); console.log('Email broadcast successfully!'); setSubject(''); setMessage(''); } catch (error) { console.error('Error broadcasting email:', error); } }; return ( <div> <h2>Broadcast Email</h2> <form onSubmit={handleSubmit}> <input type="text" value={subject} onChange={(e) => setSubject(e.target.value)} placeholder="Enter subject" required /> <textarea value={message} onChange={(e) => setMessage(e.target.value)} placeholder="Enter message" required ></textarea> <button type="submit">Broadcast</button> </form> </div> ); }; export default BroadcastEmail;

This component is similar to the SubscriptionForm component, but instead of subscribing emails, it allows you to broadcast emails to all subscribers of the SNS topic. We use the useState hook to manage the component's state: subject to store the email subject, and message to store the email message.

The handleSubmit function is an asynchronous function that is called when the form is submitted. Here's what happens:

  1. e.preventDefault() is called to prevent the default form submission behavior.
  2. We create an object params with the necessary parameters for the sns.publish method:
    • Subject: The subject of the email, stored in the subject state variable.
    • Message: The email message, stored in the message state variable.
    • TopicArn: This is the Amazon Resource Name (ARN) of the SNS topic we created earlier. You need to replace 'YOUR_SNS_TOPIC_ARN' with the actual ARN of your topic.
  3. We call sns.publish(params).promise() to broadcast the email to all subscribers of the SNS topic. The .promise() method returns a Promise that resolves when the broadcast is successful.
  4. If the broadcast is successful, we log a success message to the console and clear the subject and message state variables.
  5. If an error occurs during the broadcast process, we catch the error and log it to the console.

we can broadcast a test message to our current subscribers:

SNS should broadcast that to the respective email addresses:

By integrating these two components (SubscriptionForm and BroadcastEmail) into your React application, you'll have a complete email subscription and broadcasting system using AWS SNS.

Finally we can throw in some styling with React Boostrap

npm install react-bootstrap bootstrap

…and there we have it:

Conclusion

In this tutorial, we learned how to leverage AWS Simple Notification Service (SNS) to build an email subscription and broadcasting system with React. SNS provided a scalable and reliable messaging infrastructure, allowing us to decouple the subscription management and email broadcasting components from our application.

By creating an SNS topic and subscribing email addresses to it, we built a simple subscription form. Using SNS's publish functionality, we created a broadcast email form that sent messages to all subscribers with ease.

The key advantage of SNS is that it abstracts away the complexities of managing a messaging system, allowing us to focus on building application logic. SNS handled message delivery, retries, and scaling transparently.

Overall, AWS SNS simplifies the process of building event-driven architectures and decoupled systems, enabling real-time communication and asynchronous message delivery without managing underlying infrastructure.