BlogAtlas Vector Search voted most loved vector database in 2024 Retool State of AI reportLearn more >>
MongoDB Developer
MongoDB
plus
Sign in to follow topics
MongoDB Developer Centerchevron-right
Developer Topicschevron-right
Productschevron-right
MongoDBchevron-right

Build a Newsletter Platform With Flask and MongoDB

Mercy Bassey11 min read • Published Jun 27, 2024 • Updated Jun 27, 2024
MongoDBPython
FULL APPLICATION
Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
A newsletter is a powerful tool for maintaining regular communication with your audience. It connects you with your subscribers, allowing you to share updates, news, and other valuable content directly to their inboxes. In this article, you’ll learn how to build a dynamic and interactive newsletter platform where subscribers can easily subscribe to your newsletter, and you, as the admin, can efficiently manage and send batch emails to all subscribed users. By the end of this guide, you will have a fully functional newsletter platform that leverages JavaScript for interactivity, Flask on the server side, and MongoDB for efficient data storage.

Prerequisites

To follow along in this article, you should meet the following requirements:
  • MongoDB installed on your machine — whether that’s Linux, Mac OS, or Windows
  • Mongosh for interacting with your MongoDB instance — view the instructions for installation]
  • RabbitMQ installed on your machine for message brokering — view the installation instructions for Debian and Ubuntu, then Windows and MacOS using Homebrew
  • Gmail as the SMTP server for sending emails — in this case, generate an app password to securely authenticate your application without using your Gmail account's primary password
The commands used in this tutorial are demonstrated on a Linux machine with an Ubuntu 22.04LTS distro. The code used in this tutorial can be found in the GitHub repository.

Setting up the environment

To begin, you must ensure MongoDB, Mongosh, and your RabbitMQ server are running. To achieve this, execute the following commands sequentially:
If you have the following output, you are set:
Next, go ahead and create a working directory and virtual environment, and then activate the virtual environment using the following commands:
With the virtual environment activated, you’re now ready to install the libraries needed to develop your newsletter platform. To proceed, you’ll need to install the following libraries:
  • Flask for handling the web server and routing
  • Flask Mail for sending emails from your application
  • PyMongo for interfacing with MongoDB, which you can use to manage subscriber data and persistent storage of newsletter content
  • Celery for managing asynchronous tasks, such as sending batch emails
Using the following command, you will have them installed in your virtual environment:
Finally, in your working directory, create two directories called static and templates. These will serve as the locations for static files like CSS and HTML templates, essential for rendering your web application's front-end part. After that, create the following files:
  • app.py: This will serve as the main entry point for your Flask application, where you initialize your app and tie together the other components.
  • config.py: This file will contain all configuration settings for your application, such as MongoDB connection details, mail server configuration, and Celery broker connection alongside any other environment-specific variables.
  • routes.py: Here, you will define the routes (URLs) that your application will respond to. It will include functions to handle requests and responses, connecting URLs to Python functions.
  • tasks.py: This file will be used for defining background tasks that can be processed asynchronously — which is, in this case, to send emails.

Creating the template

With your environment set up, the next thing to do is develop the look of your newsletter platform. In the templates directory, create two HTML files — admin.html and subscrbe.html. In admin.html, add the following HTML markup:
And then add the following code in the subscribe.html file:
In the admin.html and subscribe.html templates, add the following scripts respectively in the body tag:
For the admin.html template, the script block ensures that the form submission for sending newsletters is handled asynchronously. When the admin form is submitted, the JavaScript intercepts this event to prevent a page reload. It then sends the form data to the server using the Fetch API. Upon success, it displays a message that emails are being sent, and this message clears after a few seconds. In case of an error during the form submission, it captures that error and displays an appropriate message to the admin.
For the subscribe.html template, the script block ensures that the subscription process is similarly handled asynchronously. When a user submits their subscription details, the script prevents the default form submission to the server and instead sends the data using Fetch. The server's response is then displayed directly in the HTML. If the response indicates success, a confirmation message is shown, and if there is an error (such as the server responding that the email already exists in the database), the error message is displayed.
Finally, create a styles.css file in your static folder and add the following styles:

Creating the routes and tasks

