All docschevron-rightHelpchevron-rightarrow-leftTutorialschevron-rightAdd a static map to an MMS text message

Add a static map to an MMS text message

Intermediate
codeJavaScript
Prerequisite

Familiarity with front-end development concepts.

book
Twilio MMS Geographic Restrictions

This tutorial uses Twilio Programmable Messaging to send MMS messages. At the time of writing, Twilio can only send MMS messages from accounts registered in the United States and Canada; developers outside of those countries should consider using a different MMS API.

This tutorial uses the Mapbox Static Images API and Twilio Programmable Messaging to add a customized static map of an address mentioned in an emergency alert to a text message.

Adding location context, like maps, to emergency alert text messages helps users quickly recognize where an incident occurred, increasing awareness and the likelihood that they will avoid the area. Static maps from the Mapbox Static Images API are a lightweight, text-friendly way to add location context to emergency alerts.

This tutorial assumes that your data for the emergency alert already includes geocoded latitude and longitude coordinates. If you need to geocode addresses, use the Geocoding API Playground.

Getting started

To complete this tutorial, you will need:

  • A Mapbox account and access token. Sign up for an account at mapbox.com/signup. You can find your access tokens on your account page.
  • A Twilio account. Sign up for a Twilio account at twilio.com/try-twilio. While this tutorial uses Twilio Programmable Messaging for text message templates and delivery, you are welcome to use an MMS delivery system of choice.
  • A text editor. Use the text editor of your choice for writing HTML, CSS, and JavaScript.

Create a text message template

First, we will create an emergency alert text template for Twilio Programmable Messaging using Node.js. This template does not include a map yet.

Set up node.js

First, you will need to create a Node project with access to the twilio Node helper library. To properly get set up:

  1. Create an empty directory where your code and libraries will live.
  2. In your terminal, cd into this directory.
  3. Create an empty folder called node_modules in the directory.
  4. Run npm install twilio to install the necessary helper library.
  5. Create an empty file named mms.js and open it in your text editor.

Paste the following code into mms.js:

const accountSid = '';
const authToken = '';
const client = require('twilio')(accountSid, authToken);

client.messages
  .create({
    body: '',
    from: '',
    mediaUrl: [''],
    to: ''
  })
  .then((message) => console.log(message.sid));

You will soon replace the placeholder values given in the sample.

Gather information from Twilio

To send texts with Twilio's API, you will need a phone number with MMS enabled, an accountSid, and an authToken.

To find your Twilio phone number, first log in to Twilio. Then, navigate to your active numbers page in your console. You should have received a phone number with MMS enabled when signing up for Twilio, but if not, you will have to buy a number.

After acquiring a phone number, head over to your console and scroll down. You will find your accountSid and authToken; take note of these.

Write the script

You now have all the information required to send an MMS message with Twilio Programmable Messaging. Go back to your mms.js file and fill in the following placeholder values:

  • const accountSid = your noted accountSid as String
  • const authToken = your noted authToken as String
  • body: "If there were an emergency at Commonwealth Ave and St Paul Street, you should avoid the area."
  • from: your Twilio phone number as String; remember to include the international dialing prefix +1
  • to: the phone number you wish to send a message to. For testing, use your personal phone number as String

Keep mediaUrl empty for now; you will place a Static Images API call there shortly.

Add a static map

Create a Mapbox Static Images API call

The syntax for the Mapbox Static Images API is https://api.mapbox.com/styles/v1/{username}/{style_id}/static/{longitude},{latitude},{zoom_level}/{image_width}x{image_height}. A successful Static Images API call requires at least seven parameters:

  • Username: The mapbox.com username that owns the map style used in your static map. If you’re using a Mapbox-designed template style like Mapbox Light or Mapbox Streets, use mapbox. If you’re using a custom style, this is your username.
  • Style ID: The style ID of the map style used in your static map. For example, if you’re using the Mapbox Streets style, the style ID is streets-v12. For custom styles, you can find your style ID in the styles page in Mapbox Studio.
  • Longitude: The longitude (a number between -180 and 180) of the center point for the static map. For our restaurant, this is -77.0187.
  • Latitude: The latitude (a number between -85.0511 and 85.0511) of the center point for the static map. For our restaurant, this is 38.90227.
  • Zoom level: The zoom level of the static map. Web maps have zoom levels that range from 0 (the entire planet) to 22 (part of a building).
  • Image width and height: The size of the static map image in pixels. The minimum size is 1x1 and the maximum size is 1280x1280.
  • Access token: Like the Mapbox Geocoding API, the Mapbox Static Images API requires a public access token for billing. This access token is not sensitive and is safe to use in front-end code.

Here’s a Static Images API URL for our restaurant using the Mapbox Streets style. Copy and paste this link into your web browser to test out the static map:

https://api.mapbox.com/styles/v1/mapbox/streets-v11/static/-71.1156,42.3511,15,0/320x150?access_token=YOUR_MAPBOX_ACCESS_TOKEN

Since we’re showing an intersection in an urban area, we’ll use 15 for the zoom level. Zoom level 15 provides enough context of the intersection (Commonwealth Ave & St Paul St) and enough neighborhood context (Boston University) to know where the intersection is in Boston.

If you’re showing maps for non-urban areas, you may want to use zoom levels 11-13 for suburban locations and 7-10 for rural areas. You could add information about whether the area is urban, suburban, or rural to the transaction JSON and then dynamically change the zoom level in the text.

Visit the Static Images API Playground to test out different zoom levelschevron-right

Update the MMS template

To add the static map to our MMS template, simply copy the URL of the Static Images API call into the mediaUrl property like so:

