fix: Populate extension and include content_type in attachment webhook payload (#13945)
Attachment webhook event payloads (`message_created`) were missing the
file extension and content type. The `extension` column existed but was
never populated, and `content_type` was not included in the payload at
all.
## What changed
- Added `before_save :set_extension` callback to extract file extension
from the filename when saving an attachment.
- Added `content_type` (from ActiveStorage) to the `file_metadata` used
in `push_event_data`.
### Before
```json
{
"extension": null,
"data_url": "...",
"file_size": 11960
}
```
### After
```json
{
"extension": "pdf",
"content_type": "application/pdf",
"data_url": "...",
"file_size": 11960
}
```
## How to reproduce
1. Send a message with a file attachment (e.g., PDF) via any channel
2. Inspect the `message_created` webhook payload
3. Observe `extension` is `null` and `content_type` is missing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -187,6 +187,44 @@ RSpec.describe Attachment do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'set_extension' do
|
||||
it 'sets extension from filename on save' do
|
||||
attachment = message.attachments.new(account_id: message.account_id, file_type: :file)
|
||||
attachment.file.attach(io: StringIO.new('fake pdf'), filename: 'test.pdf', content_type: 'application/pdf')
|
||||
attachment.save!
|
||||
|
||||
expect(attachment.extension).to eq('pdf')
|
||||
end
|
||||
|
||||
it 'does not overwrite extension if already set' do
|
||||
attachment = message.attachments.new(account_id: message.account_id, file_type: :file, extension: 'doc')
|
||||
attachment.file.attach(io: StringIO.new('fake pdf'), filename: 'test.pdf', content_type: 'application/pdf')
|
||||
attachment.save!
|
||||
|
||||
expect(attachment.extension).to eq('doc')
|
||||
end
|
||||
|
||||
it 'handles filenames without extension' do
|
||||
attachment = message.attachments.new(account_id: message.account_id, file_type: :file)
|
||||
attachment.file.attach(io: StringIO.new('fake data'), filename: 'README', content_type: 'text/plain')
|
||||
attachment.save!
|
||||
|
||||
expect(attachment.extension).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe 'push_event_data includes extension and content_type' do
|
||||
it 'returns extension and content_type for file attachments' do
|
||||
attachment = message.attachments.new(account_id: message.account_id, file_type: :file)
|
||||
attachment.file.attach(io: StringIO.new('fake pdf'), filename: 'test.pdf', content_type: 'application/pdf')
|
||||
attachment.save!
|
||||
|
||||
event_data = attachment.push_event_data
|
||||
expect(event_data[:extension]).to eq('pdf')
|
||||
expect(event_data[:content_type]).to eq('application/pdf')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'file size validation' do
|
||||
let(:attachment) { message.attachments.new(account_id: message.account_id, file_type: :image) }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user