With the template set up, you are now ready to define the specific routes and background tasks that will drive the functionality of your newsletter platform. This involves mapping URLs to Python functions in your Flask application, which will handle form submissions, user interactions, and any other required processes. Additionally, you'll configure Celery tasks to handle asynchronous operations such as sending emails in batches.
To begin, add the following in your config.py:
Here you are setting up the configuration for your Flask application. This configuration includes the settings for Celery to connect to its message broker (RabbitMQ in this case, indicated by the AMQP URL) and MongoDB for the results back end. You're also configuring Flask-Mail with Gmail as the SMTP server to handle outgoing emails, which requires the mail server details, port, and secure connection preferences, along with your Gmail credentials. The MAIL_DEFAULT_SENDER is used as the default sender email address for your outgoing emails. Additionally, ALLOWED_IPS is specified for an extra layer of security, limiting access to certain functionalities based on the requester's IP address. Lastly, the MONGO_URI sets the connection string to your MongoDB database, where subscriber information and other data relevant to your newsletter system will be stored.
Next, in your routes.py file, add the following code snippets:
The code snippet above establishes the essential routes and functionalities for your newsletter platform. The limit_remote_addr function restricts access to the admin interface based on IP address to enhance security. The /subscribe endpoint handles user subscriptions by checking for duplicate entries before saving new subscriber data to MongoDB. The /send-newsletters route triggers asynchronous email dispatch to subscribers using Celery, allowing for non-blocking operations and immediate feedback to the user that emails are being sent.
In your tasks.py, add the following code snippets:
This will set up a Celery task that handles the sending of emails asynchronously. When the send_emails task is called, it iterates through each subscriber, composing and sending an email using Flask-Mail. For each successful email sent, the details are logged into the MongoDB deliveries collection with the recipient's email, email title, body, and the timestamp of when it was sent. If an error occurs during the email-sending process, it is caught and logged, which ensures that Celery handles failures and maintains a record of all email transmission attempts.
Finally, in your app.py, add the following code snippets:
This will initialize your Flask application using configurations loaded from your configuration file. It sets up Flask-Mail for email functionality, connects to MongoDB using PyMongo, and configures Celery with the specified broker from the configuration file. Then, the routes and tasks are imported to integrate endpoint definitions and background task functions into the app. Additionally, it runs the application in debug mode to allow for real-time debugging and development, making it easier to track down issues as they arise.

Testing the application

Everything is all set up for your newsletter platform. Now, it's time to see how it works. To start your Flask application, navigate to your project directory in the terminal and execute the following command:
On another terminal window, execute the following command to start the celery worker:
To access your newsletter platform, navigate to localhost:5000 on your web browser. You will see the initial landing page as depicted below:
Viewing newsletter landing page
For administrative functions, visit the admin page at localhost:5000/admin. The page should look like this:
Viewing the newsletter admin page
To test your application, subscribe via the homepage. You can add as many subscribers as you wish. Upon successful subscription, you should see a confirmation similar to this:
Adding a subscriber
The form will clear and a success message will be displayed.
To verify the subscription data, use the following MongoDB commands in your terminal:
You should see that a database named newsletter has been created along with a subscribers collection containing the subscription entries:
Next, to send batch emails, go to your admin page at localhost:5000/admin and dispatch a newsletter. Your Celery backend should log the following upon successful email dispatch:
Confirm the creation of the deliveries collection alongside subscribers in your MongoDB database:
To review the contents of the deliveries collection and verify the details of the emails sent, use the following command in your MongoDB shell:
This command will display the records in the deliveries collection in a formatted manner, allowing you to easily review each entry. You should see data similar to the following output, which includes details such as email address, title of the newsletter, body content, and the timestamp of when each email was sent.
This ensures you can track the success and content of each dispatch within your newsletter system.

Conclusion

And there you have it! You've created a powerful and interactive newsletter platform. This project not only allowed you to deepen your understanding of Python, JavaScript, Flask, and MongoDB but also gave you a glimpse of how these technologies intertwine to create a functional web application.
As you admire your creation, remember that this is just the beginning. You can continue to enhance this platform with more features like automated responses, analytics integration to track subscriber engagement, and customizable email templates. The beauty of creating is that it's never truly finished. There's always something more to add, to improve, and to innovate. So, keep exploring, keep learning, and most importantly, keep creating.
Want to continue the conversation? If you have questions or want to connect with other folks building cool things with MongoDB, head to our Developer Community next.
Top Comments in Forums
There are no comments on this article yet.
Start the Conversation

Facebook Icontwitter iconlinkedin icon
Rate this tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Related
Tutorial

How to Maintain Multiple Versions of a Record in MongoDB (2024 Updates)


May 16, 2024 | 6 min read
Tutorial

How to Use Custom Aggregation Expressions in MongoDB 4.4


Sep 23, 2022 | 11 min read
Quickstart

Java - Mapping POJOs


Mar 01, 2024 | 5 min read
Tutorial

Symfony and MongoDB Workshop: Building a Rental Listing Application


Apr 08, 2024 | 3 min read
Table of Contents