Automating Email Verification Using Google Workspace and Flask API
A comprehensive guide to setting up automated email verifications with Flask and Google Workspace
Key Takeaways
- Seamless Integration: Utilize the Gmail API for robust and secure email sending from your Flask application.
- Secure Authentication: Implement OAuth 2.0 to ensure a secure connection between Flask and Google Workspace.
- Scalable Solutions: Leverage Celery and Redis for asynchronous email processing to handle high volumes efficiently.
Introduction
Automating email verification is a crucial feature for web applications to ensure that users provide valid email addresses during registration. By integrating Google Workspace with a Flask API, developers can create a reliable system to send verification emails automatically. This guide provides an in-depth, step-by-step process to set up this integration, ensuring security, scalability, and efficiency.
1. Setting Up Google Cloud Project and Enabling Gmail API
To start automating email verifications, you first need to set up a project in the Google Cloud Console and enable the Gmail API.
a. Create a New Project
- Navigate to the Google Cloud Console.
- Click on the project dropdown and select New Project.
- Enter a project name, for example, "FlaskEmailVerification," and click Create.
b. Enable the Gmail API
- Within your newly created project, go to APIs & Services > Library.
- Search for "Gmail API" and select it.
- Click Enable to activate the API for your project.
2. Obtaining OAuth 2.0 Credentials
OAuth 2.0 is essential for securely accessing the Gmail API. Follow these steps to obtain the necessary credentials.
a. Configure OAuth Consent Screen
- In the Google Cloud Console, navigate to APIs & Services > OAuth consent screen.
- Select External for the user type and click Create.
- Fill in the required fields such as Application name, Support email, and add scopes if necessary.
- Save and continue through the remaining steps, adding any necessary information.
b. Create OAuth 2.0 Credentials
- Go to APIs & Services > Credentials.
- Click Create Credentials > OAuth client ID.
- Select Web application as the application type.
- Provide an appropriate name, such as "FlaskAppClient."
- Under Authorized redirect URIs, add `http://localhost:5000/callback`.
- Click Create and download the `credentials.json` file. Store this file securely as it contains sensitive information.
3. Installing Required Python Libraries
Ensure that your development environment has all the necessary libraries installed to interact with the Gmail API and build the Flask application.
a. Set Up a Virtual Environment
python -m venv venv
source venv/bin/activate # On Windows use `venv\Scripts\activate`
b. Install Dependencies
pip install Flask Flask-Mail google-auth google-auth-oauthlib google-auth-httplib2 google-api-python-client celery redis
Explanation of Libraries:
Flask: Web framework for building the API.Flask-Mail: Facilitates sending emails from Flask.google-auth,google-auth-oauthlib,google-auth-httplib2: Handle authentication with Google APIs.google-api-python-client: Allows interaction with Google APIs, including Gmail.Celery: Task queue for managing asynchronous tasks.Redis: In-memory data structure store, used as a broker for Celery.
4. Configuring Flask Application for Gmail API Integration
With the necessary libraries installed and credentials obtained, the next step is to configure your Flask application to interact with the Gmail API.
a. Setting Up the Flask App
import os
import base64
from flask import Flask, redirect, url_for, session, request, jsonify
from flask_mail import Mail, Message
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import Flow
from googleapiclient.discovery import build
from celery import Celery
app = Flask(__name__)
app.secret_key = 'your_secret_key' # Replace with your secret key
# Flask-Mail Configuration
app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = 'your_workspace_email@yourdomain.com'
app.config['MAIL_PASSWORD'] = 'your_app_specific_password' # Use app password if two-factor is enabled
mail = Mail(app)
# Celery Configuration
app.config['CELERY_BROKER_URL'] = 'redis://localhost:6379/0'
app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379/0'
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
b. Implementing OAuth 2.0 Flow
Set up the OAuth 2.0 flow to authenticate and authorize your Flask application to send emails on behalf of the user.
# Define the OAuth 2.0 scopes
SCOPES = ['https://www.googleapis.com/auth/gmail.send']
# Initialize the OAuth flow
flow = Flow.from_client_secrets_file(
'path/to/credentials.json', # Path to your credentials.json
scopes=SCOPES,
redirect_uri='http://localhost:5000/callback'
)
@app.route('/')
def index():
authorization_url, state = flow.authorization_url(
access_type='offline',
include_granted_scopes='true'
)
session['state'] = state
return redirect(authorization_url)
@app.route('/callback')
def callback():
flow.fetch_token(authorization_response=request.url)
if not flow.credentials:
return 'Authorization failed', 400
session['credentials'] = credentials_to_dict(flow.credentials)
return 'Authentication successful. You can close this window.'
def credentials_to_dict(credentials):
return {
'token': credentials.token,
'refresh_token': credentials.refresh_token,
'token_uri': credentials.token_uri,
'client_id': credentials.client_id,
'client_secret': credentials.client_secret,
'scopes': credentials.scopes
}
c. Sending Emails via Gmail API
Implement the functionality to send emails using the Gmail API.
def send_email_via_gmail(to_email, subject, body):
creds = Credentials(**session.get('credentials'))
service = build('gmail', 'v1', credentials=creds)
message = MIMEText(body)
message['to'] = to_email
message['from'] = app.config['MAIL_USERNAME']
message['subject'] = subject
raw_message = base64.urlsafe_b64encode(message.as_bytes()).decode()
try:
message = service.users().messages().send(userId='me', body={'raw': raw_message}).execute()
print(f'Message sent: {message["id"]}')
return True
except Exception as e:
print(f'An error occurred: {e}')
return False
5. Implementing Email Verification Logic
With the email sending functionality in place, the next step is to implement the logic for email verification.
a. Creating Verification Tokens
Generate unique verification tokens to securely verify user email addresses.
import jwt
import datetime
SECRET_KEY = 'your_jwt_secret_key' # Replace with your JWT secret key
def generate_verification_token(email):
payload = {
'email': email,
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=24) # Token expires in 24 hours
}
token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
return token
def verify_token(token):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
return payload['email']
except jwt.ExpiredSignatureError:
return None
except jwt.InvalidTokenError:
return None
b. Setting Up Verification Routes
Create routes in your Flask application to handle user registration and email verification.
@app.route('/register', methods=['POST'])
def register():
data = request.get_json()
email = data.get('email')
if not email:
return jsonify({'error': 'Email is required'}), 400
token = generate_verification_token(email)
verification_link = url_for('verify_email', token=token, _external=True)
subject = 'Email Verification'
body = f'Please click the link below to verify your email address:\n{verification_link}'
# Send the verification email asynchronously
send_verification_email.delay(email, subject, body)
return jsonify({'message': 'Verification email sent'}), 200
@celery.task
def send_verification_email(to_email, subject, body):
send_email_via_gmail(to_email, subject, body)
@app.route('/verify/')
def verify_email(token):
email = verify_token(token)
if email:
# Update user status in the database to verified
# Example: User.query.filter_by(email=email).update({'is_verified': True})
# db.session.commit()
return 'Email verified successfully!', 200
else:
return 'Verification link is invalid or has expired.', 400
6. Handling SMTP as an Alternative
If you prefer not to use the Gmail API, you can configure your Flask application to send emails using the SMTP protocol via Flask-Mail.
a. Configuring Flask-Mail
from flask_mail import Mail, Message
# Flask-Mail configuration is already set in the earlier Flask app setup
mail = Mail(app)
@app.route('/send-smtp-email', methods=['POST'])
def send_smtp_email():
data = request.get_json()
recipient = data.get('email')
subject = 'SMTP Email Verification'
body = 'Please verify your email address using the SMTP method.'
msg = Message(subject, sender=app.config['MAIL_USERNAME'], recipients=[recipient])
msg.body = body
try:
mail.send(msg)
return jsonify({'message': 'SMTP Verification email sent'}), 200
except Exception as e:
return jsonify({'error': str(e)}), 500
b. Advantages of Using SMTP
- Simplicity in setup without needing OAuth 2.0.
- Suitable for applications with lower email sending requirements.
7. Ensuring Application Security
Security is paramount when handling user data and integrating with external APIs. Implement the following best practices to secure your application.
a. Protect Sensitive Information
- Store sensitive credentials, such as `credentials.json` and `SECRET_KEY`, in environment variables or secure configuration files.
- Never expose these credentials in your source code repositories.
b. Implement HTTPS
Use HTTPS to encrypt data in transit between your Flask application and users.
c. Rate Limiting
Prevent abuse by limiting the number of requests a user can make within a specific timeframe.
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
limiter = Limiter(
app,
key_func=get_remote_address,
default_limits=["200 per day", "50 per hour"]
)
8. Managing Email Sending Limits
Google Workspace imposes daily email sending limits based on your subscription plan. It is essential to manage these limits to prevent your application from exceeding them.
a. Understand Email Limits
- Standard Gmail accounts: Up to 100 emails per day.
- Google Workspace accounts: Ranges from 100 to 5,000 emails per day depending on the plan.
b. Implement Queue Management
Use Celery with Redis to queue email sending tasks, allowing you to control the rate of emails being sent and handle retries in case of failures.
@celery.task(bind=True, max_retries=3)
def send_email_task(self, to_email, subject, body):
try:
send_email_via_gmail(to_email, subject, body)
except Exception as exc:
raise self.retry(exc=exc, countdown=60)
c. Monitoring and Alerts
Set up monitoring to track email sending rates and receive alerts when approaching or exceeding limits.
9. Optional: Asynchronous Email Sending with Celery and Redis
For applications that require sending a high volume of emails, it's advisable to handle email sending asynchronously to improve performance and reliability.
a. Setting Up Celery with Flask
# tasks.py
from your_flask_app import celery
@celery.task
def send_async_email(to_email, subject, body):
send_email_via_gmail(to_email, subject, body)
b. Starting the Celery Worker
celery -A your_flask_app.celery worker --loglevel=info
c. Integrating with Flask Routes
@app.route('/send-async-email', methods=['POST'])
def send_async():
data = request.get_json()
to_email = data.get('email')
subject = 'Asynchronous Email Verification'
body = 'This is an asynchronously sent verification email.'
send_async_email.delay(to_email, subject, body)
return jsonify({'message': 'Async Verification email sent'}), 200
10. Testing the Email Verification System
Before deploying your application, thoroughly test the email verification system to ensure reliability and functionality.
a. Local Testing
- Run your Flask application locally and perform registration to trigger email sending.
- Use tools like Mailtrap to capture and inspect outgoing emails without sending them to actual users.
b. Deployment Testing
-
Deploy your Flask application to a staging environment.
-
Perform end-to-end testing to ensure that emails are sent and verification links function correctly.
11. Recap
Automating email verification in a Flask API using Google Workspace involves setting up a Google Cloud project, enabling the Gmail API, and securing OAuth 2.0 credentials. Integrating these with Flask, along with tools like Celery and Redis, ensures a scalable and secure email verification system. By following best practices in security and managing email sending limits, you can create a reliable verification process that enhances user trust and application integrity.
References
Last updated January 11, 2025