fix: preserve original filenames for Telegram inbound attachments (#15071)
## Description Telegram inbound attachments were stored under a generic, renamed filename (e.g. `file_5.pdf`) instead of the name the sender actually uploaded (e.g. `Quarterly-Report-2025.pdf`). **Root cause:** In `Telegram::IncomingMessageService#attach_files`, the attachment filename was taken from the `Down`-downloaded file's `original_filename`, which `Down` derives from the Telegram file-server download URL. That URL is built from Telegram's `getFile` response, whose `file_path` is Telegram's *internal* storage path — not the sender's chosen name. The real name is present in the webhook payload as `file_name` on the `document` / `audio` / `video` object, but it was never read. Because `Attachment#set_extension` derives the stored `extension` from the filename, this also corrupted the recorded extension for documents whose Telegram path lacked a proper one. **Fix:** Prefer the payload's `file_name`, falling back to the downloaded name when it's absent (photos, stickers, voice notes — which Telegram sends without a `file_name`). This mirrors how the Line channel (`message['fileName']`) and WhatsApp Cloud channel already handle inbound attachment filenames. ```ruby filename: file[:file_name].presence || attachment_file.original_filename, ``` Fixes #15070 ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? Added/updated specs in `spec/services/telegram/incoming_message_service_spec.rb`: - Extended the existing document-message example to assert the stored attachment retains the original payload filename (`Screenshot 2021-09-27 at 2.01.14 PM.png`) rather than Telegram's internal download name. - Added a fallback example (a `photo` payload, which carries no `file_name`) asserting the attachment is still created and the filename falls back to the downloaded name — guarding the `.presence || …` branch and confirming no regression for media types without a `file_name`. > Note: my local machine does not have the Ruby/Redis toolchain to run the suite, so I have not run RSpec/RuboCop locally — I'm relying on CI to validate. Suggested command for reviewers: `bundle exec rspec spec/services/telegram/incoming_message_service_spec.rb`. ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [x] I have added tests that prove my fix is effective - [ ] New and existing unit tests pass locally with my changes (unable to run locally — see note above; relying on CI)
This commit is contained in:
@@ -299,7 +299,29 @@ describe Telegram::IncomingMessageService do
|
||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('file')
|
||||
attachment = telegram_channel.inbox.messages.first.attachments.first
|
||||
expect(attachment.file_type).to eq('file')
|
||||
# Retain the original filename from the payload instead of Telegram's internal download name
|
||||
expect(attachment.file.filename.to_s).to eq('Screenshot 2021-09-27 at 2.01.14 PM.png')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when attachment params have no file_name' do
|
||||
it 'falls back to the downloaded file name' do
|
||||
allow(telegram_channel.inbox.channel).to receive(:get_telegram_file_path).and_return('https://chatwoot-assets.local/sample.png')
|
||||
params = {
|
||||
'update_id' => 2_342_342_343_242,
|
||||
'message' => {
|
||||
'photo' => [{
|
||||
'file_id' => 'AgACAgUAAxkBAAODYV3aGZlD6vhzKsE2WNmblsr6zKwAAi-tMRvCoeBWNQ1ENVBzJdwBAAMCAANzAAMhBA',
|
||||
'file_unique_id' => 'AQADL60xG8Kh4FZ4', 'file_size' => 1883, 'width' => 90, 'height' => 67
|
||||
}]
|
||||
}.merge(message_params)
|
||||
}.with_indifferent_access
|
||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||
attachment = telegram_channel.inbox.messages.first.attachments.first
|
||||
expect(attachment.file_type).to eq('image')
|
||||
expect(attachment.file.filename.to_s).to eq('sample.png')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user