[
  'https://api.mapbox.com/styles/v1/mapbox/dark-v12/static/pin-l(-77.0187,38.90227)/-77.0187,38.90227,14/320x150?access_token=YOUR_MAPBOX_ACCESS_TOKEN'
];

One you have assigned mediaUrl, run node mms.js in your directory to test your app. If successful, you will receive the text message ID in your computer's console, and your phone will receive a text message that looks like this a few seconds later:

Customize the map

The Mapbox Streets style includes some points of interest (POIs) that we don’t need for a small map. It’s also unclear where the emergency incident is in the static map. We can improve our static map implementation by changing the map style, adding a marker, adjusting attribution, and enabling high-density display support.

Map style

The Mapbox Streets style features various points of interest (POIs) that aren’t relevant to our use case. We can swap the Mapbox Streets style (style ID streets-v12) with either the Mapbox Light style (style ID light-v11) or the Mapbox Dark style (style ID dark-v11) to quickly hide all POI categories. While both map styles match our color scheme, Mapbox Light looks better in iOS Light Mode.

Update the mediaUrl property in your mms.js. Find the string "streets-v11" and change it to "light-v10". Your map should look like this:

If you need to further customize your map style - like highlighting nearby POIs while keeping Light style - you can create a custom style in Mapbox Studio. In the Static Images API URL, replace mapbox with your username and replace streets-v12 or dark-v11 with the style ID for your custom style. You will need to publish your custom style before using it with the Static Images API.

Adding a marker

While our static map shows the neighborhood of our incident, it’s not clear where the emergency is on the map. We can add or overlay a marker to show the exact location.

To add a default map marker to our Static Images API URL, add pin-s+555555(-71.115799,42.351133)/ after /static/. This parameter will add a large pin (pin-s) using a gray pin color #555555 at longitude -71.115799 and latitude 42.351133. Here’s our updated URL and static map with the new pin parameter:

https://api.mapbox.com/styles/v1/mapbox/light-v11/static/pin-s+555555(-71.115799,42.351133)/-71.1156,42.3511,15,0/320x150?access_token=YOUR_MAPBOX_ACCESS_TOKEN

We can further customize static map markers with any Maki icon. Here’s our new map marker using the cross Maki icon:

https://api.mapbox.com/styles/v1/mapbox/light-v11/static/pin-s-cross+555555(-71.115799,42.351133)/-71.1156,42.3511,15,0/320x150?access_token=YOUR_MAPBOX_ACCESS_TOKEN

At any time, replace your mediaUrl property in mms.js to change the image to send through text messaging.

Attribution

Our map is small (320x150px), and every pixel matters. The attribution in the bottom right-hand corner takes up a lot of space. We must provide attribution though since we’re using a Mapbox-designed template style (Mapbox Light) with a Mapbox tileset (Mapbox Streets). If it improves our design, we can move the attribution from the image to the body of the text itself (text attribution).

Add attribution=false& to the Static Images API URL in mediaUrl between 320x150? and accessToken=. Your URL will look like this:

https://api.mapbox.com/styles/v1/mapbox/light-v11/static/pin-s-cross+555555(-71.115799,42.351133)/-71.1156,42.3511,15,0/320x150?attribution=false&access_token=YOUR_MAPBOX_ACCESS_TOKEN

Add the following to the body of the text to add text attribution:

Map provided by Mapbox (https://www.mapbox.com/about/maps/) and OpenStreetMap (https://www.openstreetmap.org/copyright). Improve this map: https://www.mapbox.com/contribute

High-density display support

We have one final optimization before our MMS map is ready for production. Our map looks fuzzy and pixelated on high-density displays, like on an iPhone with Retina support.

The Mapbox Static Images API supports high-density displays. Add @2x after the parameters for image width and height:

https://api.mapbox.com/styles/v1/mapbox/light-v11/static/pin-s-cross+555555(-71.115799,42.351133)/-71.1156,42.3511,15,0/320x150@2x?attribution=false&access_token=YOUR_MAPBOX_ACCESS_TOKEN

Enabling high-density display support will automatically double the image size on low-density displays. Our map image is 320x150@2x or 640x300 pixels. Adding @2x to our API call doubles the width of our map on low-density displays.

One downside of our new static map is that low-density display users will download higher resolution images than needed, decreasing texting and network performance.

Final product

You built a static map text message for an emergency alert using the Mapbox Static Images API. We used the Mapbox Light map style and Maki icons to optimize our static map for texting use cases. Our map supports high-density displays. We also used text attribution to improve the design of our text.

By the end of this tutorial, the JavaScript in mms.js should look like this. Replace necessary variables, like YOUR_MAPBOX_ACCESS_TOKEN, accountSid, and authToken.

const accountSid = 'my accountSid';
const authToken = 'my authToken';
const client = require('twilio')(accountSid, authToken);

client.messages
  .create({
    body: 'If there were an emergency at Commonwealth Ave and St Paul Street, you should avoid the area. \n\nMap provided by Mapbox (https://www.mapbox.com/about/maps/) and OpenStreetMap (https://www.openstreetmap.org/copyright). Improve this map: https://www.mapbox.com/contribute',
    from: 'my Twilio number',
    mediaUrl: [
      'https://api.mapbox.com/styles/v1/mapbox/light-v11/static/pin-s-cross+555555(-71.115799,42.351133)/-71.1156,42.3511,15,0/320x150@2x?attribution=false&access_token=YOUR_MAPBOX_ACCESS_TOKEN'
    ],
    to: 'my personal number'
  })
  .then((message) => console.log(message.sid));

After editing your JavaScript code, run node mms.js in your project directory to use your app.

Next steps

Learn how to customize your static map further and build for other use cases.

Was this page helpful?