diff --git a/lib/integrations/slack/send_on_slack_service.rb b/lib/integrations/slack/send_on_slack_service.rb index c37a152e8..0563ffd73 100644 --- a/lib/integrations/slack/send_on_slack_service.rb +++ b/lib/integrations/slack/send_on_slack_service.rb @@ -121,16 +121,22 @@ class Integrations::Slack::SendOnSlackService < Base::SendOnChannelService end def upload_file - return unless message.attachments.first.with_attached_file? + message.attachments.each do |attachment| + next unless attachment.with_attached_file? - result = slack_client.files_upload_v2( - filename: message.attachments.first.file.filename, - content: message.attachments.first.file.download, - initial_comment: 'Attached File!', - thread_ts: conversation.identifier, - channel_id: hook.reference_id - ) - Rails.logger.info "slack_upload_result: #{result}" + begin + result = slack_client.files_upload_v2( + filename: attachment.file.filename.to_s, + content: attachment.file.download, + initial_comment: 'Attached File!', + thread_ts: conversation.identifier, + channel_id: hook.reference_id + ) + Rails.logger.info "slack_upload_result: #{result}" + rescue Slack::Web::Api::Errors::SlackError => e + Rails.logger.error "Failed to upload file #{attachment.file.filename}: #{e.message}" + end + end end def file_type diff --git a/spec/lib/integrations/slack/send_on_slack_service_spec.rb b/spec/lib/integrations/slack/send_on_slack_service_spec.rb index 848a683b4..ee08a2903 100644 --- a/spec/lib/integrations/slack/send_on_slack_service_spec.rb +++ b/spec/lib/integrations/slack/send_on_slack_service_spec.rb @@ -163,7 +163,7 @@ describe Integrations::Slack::SendOnSlackService do attachment.file.attach(io: Rails.root.join('spec/assets/avatar.png').open, filename: 'avatar.png', content_type: 'image/png') expect(slack_client).to receive(:files_upload_v2).with( - filename: attachment.file.filename, + filename: attachment.file.filename.to_s, content: anything, channel_id: hook.reference_id, thread_ts: conversation.identifier, @@ -178,6 +178,61 @@ describe Integrations::Slack::SendOnSlackService do expect(message.attachments).to be_any end + it 'sent multiple attachments on slack' do + expect(slack_client).to receive(:chat_postMessage).with( + channel: hook.reference_id, + text: message.content, + username: "#{message.sender.name} (Contact)", + thread_ts: conversation.identifier, + icon_url: anything, + unfurl_links: true + ).and_return(slack_message) + + attachment1 = message.attachments.new(account_id: message.account_id, file_type: :image) + attachment1.file.attach(io: Rails.root.join('spec/assets/avatar.png').open, filename: 'avatar.png', content_type: 'image/png') + + attachment2 = message.attachments.new(account_id: message.account_id, file_type: :image) + attachment2.file.attach(io: Rails.root.join('spec/assets/avatar.png').open, filename: 'logo.png', content_type: 'image/png') + + expect(slack_client).to receive(:files_upload_v2).twice.and_return(file_attachment) + + message.save! + builder.perform + + expect(message.external_source_id_slack).to eq 'cw-origin-6789.12345' + expect(message.attachments.count).to eq 2 + end + + it 'handles file upload errors gracefully' do + expect(slack_client).to receive(:chat_postMessage).with( + channel: hook.reference_id, + text: message.content, + username: "#{message.sender.name} (Contact)", + thread_ts: conversation.identifier, + icon_url: anything, + unfurl_links: true + ).and_return(slack_message) + + attachment = message.attachments.new(account_id: message.account_id, file_type: :image) + attachment.file.attach(io: Rails.root.join('spec/assets/avatar.png').open, filename: 'avatar.png', content_type: 'image/png') + + expect(slack_client).to receive(:files_upload_v2).with( + filename: attachment.file.filename.to_s, + content: anything, + channel_id: hook.reference_id, + thread_ts: conversation.identifier, + initial_comment: 'Attached File!' + ).and_raise(Slack::Web::Api::Errors::SlackError.new('File upload failed')) + + expect(Rails.logger).to receive(:error).with('Failed to upload file avatar.png: File upload failed') + + message.save! + + builder.perform + + expect(message.external_source_id_slack).to eq 'cw-origin-6789.12345' + end + it 'will not call file_upload if attachment does not have a file (e.g facebook - fallback type)' do expect(slack_client).to receive(:chat_postMessage).with( channel: hook.reference_id,