From 09f46aa912de271092e5300a3b7c4b5a068c053f Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Mon, 10 Jul 2023 15:04:31 -0700 Subject: [PATCH] chore: Update onMessage event to include conversation id (#7497) --- .../widget/helpers/IframeEventHelper.js | 20 +++++++++ app/javascript/widget/helpers/actionCable.js | 6 +++ app/listeners/action_cable_listener.rb | 2 +- app/models/message.rb | 20 ++++++--- .../dyte/processor_service_spec.rb | 2 +- spec/models/message_spec.rb | 44 +++++++++++++++++++ 6 files changed, 85 insertions(+), 9 deletions(-) diff --git a/app/javascript/widget/helpers/IframeEventHelper.js b/app/javascript/widget/helpers/IframeEventHelper.js index 40c0e1f1c..fe95cb04a 100644 --- a/app/javascript/widget/helpers/IframeEventHelper.js +++ b/app/javascript/widget/helpers/IframeEventHelper.js @@ -25,3 +25,23 @@ export const getExtraSpaceToScroll = () => { return extraHeight; }; + +export const shouldTriggerMessageUpdateEvent = message => { + const { previous_changes: previousChanges } = message; + + if (!previousChanges) { + return false; + } + const hasNotifiableAttributeChanges = Object.keys(previousChanges).includes( + 'content_attributes' + ); + if (!hasNotifiableAttributeChanges) { + return false; + } + + const hasSubmittedValueChanges = Object.keys( + previousChanges.content_attributes[1] || {} + ).includes('submitted_values'); + + return hasSubmittedValueChanges; +}; diff --git a/app/javascript/widget/helpers/actionCable.js b/app/javascript/widget/helpers/actionCable.js index 6d7af376c..f39fee399 100644 --- a/app/javascript/widget/helpers/actionCable.js +++ b/app/javascript/widget/helpers/actionCable.js @@ -2,6 +2,7 @@ import BaseActionCableConnector from '../../shared/helpers/BaseActionCableConnec import { playNewMessageNotificationInWidget } from 'widget/helpers/WidgetAudioNotificationHelper'; import { ON_AGENT_MESSAGE_RECEIVED } from '../constants/widgetBusEvents'; import { IFrameHelper } from 'widget/helpers/utils'; +import { shouldTriggerMessageUpdateEvent } from './IframeEventHelper'; const isMessageInActiveConversation = (getters, message) => { const { conversation_id: conversationId } = message; @@ -67,6 +68,11 @@ class ActionCableConnector extends BaseActionCableConnector { if (isMessageInActiveConversation(this.app.$store.getters, data)) { return; } + + if (shouldTriggerMessageUpdateEvent(data)) { + IFrameHelper.sendMessage({ event: 'onMessage', data }); + } + this.app.$store.dispatch('conversation/addOrUpdateMessage', data); }; diff --git a/app/listeners/action_cable_listener.rb b/app/listeners/action_cable_listener.rb index e612da583..ba5f2ed31 100644 --- a/app/listeners/action_cable_listener.rb +++ b/app/listeners/action_cable_listener.rb @@ -29,7 +29,7 @@ class ActionCableListener < BaseListener conversation = message.conversation tokens = user_tokens(account, conversation.inbox.members) + contact_tokens(conversation.contact_inbox, message) - broadcast(account, tokens, MESSAGE_UPDATED, message.push_event_data) + broadcast(account, tokens, MESSAGE_UPDATED, message.push_event_data.merge(previous_changes: event.data[:previous_changes])) end def first_reply_created(event) diff --git a/app/models/message.rb b/app/models/message.rb index a16cb7b10..c025746c7 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -135,21 +135,26 @@ class Message < ApplicationRecord end def push_event_data - data = attributes.merge( + data = attributes.symbolize_keys.merge( created_at: created_at.to_i, message_type: message_type_before_type_cast, conversation_id: conversation.display_id, - conversation: { - assignee_id: conversation.assignee_id, - unread_count: conversation.unread_incoming_messages.count, - last_activity_at: conversation.last_activity_at.to_i - } + conversation: conversation_push_event_data ) data.merge!(echo_id: echo_id) if echo_id.present? data.merge!(attachments: attachments.map(&:push_event_data)) if attachments.present? merge_sender_attributes(data) end + def conversation_push_event_data + { + assignee_id: conversation.assignee_id, + unread_count: conversation.unread_incoming_messages.count, + last_activity_at: conversation.last_activity_at.to_i, + contact_inbox: { source_id: conversation.contact_inbox.source_id } + } + end + # TODO: We will be removing this code after instagram_manage_insights is implemented # Better logic is to listen to webhook and remove stories proactively rather than trying # a fetch every time a message is returned @@ -276,7 +281,8 @@ class Message < ApplicationRecord end def dispatch_update_event - Rails.configuration.dispatcher.dispatch(MESSAGE_UPDATED, Time.zone.now, message: self, performed_by: Current.executed_by) + Rails.configuration.dispatcher.dispatch(MESSAGE_UPDATED, Time.zone.now, message: self, performed_by: Current.executed_by, + previous_changes: previous_changes) end def send_reply diff --git a/spec/lib/integrations/dyte/processor_service_spec.rb b/spec/lib/integrations/dyte/processor_service_spec.rb index bdfe615c1..586190b8d 100644 --- a/spec/lib/integrations/dyte/processor_service_spec.rb +++ b/spec/lib/integrations/dyte/processor_service_spec.rb @@ -25,7 +25,7 @@ describe Integrations::Dyte::ProcessorService do it 'creates an integration message in the conversation' do response = processor.create_a_meeting(agent) - expect(response['content']).to eq("#{agent.available_name} has started a meeting") + expect(response[:content]).to eq("#{agent.available_name} has started a meeting") expect(conversation.reload.messages.last.content_type).to eq('integrations') end end diff --git a/spec/models/message_spec.rb b/spec/models/message_spec.rb index ff6964d34..85eb1267a 100644 --- a/spec/models/message_spec.rb +++ b/spec/models/message_spec.rb @@ -50,6 +50,50 @@ RSpec.describe Message do end end + describe '#push_event_data' do + subject(:push_event_data) { message.push_event_data } + + let(:message) { create(:message, echo_id: 'random-echo_id') } + + let(:expected_data) do + { + + account_id: message.account_id, + additional_attributes: message.additional_attributes, + content_attributes: message.content_attributes, + content_type: message.content_type, + content: message.content, + conversation_id: message.conversation.display_id, + created_at: message.created_at.to_i, + external_source_ids: message.external_source_ids, + id: message.id, + inbox_id: message.inbox_id, + message_type: message.message_type_before_type_cast, + private: message.private, + processed_message_content: message.processed_message_content, + sender_id: message.sender_id, + sender_type: message.sender_type, + source_id: message.source_id, + status: message.status, + updated_at: message.updated_at, + conversation: { + assignee_id: message.conversation.assignee_id, + contact_inbox: { + source_id: message.conversation.contact_inbox.source_id + }, + last_activity_at: message.conversation.last_activity_at.to_i, + unread_count: message.conversation.unread_incoming_messages.count + }, + sender: message.sender.push_event_data, + echo_id: 'random-echo_id' + } + end + + it 'returns push event payload' do + expect(push_event_data).to eq(expected_data) + end + end + describe 'Check if message is a valid first reply' do it 'is valid if it is outgoing' do outgoing_message = create(:message, message_type: :outgoing)