Building an Email Subscription and Broadcasting System with React and AWS SNS
By abdulmumin yaqeen
on May 14, 2024
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:
- Create an SNS topic to represent our email list.
- Build a React component that allows users to subscribe their email addresses to the SNS topic.
- 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:
- Nodejs and npm or bun (in our case) installed on your machine.
- An AWS account set up with the appropriate credentials and permissions to use SNS.
- Basic knowledge of React and JavaScript.
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.
AWS.config.update
is a method provided by the AWS SDK to update the global AWS configuration. We pass an object with our AWS credentials (accessKeyId
,secretAccessKey
) and the desired AWS region (region
).- After configuring the credentials, we create a new instance of the
AWS.SNS
service, which we'll use to interact with the SNS service. - Finally, we export the
sns
instance so that it can be imported and used in other parts of our application.
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:
e.preventDefault()
is called to prevent the default form submission behavior.- We create an object
params
with the necessary parameters for thesns.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 theemail
state variable.
- 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. - If the subscription is successful, we update the
subscribed
state totrue
and clear theemail
state. - 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:
e.preventDefault()
is called to prevent the default form submission behavior.- We create an object
params
with the necessary parameters for thesns.publish
method:Subject
: The subject of the email, stored in thesubject
state variable.Message
: The email message, stored in themessage
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.
- 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. - If the broadcast is successful, we log a success message to the console and clear the
subject
andmessage
state variables. - 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.