fix: Twilio multiple attachment fix (#11452)
This commit is contained in:
committed by
GitHub
parent
bce1f58e86
commit
e9cda40b71
@@ -24,9 +24,10 @@ class Twilio::CallbackController < ApplicationController
|
|||||||
:Body,
|
:Body,
|
||||||
:ToCountry,
|
:ToCountry,
|
||||||
:FromState,
|
:FromState,
|
||||||
:MediaUrl0,
|
*Array.new(10) { |i| :"MediaUrl#{i}" },
|
||||||
:MediaContentType0,
|
*Array.new(10) { |i| :"MediaContentType#{i}" },
|
||||||
:MessagingServiceSid
|
:MessagingServiceSid,
|
||||||
|
:NumMedia
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -106,15 +106,22 @@ class Twilio::IncomingMessageService
|
|||||||
end
|
end
|
||||||
|
|
||||||
def attach_files
|
def attach_files
|
||||||
return if params[:MediaUrl0].blank?
|
num_media = params[:NumMedia].to_i
|
||||||
|
return if num_media.zero?
|
||||||
|
|
||||||
attachment_file = download_attachment_file
|
num_media.times do |i|
|
||||||
|
media_url = params[:"MediaUrl#{i}"]
|
||||||
|
attach_single_file(media_url) if media_url.present?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def attach_single_file(media_url)
|
||||||
|
attachment_file = download_attachment_file(media_url)
|
||||||
return if attachment_file.blank?
|
return if attachment_file.blank?
|
||||||
|
|
||||||
@message.attachments.new(
|
@message.attachments.new(
|
||||||
account_id: @message.account_id,
|
account_id: @message.account_id,
|
||||||
file_type: file_type(params[:MediaContentType0]),
|
file_type: file_type(attachment_file.content_type),
|
||||||
file: {
|
file: {
|
||||||
io: attachment_file,
|
io: attachment_file,
|
||||||
filename: attachment_file.original_filename,
|
filename: attachment_file.original_filename,
|
||||||
@@ -123,24 +130,22 @@ class Twilio::IncomingMessageService
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def download_attachment_file
|
def download_attachment_file(media_url)
|
||||||
download_with_auth
|
download_with_auth(media_url)
|
||||||
rescue Down::Error, Down::ClientError => e
|
rescue Down::Error, Down::ClientError => e
|
||||||
handle_download_attachment_error(e)
|
handle_download_attachment_error(e, media_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
def download_with_auth
|
def download_with_auth(media_url)
|
||||||
Down.download(
|
Down.download(
|
||||||
params[:MediaUrl0],
|
media_url,
|
||||||
# https://support.twilio.com/hc/en-us/articles/223183748-Protect-Media-Access-with-HTTP-Basic-Authentication-for-Programmable-Messaging
|
|
||||||
http_basic_authentication: [twilio_channel.account_sid, twilio_channel.auth_token || twilio_channel.api_key_sid]
|
http_basic_authentication: [twilio_channel.account_sid, twilio_channel.auth_token || twilio_channel.api_key_sid]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# This is just a temporary workaround since some users have not yet enabled media protection. We will remove this in the future.
|
def handle_download_attachment_error(error, media_url)
|
||||||
def handle_download_attachment_error(error)
|
|
||||||
Rails.logger.info "Error downloading attachment from Twilio: #{error.message}: Retrying"
|
Rails.logger.info "Error downloading attachment from Twilio: #{error.message}: Retrying"
|
||||||
Down.download(params[:MediaUrl0])
|
Down.download(media_url)
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
Rails.logger.info "Error downloading attachment from Twilio: #{e.message}: Skipping"
|
Rails.logger.info "Error downloading attachment from Twilio: #{e.message}: Skipping"
|
||||||
nil
|
nil
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ describe Twilio::IncomingMessageService do
|
|||||||
context 'when a message with an attachment is received' do
|
context 'when a message with an attachment is received' do
|
||||||
before do
|
before do
|
||||||
stub_request(:get, 'https://chatwoot-assets.local/sample.png')
|
stub_request(:get, 'https://chatwoot-assets.local/sample.png')
|
||||||
.to_return(status: 200, body: 'image data', headers: {})
|
.to_return(status: 200, body: 'image data', headers: { 'Content-Type' => 'image/png' })
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:params_with_attachment) do
|
let(:params_with_attachment) do
|
||||||
@@ -203,7 +203,7 @@ describe Twilio::IncomingMessageService do
|
|||||||
.to_raise(Down::Error.new('Download error'))
|
.to_raise(Down::Error.new('Download error'))
|
||||||
|
|
||||||
stub_request(:get, 'https://chatwoot-assets.local/sample.png')
|
stub_request(:get, 'https://chatwoot-assets.local/sample.png')
|
||||||
.to_return(status: 200, body: 'image data', headers: {})
|
.to_return(status: 200, body: 'image data', headers: { 'Content-Type' => 'image/png' })
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:params_with_attachment_error) do
|
let(:params_with_attachment_error) do
|
||||||
@@ -229,5 +229,36 @@ describe Twilio::IncomingMessageService do
|
|||||||
expect(conversation.reload.messages.last.attachments.first.file_type).to eq('image')
|
expect(conversation.reload.messages.last.attachments.first.file_type).to eq('image')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when a message with multiple attachments is received' do
|
||||||
|
before do
|
||||||
|
stub_request(:get, 'https://chatwoot-assets.local/sample.png')
|
||||||
|
.to_return(status: 200, body: 'image data 1', headers: { 'Content-Type' => 'image/png' })
|
||||||
|
stub_request(:get, 'https://chatwoot-assets.local/sample.jpg')
|
||||||
|
.to_return(status: 200, body: 'image data 2', headers: { 'Content-Type' => 'image/jpeg' })
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:params_with_multiple_attachments) do
|
||||||
|
{
|
||||||
|
SmsSid: 'SMxx',
|
||||||
|
From: '+12345',
|
||||||
|
AccountSid: 'ACxxx',
|
||||||
|
MessagingServiceSid: twilio_channel.messaging_service_sid,
|
||||||
|
Body: 'testing multiple media',
|
||||||
|
NumMedia: '2',
|
||||||
|
MediaContentType0: 'image/png',
|
||||||
|
MediaUrl0: 'https://chatwoot-assets.local/sample.png',
|
||||||
|
MediaContentType1: 'image/jpeg',
|
||||||
|
MediaUrl1: 'https://chatwoot-assets.local/sample.jpg'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates a new message with multiple media attachments in existing conversation' do
|
||||||
|
described_class.new(params: params_with_multiple_attachments).perform
|
||||||
|
expect(conversation.reload.messages.last.content).to eq('testing multiple media')
|
||||||
|
expect(conversation.reload.messages.last.attachments.count).to eq(2)
|
||||||
|
expect(conversation.reload.messages.last.attachments.map(&:file_type)).to contain_exactly('image', 'image')
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user