fix(contacts): truncate inbound contact names (IMAP sender display names) (#14631)
## Description Truncates long contact names in `ContactInboxWithContactBuilder` before persisting them, so inbound IMAP sender display names over the `contacts.name` 255-character limit no longer raise `ActiveRecord::RecordInvalid` from `Inboxes::FetchImapEmailsJob`. This keeps email ingestion moving while preserving the existing contact name length constraint. Linear ticket: [https://linear.app/chatwoot/issue/CW-7263/sentry-active-record-invalid-contact-create-from-imap-fetch-job](https://linear.app/chatwoot/issue/CW-7263/sentry-active-record-invalid-contact-create-from-imap-fetch-job) ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - [x] `bundle exec rspec spec/builders/contact_inbox_with_contact_builder_spec.rb` - [x] `bundle exec rspec spec/mailboxes/imap/imap_mailbox_spec.rb` - [x] `bundle exec rubocop app/builders/contact_inbox_with_contact_builder.rb spec/builders/contact_inbox_with_contact_builder_spec.rb` ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes
This commit is contained in:
@@ -50,7 +50,7 @@ class ContactInboxWithContactBuilder
|
||||
|
||||
def create_contact
|
||||
account.contacts.create!(
|
||||
name: contact_attributes[:name] || ::Haikunator.haikunate(1000),
|
||||
name: contact_name,
|
||||
phone_number: contact_attributes[:phone_number],
|
||||
email: contact_attributes[:email],
|
||||
identifier: contact_attributes[:identifier],
|
||||
@@ -59,6 +59,11 @@ class ContactInboxWithContactBuilder
|
||||
)
|
||||
end
|
||||
|
||||
def contact_name
|
||||
name = contact_attributes[:name] || ::Haikunator.haikunate(1000)
|
||||
name.truncate(ApplicationRecord::MAX_STRING_COLUMN_LENGTH, omission: '')
|
||||
end
|
||||
|
||||
def find_contact
|
||||
contact = find_contact_by_identifier(contact_attributes[:identifier])
|
||||
contact ||= find_contact_by_email(contact_attributes[:email])
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
class ApplicationRecord < ActiveRecord::Base
|
||||
MAX_STRING_COLUMN_LENGTH = 255
|
||||
MAX_TEXT_COLUMN_LENGTH = 20_000
|
||||
|
||||
include Events::Types
|
||||
self.abstract_class = true
|
||||
|
||||
@@ -37,7 +40,7 @@ class ApplicationRecord < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def validate_content_length(column)
|
||||
max_length = column.type == :text ? 20_000 : 255
|
||||
max_length = column.type == :text ? MAX_TEXT_COLUMN_LENGTH : MAX_STRING_COLUMN_LENGTH
|
||||
return if self[column.name].nil? || self[column.name].length <= max_length
|
||||
|
||||
errors.add(column.name.to_sym, "is too long (maximum is #{max_length} characters)")
|
||||
|
||||
@@ -39,6 +39,21 @@ describe ContactInboxWithContactBuilder do
|
||||
expect(contact_inbox.inbox_id).to eq(inbox.id)
|
||||
end
|
||||
|
||||
it 'truncates long contact names before creating the contact' do
|
||||
long_name = 'a' * 300
|
||||
|
||||
contact_inbox = described_class.new(
|
||||
source_id: '123456',
|
||||
inbox: inbox,
|
||||
contact_attributes: {
|
||||
name: long_name,
|
||||
email: 'testemail@example.com'
|
||||
}
|
||||
).perform
|
||||
|
||||
expect(contact_inbox.contact.name).to eq(long_name.first(ApplicationRecord::MAX_STRING_COLUMN_LENGTH))
|
||||
end
|
||||
|
||||
it 'doesnot create contact if it already exist with identifier' do
|
||||
contact_inbox = described_class.new(
|
||||
source_id: '123456',
|
||||
|
||||
Reference in New Issue
Block a user