Retrieving Twilio MMS Image URLs in Python

July 25, 2020
Written by
Sam Agnew
Twilion

Copy of Generic Blog Header 4.png

When working with Twilio MMS, you often need to access a URL to the pictures contained in a message. Typically when the message is initially received, the webhook request that Twilio sends to your application will contain MediaUrl properties that you can use directly in your application. But if you want to use the REST API to access a URL to an image contained in a Message Resource, you need to do a little more work, as the only option available to you is the uri of the Media resource:

if int(message.num_media) > 0:
    for media in message.media.list():
        media_url = 'https://api.twilio.com' + media.uri[:-5] # Strip off the '.json'
        print(media_url)

Let's walk through a few different ways to retrieve a media URL from a Twilio MMS message in Python. To try these examples for yourself, make sure you have a Twilio account and a phone number as well as Python installed on your machine with a local developer environment set up.

You'll also need to install the Twilio Python helper library:

pip install twilio==6.39.0

Accessing an image URL when an MMS message is received

If you want to access the image URL in a function that deals with a webhook request when a picture message is received, you might do something like this:

def sms_reply():
    if int(request.values['NumMedia']) > 0:
       image_url = request.values['MediaUrl0']
   # Do other stuff

Let's walk through a quick example using the Flask microframework. If you want to try this for yourself, you'll need to install Flask:

pip install Flask==1.1.2

For a basic web application that receives an MMS message containing an image and responds back with that same image, create a file called app.py and add the following code to it:

from flask import Flask, request
from twilio.twiml.messaging_response import MessagingResponse


app = Flask(__name__)


@app.route("/", methods=['GET', 'POST'])
def sms_reply():
    """Respond to incoming with a simple text message."""

    if int(request.values['NumMedia']) > 0:
       image_url = request.values['MediaUrl0']

    resp = MessagingResponse()
    resp.message("Thanks for the image!").media(image_url)
    return str(resp)

if __name__ == '__main__':
    app.run()

Run the file with the command python app.py in your terminal from the directory where the code exists.

To avoid having to deploy code just to test our app, we’ll use a nifty tool called ngrok to open a tunnel to our local machine.

Ngrok generates a custom forwarding URL that we will use to tell Twilio where to find our application. Download ngrok and run it in your terminal on port 5000:

./ngrok http 5000

Open the phone number configuration screen in your Twilio console. Scroll down to the “a message comes in” field. You should see something like this:

Twilio console

Copy and paste the URL that was generated by ngrok, click save, then text a picture to your number to see it sent back to you from your Twilio number.

Accessing an image URL with the Twilio REST API

As mentioned before, the only thing that's available to you when it comes to messages that have already been received is the uri property on a Media resource, perhaps one that you retrieved from a Message resource.

If you just followed the previous steps to send an image to your Twilio phone number, you can access this using the Twilio REST API by fetching the message resource and building the media URL manually from this uri property.

Run the following Python code to fetch messages sent to your Twilio number that contain media and print the URLs (if you just want to test this out and you haven't sent any media to your Twilio number, try texting an image right now):

from twilio.rest import Client


# Grab your Account Sid and Auth Token from twilio.com/console and set them as
# Environment variables named: "TWILIO_ACCOUNT_SID" and "TWILIO_AUTH_TOKEN"
client = Client()

# Print all image URLs for messages sent to your number containing media.
for msg in client.messages.list(to='your-twilio-number'):
    if int(msg.num_media) > 0:
        for media in msg.media.list():
            media_url = 'https://api.twilio.com' + media.uri[:-5] # Strip off the '.json'
            print(media_url)

This should print out all of the image URLs for any message sent to your Twilio number (don't forget to replace the string in the code with your Twilio number). If you want to view one of the images, copy the URL and paste it into a web browser.

What do I use this for?

At this point, you now have access directly to the URLs of images sent to your Twilio phone numbers. From here you can do all kinds of things with it. Maybe you want to display them on a web page on the Django app you built for a local farmer's market, or maybe you want to download them to a machine to do more image processing/analysis on them.

Feel free to drop me a line if you have any question or just want to show off what you build: