From a7cb0b71329825db52ccf07f6be6e27779bbf931 Mon Sep 17 00:00:00 2001 From: Ravikant Tiwari Date: Tue, 4 Nov 2025 13:12:56 +0000 Subject: [PATCH] fix: Enable Twilio MMS inbound by following redirects (#36491) Changes fetch redirect mode from 'error' to 'follow' to handle Twilio's 302 redirects when downloading MMS media attachments. Also appends media URLs to message body for better visibility. - Modified getUploadFile() to follow redirects and added error logging - Enhanced Twilio parse() to append media URLs to message text - Maintains SSRF protection and backward compatibility Resolves: #36491 --- apps/meteor/app/livechat/imports/server/rest/sms.ts | 4 +++- .../omnichannel-integrations/providers/twilio.ts | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/meteor/app/livechat/imports/server/rest/sms.ts b/apps/meteor/app/livechat/imports/server/rest/sms.ts index b271194c1f05c..c606a17c3a9e1 100644 --- a/apps/meteor/app/livechat/imports/server/rest/sms.ts +++ b/apps/meteor/app/livechat/imports/server/rest/sms.ts @@ -33,13 +33,15 @@ const getUploadFile = async (details: Omit, fileUrl: string) => throw new Meteor.Error('error-invalid-url', 'Invalid URL'); } - const response = await fetch(fileUrl, { redirect: 'error' }); + // Follow redirects to support Twilio media URLs that redirect to actual media location + const response = await fetch(fileUrl, { redirect: 'follow' }); const content = Buffer.from(await response.arrayBuffer()); const contentSize = content.length; if (response.status !== 200 || contentSize === 0) { + logger.warn(`Failed to fetch file from ${fileUrl}: status ${response.status}, size ${contentSize}`); throw new Meteor.Error('error-invalid-file-uploaded', 'Invalid file uploaded'); } diff --git a/apps/meteor/server/services/omnichannel-integrations/providers/twilio.ts b/apps/meteor/server/services/omnichannel-integrations/providers/twilio.ts index 26b6dbaea1cf9..bca2ffd69914e 100644 --- a/apps/meteor/server/services/omnichannel-integrations/providers/twilio.ts +++ b/apps/meteor/server/services/omnichannel-integrations/providers/twilio.ts @@ -99,6 +99,16 @@ export class Twilio implements ISMSProvider { returnData.media.push(media); } + // Append media URLs to the message body for better visibility + if (returnData.media.length > 0) { + const links = returnData.media + .map((media) => media.url) + .filter((url) => !!url) // skip empty URLs + .join('\n'); + + returnData.body = [returnData.body, links].filter(Boolean).join('\n'); + } + return returnData; }