diff --git a/app/builders/contact_inbox_builder.rb b/app/builders/contact_inbox_builder.rb index 788ae39d1..fe41dcb86 100644 --- a/app/builders/contact_inbox_builder.rb +++ b/app/builders/contact_inbox_builder.rb @@ -65,6 +65,8 @@ class ContactInboxBuilder source_id: @source_id } + update_contact_verification_status + ::ContactInbox.where(attrs).first_or_create!(hmac_verified: hmac_verified || false) rescue ActiveRecord::RecordNotUnique Rails.logger.info("[ContactInboxBuilder] RecordNotUnique #{@source_id} #{@contact.id} #{@inbox.id}") @@ -102,4 +104,18 @@ class ContactInboxBuilder def allowed_channels? @inbox.email? || @inbox.sms? || @inbox.twilio? || @inbox.whatsapp? end + + def update_contact_verification_status + return if @contact.is_verified + return unless should_verify_contact? + + @contact.update!(is_verified: true) + end + + def should_verify_contact? + # Social channels where contacts should be verified by default + @inbox.facebook? || @inbox.instagram? || @inbox.instagram_direct? || + @inbox.twitter? || @inbox.line? || @inbox.whatsapp? || + @inbox.telegram? + end end diff --git a/app/jobs/migration/populate_contact_verification_job.rb b/app/jobs/migration/populate_contact_verification_job.rb new file mode 100644 index 000000000..631ffb81d --- /dev/null +++ b/app/jobs/migration/populate_contact_verification_job.rb @@ -0,0 +1,40 @@ +# Delete migration and spec after 2 consecutive releases. +class Migration::PopulateContactVerificationJob < ApplicationJob + queue_as :scheduled_jobs + + def perform + updated_count = 0 + + Contact.find_each(batch_size: 1000) do |contact| + next if contact.is_verified + next unless should_verify_contact?(contact) + + contact.update_columns(is_verified: true) # rubocop:disable Rails/SkipsModelValidations + updated_count += 1 + end + + Rails.logger.info "[PopulateContactVerificationJob] Updated #{updated_count} contacts to verified" + end + + private + + def should_verify_contact?(contact) + verification_attributes?(contact) || social_channel_inbox?(contact) + end + + def verification_attributes?(contact) + contact.email.present? || + contact.phone_number.present? || + contact.identifier.present? + end + + def social_channel_inbox?(contact) + contact.inboxes.any? { |inbox| social_channel?(inbox) } + end + + def social_channel?(inbox) + inbox.facebook? || inbox.instagram? || inbox.instagram_direct? || + inbox.twitter? || inbox.line? || inbox.whatsapp? || + inbox.telegram? + end +end diff --git a/app/models/contact.rb b/app/models/contact.rb index 4d7b37c44..5e69f26f1 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -243,9 +243,11 @@ class Contact < ApplicationRecord end def update_is_verified + # Once verified, always verified - don't change back to false + return if is_verified + self.is_verified = email.present? || phone_number.present? || - identifier.present? || - (additional_attributes.present? && additional_attributes['company_name'].present?) + identifier.present? end end diff --git a/app/models/inbox.rb b/app/models/inbox.rb index 1c898ba7f..1603e62cd 100644 --- a/app/models/inbox.rb +++ b/app/models/inbox.rb @@ -135,6 +135,14 @@ class Inbox < ApplicationRecord channel_type == 'Channel::Email' end + def line? + channel_type == 'Channel::Line' + end + + def telegram? + channel_type == 'Channel::Telegram' + end + def twilio? channel_type == 'Channel::TwilioSms' end diff --git a/db/migrate/20250722153206_populate_contact_verification_for_social_channels.rb b/db/migrate/20250722153206_populate_contact_verification_for_social_channels.rb new file mode 100644 index 000000000..15ef2cded --- /dev/null +++ b/db/migrate/20250722153206_populate_contact_verification_for_social_channels.rb @@ -0,0 +1,5 @@ +class PopulateContactVerificationForSocialChannels < ActiveRecord::Migration[7.0] + def change + Migration::PopulateContactVerificationJob.perform_later + end +end diff --git a/lib/tasks/populate_contact_verification.rake b/lib/tasks/populate_contact_verification.rake deleted file mode 100644 index ead410c98..000000000 --- a/lib/tasks/populate_contact_verification.rake +++ /dev/null @@ -1,27 +0,0 @@ -namespace :contacts do - desc 'Populate is_verified column for existing contacts based on verification criteria' - task populate_verification: :environment do - total_contacts = Contact.count - puts "Total contacts to process: #{total_contacts}" - - batch_size = 1000 - updated_count = 0 - - Contact.find_each(batch_size: batch_size) do |contact| - # Check if contact should be verified using the same logic as model - should_be_verified = contact.email.present? || - contact.phone_number.present? || - contact.identifier.present? || - (contact.additional_attributes.present? && contact.additional_attributes['company_name'].present?) - - # Update only if current value is different (avoid unnecessary updates) - if contact.is_verified != should_be_verified - # Using update_columns to avoid callbacks and validations for bulk operation - contact.update_columns(is_verified: should_be_verified) # rubocop:disable Rails/SkipsModelValidations - updated_count += 1 - end - # Progress indicator - puts "Updated #{updated_count} contacts..." if (updated_count % 100).zero? - end - end -end