Solved: Forwarding SMS from Twilio to Email for 2FA Sharing

Source: Dev.to | Jan 30, 2026 (UTC)

🚀 Executive Summary

TL;DR: On-call teams often face bottlenecks sharing 2FA codes from physical phones. This solution details building a robust Twilio-to-email forwarder using a Python Flask webhook to automatically deliver SMS codes to a team distribution list, eliminating coordination overhead.

🎯 Key Takeaways

  • A Python Flask application serves as the webhook endpoint, receiving incoming SMS from Twilio and processing them for email forwarding.
  • Environment variables, loaded via python-dotenv from a config.env file, are crucial for securely managing sensitive credentials like Twilio Account SID/Auth Token and email service API keys.
  • Proper configuration of the Twilio phone number’s ‘A MESSAGE COMES IN’ webhook URL to point to the publicly accessible Flask application endpoint (e.g., https://your-app-name.com/sms) is essential for functionality.

Forwarding SMS from Twilio to Email for 2FA Sharing

Darian Vance here. Let’s talk about a common headache in any team that shares on-call duties or access to a central service: the dreaded 2FA code. For a while, my team had a physical “on-call phone” that we’d pass around. It was a mess. The phone would get left at the office, run out of battery, you name it. We were constantly blocked. I finally decided to solve this properly, and this Twilio-to-email forwarder is the result. It’s a simple, robust solution that turns SMS codes into emails sent to a team distribution list. It saved us countless hours of coordination overhead, and I think it can do the same for you.

Let’s get this set up. It’s faster than you think.

Prerequisites

Before we dive in, make sure you have the following ready to go:

  • A Twilio account with an active phone number. You’ll need your Account SID and Auth Token.
  • An email delivery service account. I’m a fan of SendGrid for its reliability, but others like Mailgun or AWS SES work just as well. You’ll need an API key.
  • A Python environment. We’ll be using Flask to create a simple web server to act as our webhook.

The Guide: Building the Forwarder

Step 1: Set Up Your Project and Environment

First things first, get your project directory organized. I’ll skip the standard virtualenv setup since you likely have your own workflow for that. Just make sure you have a clean environment to work in. You’ll need to install a few Python packages. I use pip for this, so you’d run the commands to install twilio, flask, python-dotenv, and your email provider’s library (e.g., sendgrid).

Next, create a file named config.env. This is where we’ll store our secrets. Storing credentials directly in the code is a huge security risk, and this method keeps them separate and safe. Your file should look like this:

# Twilio Credentials TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx TWILIO_AUTH_TOKEN=your_twilio_auth_token # Email Configuration SENDGRID_API_KEY=SG.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx [email protected] [email protected]

Enter fullscreen mode

Exit fullscreen mode

Step 2: The Python Webhook Script

This is where the magic happens. We’ll write a small Flask application that listens for incoming messages from Twilio. When Twilio receives an SMS on your number, it will send a POST request to our application’s endpoint. Our script will then parse that request and use our email service to forward the message content.

Create a file, let’s call it app.py, and add the following code:

import os from dotenv import load_dotenv from flask import Flask, request from twilio.twiml.messaging_response import MessagingResponse from sendgrid import SendGridAPIClient from sendgrid.helpers.mail import Mail # Load environment variables from config.env load_dotenv('config.env') app = Flask(__name__) # Fetch credentials from environment SG_API_KEY = os.getenv('SENDGRID_API_KEY') FROM_EMAIL = os.getenv('FROM_EMAIL') TO_EMAIL = os.getenv('TO_EMAIL') @app.route("/sms", methods=['POST']) def sms_webhook(): """ Receives an SMS from Twilio and forwards it via SendGrid. """ # Get the SMS message body and sender number from the request message_body = request.values.get('Body', 'No content') from_number = request.values.get('From', 'Unknown sender') # Prepare the email content email_subject = f"New SMS from {from_number}" email_content = f"<h2>SMS Received</h2><p><strong>From:</strong> {from_number}</p><p><strong>Message:</strong></p><pre>{message_body}</pre>" # Create the Mail object message = Mail( from_email=FROM_EMAIL, to_emails=TO_EMAIL, subject=email_subject, html_content=email_content ) try: # Use the SendGrid client to send the email sg = SendGridAPIClient(SG_API_KEY) response = sg.send(message) print(f"Email sent with status code: {response.status_code}") except Exception as e: # In a real app, I'd have more robust logging here print(f"Error sending email: {e}") # Even if email fails, we respond to Twilio to avoid an error loop pass # Respond to Twilio to acknowledge receipt of the SMS twiml_response = MessagingResponse() return str(twiml_response) if __name__ == "__main__": app.run(debug=True, port=5002)

Enter fullscreen mode

Exit fullscreen mode

Pro Tip: Validate Twilio Requests

In my production setups, I never trust an open webhook. Twilio cryptographically signs its requests, and you should validate that signature. The twilio Python library includes a RequestValidator helper class. You’d initialize it with your Auth Token and then check if the request is legitimate before processing it. This prevents anyone on the internet from spamming your email forwarder by just sending POST requests to your URL.

Step 3: Deploy and Configure the Webhook

This Flask app needs to be running on a server with a public IP address or URL so Twilio can reach it. You could use a small cloud VM, a PaaS like Heroku, or a serverless function. For a quick test, a tool like ngrok is fantastic for exposing your local development server to the internet.

Once your application is live and you have its public URL (e.g., https://your-app-name.herokuapp.com/sms), you need to tell Twilio where to send the messages.

  1. Go to your Twilio console and navigate to “Phone Numbers” > “Manage” > “Active Numbers”.
  2. Click on the number you’re using for this forwarder.
  3. Scroll down to the “Messaging” section.
  4. Under “A MESSAGE COMES IN”, select “Webhook”.
  5. Paste your public URL into the text box and ensure the method is set to “HTTP POST”.
  6. Click “Save”.

That’s it! Send a test SMS to your Twilio number, and you should see an email arrive in the inbox you specified in config.env moments later.

Common Pitfalls (Where I Usually Mess Up)

Conclusion

And there you have it. A simple, server-side solution that completely removes the bottleneck of a shared physical phone for 2FA. This setup is lightweight, cheap to run, and infinitely more scalable than passing a device around. It’s one of those small DevOps improvements that pays dividends in team sanity and efficiency every single day. Hope this helps you out!

👉 Read the original article on TechResolve.blog

☕ Support my work

If this article helped you, you can buy me a coffee:

👉 https://buymeacoffee.com/darianvance

For further actions, you may consider blocking this person and/or reporting abuse

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *

Читайте також