Feed Alert - an RSS Reader Powered by AWS Amplify

Read or listen to your favorite feeds and get notified when new stories are posted!

Introducing Feed Alert 🚀

feed-alert.com - Github

I'm writing this blog post hours before the AWS hackathon deadline, but I'm finally done with the initial set of features for Feed Alert, a service that allows you to read your favorite RSS feeds and get push notifications when new stories are posted.

Tech stack:

  • Amplify API (GraphQL and REST)
  • Amplify Predictions (TTS)
  • Amplify Auth
  • Amplify Analytics
  • Amplify Functions
  • Amplify Hosting
  • Firebase Cloud Messaging
  • Route 53
  • Secrets Manager
  • EventBridge
  • Step Functions

🖼️ Screenshots

Reader: Screenshot 2021-03-01 042828.png Screenshot 2021-03-01 043518.png Adding a feed: add.gif Auth: auth.gif Guests: Screenshot 2021-03-01 044258.png Users: Screenshot 2021-03-01 044622.png

Before the hackathon announcement, I didn't even know that AWS had its own set of serverless services, and it was quite a pleasant surprise with me being familiar with relational databases and Amplify relying on DynamoDB, so that was something that really sets this offering apart from the competition.

I did have many side projects planned but I did choose to go with Feed Alert since Amplify provides many services that I needed to finish this particular project and to take advantage of AWS infinite scalability that running an RSS aggregator requires.

What inspired this idea was me trying to find a reader that had instant and non-intrusive notifications, and a frictionless reading experience, and I wasn't alone: I wasn't alone

What makes Feed Alert different is relying on serverless aggregators while most feed readers do the aggregation work locally, which doesn't allow them to send instant notifications to users, nor provide a consistent cross-platform experience.

I won't be covering details like initializing your react app since these are well covered in the official docs, but I will talk about the integration of my project with AWS services and some challenges that I faced, while also making sure that this article is structured in a way that is indexable by search engines so that it can be easily accessible for other developers. Lots to talk about since I was only planning on using a subset of Amplify's services but that quickly expanded to other AWS services like Route 53, Secrets Manager, EventBridge, and Step Functions... 😅

👨‍💻 Implementation Details

Aggregators:

I wasn't planning to use Step Functions initially but the resiliency and unlimited scalability they provide are too good to pass up, and it turned out to be the best technical decision I made!

It's pretty amazing how everything is connected in the AWS ecosystem, especially that I could use the express function I made using Amplify in my state machine! Also, look at those pretty graphs 😍:

stepfunctions_graph.png

The usage of Step Functions allowed me to iterate faster and finish the aggregators implementation in less than a day! And the tight integration also made it easy to effortlessly set scheduling rules using EventBridge. Great stuff all around.

I did share the state machine I used on the github repo as well, take a look if you want to learn how to use your Amplify functions in Step Functions.

Auth:

With Amplify you can opt to use their pre-built UIs for the login/signup process but implementing your own custom forms is just as easy!

The documentation does a really good job at explaining how to implement the different flows, and you can also take a look at the github repo for the signup/login implementation (uses react-hook-form).

But I had to point out that you probably should handle instances where a user accidentally closes the verification page without completing the process by resending the verification message and reprompting them for the code, here's how you could do so in Amplify:

Auth.signIn(email, password)
  .then(() => {
    // Successful login
  })
  .catch((error) => {
    if (error.code === "UserNotConfirmedException") {
      return Auth.resendSignUp(email).then(() =>
        // Ask for the code
      );
    } else {
      // Handle other errors
    }
  });

This is how easy to customize Amplify is!

I didn't want to introduce any state management this early but I wanted to be able to share the auth state with other components the React way, so I did this:

// App.js
const [user, setUser] = useState(null);

const listener = () => {
  return Auth.currentAuthenticatedUser()
    .then((user) => setUser(user))
    .catch(() => setUser(null));
};

useEffect(() => {
  listener();
  Hub.listen("auth", listener);
  return () => Hub.remove("auth", listener);
}, []);

return <AuthContext.Provider value={user}>
  // ...
</AuthContext.Provider>;

Now I can easily access the current user details from other components:

const user = useContext(AuthContext);

TTS

This one was much simpler to implement than I thought! I only had to check if the feed content was within Amazon Polly's limits and use Amplify's Predictions to send the request and generate the audio which is then played using the browser's Audio API.

Notifications:

I didn't want to use a third party service but Amplify push notifications only supports Android and iOS at the time of writing this article so I used Firebase Cloud Messaging, and created some Amplify functions to handle subscriptions and sending, I also had to use Secrets Manager to store the credentials I use to authenticate against the Firebase admin API.

And it works well!

photo_2021-03-01_05-45-14.jpg

👀 What's next?

  • A daily email digest.
  • An Amazon Elasticsearch integration for full text search.
  • Implementing Mercury parser since most feeds don't provide the full article content.

I hope you find Feed Alert useful, let me know if you have any suggestions or features you want to see in the future! 👋

casiimir's photo

Wooh, cool Abdessamad. I appreciate your approach, stunning design! (Good luck you too for the challenge! 😜)

Abdessamad's photo

Thanks a lot Casiimir, I like what you did with Less 3 Than as well! 🤗

Gamer Dev's photo

Well, this one is great!

I like rss feeds in my personal websites as well. They are kindda my way to get updates from different sources.

I might even be using this.

Abdessamad's photo

Same! That's exactly what inspired this idea.

Glad you found it useful and thank you for the feedback ♥