Search code examples
node.jstwiliosmstwilio-apimms

Twilio code (node.js) is SMS not forwarding mediaurl's in text messages


I am trying to get code (node.js) running as a Twilio function service that forwards SMS/MMS to a subscribed group of phone numbers. The code is working, except for none of the attachments are sending with the forwarded message. I'm very new to Twilio. Any and all help would be much appreciated.

Here is the code I am trying to get working:

`exports.handler = function(context, event, callback) {
    const twilioClient = context.getTwilioClient();
    const syncServiceSid = 'My_Sync_Service_ID_Would_Be_Here'; // 

    const subscribe = (phoneNumber) => {
        return twilioClient.sync.services(syncServiceSid)
            .syncLists('subscribers')
            .syncListItems
            .create({ data: { phone_number: phoneNumber } });
    };

    const unsubscribe = (phoneNumber) => {
        return twilioClient.sync.services(syncServiceSid)
            .syncLists('subscribers')
            .syncListItems
            .list()
            .then(subscribers => {
                const subscriberItem = subscribers.find(item => item.data.phone_number === phoneNumber);
                if (subscriberItem) {
                    return subscriberItem.remove();
                }
            });
    };

const sendSMS = (to, body, mediaUrl) => {
    const additionalText = "Message from the Text Group! \n From: " + event.From + "\n";  
    const modifiedBody = additionalText + body;
    const mediaUrls = event.MediaUrl || []; // Array of attachment URLs

    const messageOptions = {
        body: modifiedBody,
        from: '+18335551212',  // My real Twilio phone number would go here
        to: to, 
 
    // Add media URLs to the message options if they exist
    if (mediaUrls.length > 0) {
    messageOptions.mediaUrl = mediaUrls || [];
   };

    return twilioClient.messages.create(messageOptions);
};

    // Handle incoming message
    const incomingMessage = event.Body;

    if (incomingMessage.toLowerCase() === 'join') {
        subscribe(event.From)
            .then(() => {
                callback(null, "You have successfully joined the text group! Text the word LEAVE to stop getting messages.");
            })
            .catch(error => {
                console.error("Error subscribing:", error);
                callback(error);
            });
    } else if (incomingMessage.toLowerCase() === 'leave') {
        unsubscribe(event.From)
            .then(() => {
                callback(null, "You have successfully unsubscribed from the text group. To rejoin, text JOIN to start getting messasges again. ");
            })
            .catch(error => {
                console.error("Error unsubscribing:", error);
                callback(error);
            });
    } else {
twilioClient.sync.services(syncServiceSid)
    .syncLists('subscribers')
    .syncListItems
    .list()
    .then(subscribers => {
        const isSenderSubscribed = subscribers.some(subscriber => subscriber.data.phone_number === event.From);

        if (isSenderSubscribed) {
            console.log("Media URLs:", mediaUrl); // Added this line to check the contents of mediaUrls
            const sendMessagePromises = subscribers.map(subscriber => {
            return sendSMS(subscriber.data.phone_number, incomingMessage, mediaUrl);
});


            Promise.all(sendMessagePromises)
                .then(() => {
                    callback(null, "Message forwarded to subscribers");
                })
                .catch(error => {
                    console.error("Error sending message:", error);
                    callback(error);
                });
        } else {
            callback(null, "You are not subscribed. To join, please contact a member of the text group for information on how to join.");
        }
    })
    .catch(error => {
        console.error("Error retrieving subscribers:", error);
        callback(error);
    });

    }
};

** This code will forward only the event.body and does not include any MMS attachments. **

**If I replace the event.MediaUrl with a static array containing URLs to media content, the code forwards the message with the attachements. **


Solution

  • It appears there are some issues in your code related to how you're handling the mediaUrl for the MMS messages. Here's a breakdown of what needs to be corrected:

    The event.MediaUrl variable may contain multiple media URLs, and they will be named MediaUrl0, MediaUrl1, etc. You'll need to loop through and collect all the URLs.

    In the sendSMS function, you're using the mediaUrl variable, but you're trying to print out the content of mediaUrls (with an "s") later in the code. This inconsistency may be causing the issue. Let's streamline that.

    Your comment says you're adding a line to check the contents of mediaUrls, but you've written mediaUrl. This will cause an error.

    Here's how to correct the above points:

    Collecting all MediaUrls: Create a function to collect all media URLs from the event:

    const getMediaUrls = (event) => {
        const mediaUrls = [];
        let i = 0;
        while (event[`MediaUrl${i}`]) {
            mediaUrls.push(event[`MediaUrl${i}`]);
            i++;
        }
        return mediaUrls;
    };
    

    Refactor the sendSMS function: Use mediaUrls instead of mediaUrl to ensure consistency:

    const sendSMS = (to, body, mediaUrls) => {
        const additionalText = "Message from the Text Group! \n From: " + event.From + "\n";  
        const modifiedBody = additionalText + body;
    
        const messageOptions = {
            body: modifiedBody,
            from: '+18335551212',  // Your real Twilio phone number
            to: to
        };
    
        if (mediaUrls && mediaUrls.length > 0) {
            messageOptions.mediaUrl = mediaUrls;
        }
    
        return twilioClient.messages.create(messageOptions);
    };
    

    Correct the MediaUrls Debugging Line: Change this line:

    console.log("Media URLs:", mediaUrl);
    

    To:

    console.log("Media URLs:", mediaUrls);
    

    Finally, when you are processing the incoming message, make sure you're extracting the media URLs correctly. Update the part of the code where you handle the message forwarding to:

    const mediaUrls = getMediaUrls(event);  // Extract media URLs
    
    // ... rest of your code ...
    
    return sendSMS(subscriber.data.phone_number, incomingMessage, mediaUrls);
    

    These changes should make your code send the attachments correctly when forwarding the message.