James Jashinski
James Jashinski

Reputation: 23

How do I forward an MMS message using sendgrid?

The following code is straight out of the examples. It works like a charm for an SMS message. The event.Body most not be present on an MMS message. I would like some code so the an incoming SMS or MMS message can be captured and sent using sendgrid.

This is the Exact error from the twilio site.

Error - 82002 Error on Twilio Function response Your Function invocation resulted in StatusCode 5xx.

Possible Causes Your Function timed out before responding Your Function returned an error response

Possible Solutions Your Function must contain a callback. Make sure you place the Function callback callback(err, response) is placed correctly in your Function code. If you are using a JavaScript promise, make sure the callback is called in both success and catch blocks. Your Function responded with an error.


const got = require('got'); 

exports.handler = function(context, event, callback) { 
      const requestBody = { 
    personalizations: [{ to: [{ email: context.TO_EMAIL_ADDRESS }] }], 
    from: { email: context.FROM_EMAIL_ADDRESS }, 
    subject: `New SMS message from: ${event.From}`, 
    content: [ 
      { 
        type: 'text/plain', 
        value: event.Body 
      } 
    ] 
      }; 
    let twiml = new Twilio.twiml.MessagingResponse(); 
    
    got.post('https://api.sendgrid.com/v3/mail/send', { 
    headers: { 
      Authorization: `Bearer ${context.SENDGRID_API_KEY}`, 
      'Content-Type': 'application/json' 
    }, 
    body: JSON.stringify(requestBody) 
  }) 
    .then(response => { 
      callback(null, twiml); 
    }) 
    .catch(err => { 
      callback(err); 
    });   
    
    
}; 

Looking for help in sending the email on an incoming MMS message from twilio.

Thanks in advance.

Upvotes: 2

Views: 583

Answers (2)

lizziepika
lizziepika

Reputation: 3300

Twilio Developer Evangelist here.

You can forward MMS messages to email with SendGrid in Node.js with Express by saving the inbound image using Request, as further detailed in this blog post by my teammate Sam Agnew.

First, we need to require all the modules we are going to use, creating an Express app object and adding the Body Parser middleware to it.

const fs = require('fs');
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const sgMail = require('@sendgrid/mail');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));

Next we need to create a route in this Express app to handle the POST request sent by Twilio when a MMS is sent to your Twilio number. This code saves the inbound image (you can get the URL of the inbound image with req.body.MediaUrl0) and waits a few seconds (the code below uses native Promises for this) for the image to save in the same directory as your Node.js file. It then sends that image inline in an email with SendGrid. This is done by setting disposition: 'inline' under attachments and also setting the content_id there so you can reference it in the HTML part of your email's message body.

It's also important to convert the image to a base64-encoded string, which you can do with readFileSync, as shown below.

app.post('/sms', (req, res) => {
    sgMail.setApiKey(
        'REPLACE-WITH-YOUR-SENDGRID-API-KEY'
    );
    const filename = `${req.body.MessageSid}.png`;
    const url = req.body.MediaUrl0;
    request(url)
        .pipe(fs.createWriteStream(filename))
        .on('open', () => console.log('image downloaded'));
    const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs));
    sleep(3000).then(() => {
        const msg = {
            to: `EMAIL-YOU-WANT-TO-RECEIVE-IMAGE`,
            from: `EMAIL-TO-SEND-FROM`,
            subject: `Send an image!`,
            html: `<body><p>Image is below</p><img src= "cid:mmsimg" alt='test image' /></body>`,
            attachments: [
                {
                    filename: filename,
                    type: 'image/png',
                    content_id: 'mmsimg',
                    content: fs.readFileSync(filename, { encoding: 'base64' }),
                    disposition: 'inline'
                }
            ]
        };
        sgMail.send(msg).then(result => {
            console.log(result);
        })
        .catch(err => {
            console.log(err);
        });
    });
});

Lastly, we make the Express app listen for requests on port 3000.

app.listen(3000, () => console.log('Listening on port 3000!'));

Hope this helps!

Upvotes: 3

Alan
Alan

Reputation: 10771

James, if you are ok with just sending the URL of the MMS via email instead of the actual physical MMS media and make some assumptions (like your sending a single MMS without a body), you can easily modify the code by modifying a few lines.

Say:

const bodyContent = event.Body || event.MediaUrl0; 

(and refer to bodyContent later in the code, instead of event.Body).

This will set the email Body to either the incoming SMS body or the URL to the MMS if the Body is null.

You can easily modify the Twilio Function, based on this information, so it can deal with mixed use cases.

How do I retrieve the MediaUrl parameter for an MMS I received?

Upvotes: 2

Related Questions