diff --git a/app/javascript/dashboard/components-next/message/bubbles/BaseAttachment.vue b/app/javascript/dashboard/components-next/message/bubbles/BaseAttachment.vue index d494de908..8beceee26 100644 --- a/app/javascript/dashboard/components-next/message/bubbles/BaseAttachment.vue +++ b/app/javascript/dashboard/components-next/message/bubbles/BaseAttachment.vue @@ -10,6 +10,7 @@ defineProps({ iconBgColor: { type: String, default: 'bg-n-alpha-3' }, senderTranslationKey: { type: String, required: true }, content: { type: String, required: true }, + title: { type: String, default: '' }, // Title can be any name, description, etc action: { type: Object, required: true, @@ -48,6 +49,9 @@ const senderName = computed(() => { }} +
+ {{ title }} +
{{ content }}
diff --git a/app/javascript/dashboard/components-next/message/bubbles/Contact.vue b/app/javascript/dashboard/components-next/message/bubbles/Contact.vue index 7230a7e05..dda249559 100644 --- a/app/javascript/dashboard/components-next/message/bubbles/Contact.vue +++ b/app/javascript/dashboard/components-next/message/bubbles/Contact.vue @@ -11,7 +11,7 @@ import { ExceptionWithMessage, } from 'shared/helpers/CustomErrors'; -const { content, attachments } = useMessageContext(); +const { attachments } = useMessageContext(); const $store = useStore(); const { t } = useI18n(); @@ -24,6 +24,12 @@ const phoneNumber = computed(() => { return attachment.value.fallbackTitle; }); +const contactName = computed(() => { + const { meta } = attachment.value ?? {}; + const { firstName, lastName } = meta ?? {}; + return `${firstName ?? ''} ${lastName ?? ''}`.trim(); +}); + const formattedPhoneNumber = computed(() => { return phoneNumber.value.replace(/\s|-|[A-Za-z]/g, ''); }); @@ -32,13 +38,9 @@ const rawPhoneNumber = computed(() => { return phoneNumber.value.replace(/\D/g, ''); }); -const name = computed(() => { - return content.value; -}); - function getContactObject() { const contactItem = { - name: name.value, + name: contactName.value, phone_number: `+${rawPhoneNumber.value}`, }; return contactItem; @@ -99,6 +101,7 @@ const action = computed(() => ({ icon="i-teenyicons-user-circle-solid" icon-bg-color="bg-[#D6409F]" sender-translation-key="CONVERSATION.SHARED_ATTACHMENT.CONTACT" + :title="contactName" :content="phoneNumber" :action="formattedPhoneNumber ? action : null" /> diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 65e56a21f..0bfd9a978 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -9,6 +9,7 @@ # external_url :string # fallback_title :string # file_type :integer default("image") +# meta :jsonb # created_at :datetime not null # updated_at :datetime not null # account_id :integer not null @@ -116,7 +117,8 @@ class Attachment < ApplicationRecord def contact_metadata { - fallback_title: fallback_title + fallback_title: fallback_title, + meta: meta || {} } end diff --git a/app/services/telegram/incoming_message_service.rb b/app/services/telegram/incoming_message_service.rb index d39005030..e337a03f6 100644 --- a/app/services/telegram/incoming_message_service.rb +++ b/app/services/telegram/incoming_message_service.rb @@ -143,7 +143,11 @@ class Telegram::IncomingMessageService @message.attachments.new( account_id: @message.account_id, file_type: :contact, - fallback_title: contact_card['phone_number'].to_s + fallback_title: contact_card['phone_number'].to_s, + meta: { + first_name: contact_card['first_name'], + last_name: contact_card['last_name'] + } ) end diff --git a/db/migrate/20250207040150_add_meta_to_attachment.rb b/db/migrate/20250207040150_add_meta_to_attachment.rb new file mode 100644 index 000000000..32188b4d7 --- /dev/null +++ b/db/migrate/20250207040150_add_meta_to_attachment.rb @@ -0,0 +1,5 @@ +class AddMetaToAttachment < ActiveRecord::Migration[7.0] + def change + add_column :attachments, :meta, :jsonb, default: {} + end +end diff --git a/db/schema.rb b/db/schema.rb index 17e5c46da..6bea44c8b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2025_01_16_061033) do +ActiveRecord::Schema[7.0].define(version: 2025_02_07_040150) do # These extensions should be enabled to support this database enable_extension "pg_stat_statements" enable_extension "pg_trgm" @@ -174,6 +174,7 @@ ActiveRecord::Schema[7.0].define(version: 2025_01_16_061033) do t.datetime "updated_at", precision: nil, null: false t.string "fallback_title" t.string "extension" + t.jsonb "meta", default: {} t.index ["account_id"], name: "index_attachments_on_account_id" t.index ["message_id"], name: "index_attachments_on_message_id" end diff --git a/spec/models/attachment_spec.rb b/spec/models/attachment_spec.rb index b1d19bd0e..241125538 100644 --- a/spec/models/attachment_spec.rb +++ b/spec/models/attachment_spec.rb @@ -67,4 +67,65 @@ RSpec.describe Attachment do expect(message.attachments.first.push_event_data[:data_url]).not_to eq message.attachments.first.external_url end end + + describe 'meta data handling' do + let(:message) { create(:message) } + + context 'when attachment is a contact type' do + let(:contact_attachment) do + message.attachments.create!( + account_id: message.account_id, + file_type: :contact, + fallback_title: '+1234567890', + meta: { + first_name: 'John', + last_name: 'Doe' + } + ) + end + + it 'stores and retrieves meta data correctly' do + expect(contact_attachment.meta['first_name']).to eq('John') + expect(contact_attachment.meta['last_name']).to eq('Doe') + end + + it 'includes meta data in push_event_data' do + event_data = contact_attachment.push_event_data + expect(event_data[:meta]).to eq({ + 'first_name' => 'John', + 'last_name' => 'Doe' + }) + end + + it 'returns empty hash for meta if not set' do + attachment = message.attachments.create!( + account_id: message.account_id, + file_type: :contact, + fallback_title: '+1234567890' + ) + expect(attachment.push_event_data[:meta]).to eq({}) + end + end + + context 'when meta is used with other file types' do + let(:image_attachment) do + attachment = message.attachments.new( + account_id: message.account_id, + file_type: :image, + meta: { description: 'Test image' } + ) + attachment.file.attach( + io: Rails.root.join('spec/assets/avatar.png').open, + filename: 'avatar.png', + content_type: 'image/png' + ) + attachment.save! + attachment + end + + it 'preserves meta data with file attachments' do + expect(image_attachment.meta['description']).to eq('Test image') + end + end + end end