From 325dc4a741f28d2b0cbc478a97a736bca14a032e Mon Sep 17 00:00:00 2001 From: Pranav Date: Thu, 13 Mar 2025 17:46:48 -0700 Subject: [PATCH] fix: Move contact events to account stream rather than individual user stream (#11082) --- app/channels/room_channel.rb | 17 ++++++++++------- app/listeners/action_cable_listener.rb | 20 ++++++++------------ spec/channels/room_channel_spec.rb | 9 +++++++++ spec/listeners/action_cable_listener_spec.rb | 4 +--- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/app/channels/room_channel.rb b/app/channels/room_channel.rb index 0680f1458..629078229 100644 --- a/app/channels/room_channel.rb +++ b/app/channels/room_channel.rb @@ -2,10 +2,9 @@ class RoomChannel < ApplicationCable::Channel def subscribed # TODO: should we only do ensure stream if current account is present? # for now going ahead with guard clauses in update_subscription and broadcast_presence - - ensure_stream current_user current_account + ensure_stream update_subscription broadcast_presence end @@ -22,12 +21,12 @@ class RoomChannel < ApplicationCable::Channel data = { account_id: @current_account.id, users: ::OnlineStatusTracker.get_available_users(@current_account.id) } data[:contacts] = ::OnlineStatusTracker.get_available_contacts(@current_account.id) if @current_user.is_a? User - ActionCable.server.broadcast(@pubsub_token, { event: 'presence.update', data: data }) + ActionCable.server.broadcast(pubsub_token, { event: 'presence.update', data: data }) end def ensure_stream - @pubsub_token = params[:pubsub_token] - stream_from @pubsub_token + stream_from pubsub_token + stream_from "account_#{@current_account.id}" if @current_account.present? && @current_user.is_a?(User) end def update_subscription @@ -36,11 +35,15 @@ class RoomChannel < ApplicationCable::Channel ::OnlineStatusTracker.update_presence(@current_account.id, @current_user.class.name, @current_user.id) end + def pubsub_token + @pubsub_token ||= params[:pubsub_token] + end + def current_user @current_user ||= if params[:user_id].blank? - ContactInbox.find_by!(pubsub_token: @pubsub_token).contact + ContactInbox.find_by!(pubsub_token: pubsub_token).contact else - User.find_by!(pubsub_token: @pubsub_token, id: params[:user_id]) + User.find_by!(pubsub_token: pubsub_token, id: params[:user_id]) end end diff --git a/app/listeners/action_cable_listener.rb b/app/listeners/action_cable_listener.rb index 99a8fe2af..37dc939e7 100644 --- a/app/listeners/action_cable_listener.rb +++ b/app/listeners/action_cable_listener.rb @@ -137,30 +137,22 @@ class ActionCableListener < BaseListener def contact_created(event) contact, account = extract_contact_and_account(event) - tokens = user_tokens(account, account.agents) - - broadcast(account, tokens, CONTACT_CREATED, contact.push_event_data) + broadcast(account, [account_token(account)], CONTACT_CREATED, contact.push_event_data) end def contact_updated(event) contact, account = extract_contact_and_account(event) - tokens = user_tokens(account, account.agents) - - broadcast(account, tokens, CONTACT_UPDATED, contact.push_event_data) + broadcast(account, [account_token(account)], CONTACT_UPDATED, contact.push_event_data) end def contact_merged(event) contact, account = extract_contact_and_account(event) - tokens = event.data[:tokens] - - broadcast(account, tokens, CONTACT_MERGED, contact.push_event_data) + broadcast(account, [account_token(account)], CONTACT_MERGED, contact.push_event_data) end def contact_deleted(event) contact, account = extract_contact_and_account(event) - tokens = user_tokens(account, account.agents) - - broadcast(account, tokens, CONTACT_DELETED, contact.push_event_data) + broadcast(account, [account_token(account)], CONTACT_DELETED, contact.push_event_data) end def conversation_mentioned(event) @@ -172,6 +164,10 @@ class ActionCableListener < BaseListener private + def account_token(account) + "account_#{account.id}" + end + def typing_event_listener_tokens(account, conversation, user) current_user_token = user.is_a?(Contact) ? conversation.contact_inbox.pubsub_token : user.pubsub_token (user_tokens(account, conversation.inbox.members) + [conversation.contact_inbox.pubsub_token]) - [current_user_token] diff --git a/spec/channels/room_channel_spec.rb b/spec/channels/room_channel_spec.rb index 362a3d405..b39725f04 100644 --- a/spec/channels/room_channel_spec.rb +++ b/spec/channels/room_channel_spec.rb @@ -2,6 +2,8 @@ require 'rails_helper' RSpec.describe RoomChannel do let!(:contact_inbox) { create(:contact_inbox) } + let!(:account) { create(:account) } + let!(:user) { create(:user, account: account) } before do stub_connection @@ -12,4 +14,11 @@ RSpec.describe RoomChannel do expect(subscription).to be_confirmed expect(subscription).to have_stream_for(contact_inbox.pubsub_token) end + + it 'subscribes to a stream when pubsub_token is provided for user' do + subscribe(user_id: user.id, pubsub_token: user.pubsub_token, account_id: account.id) + expect(subscription).to be_confirmed + expect(subscription).to have_stream_for(user.pubsub_token) + expect(subscription).to have_stream_for("account_#{account.id}") + end end diff --git a/spec/listeners/action_cable_listener_spec.rb b/spec/listeners/action_cable_listener_spec.rb index b353f330d..55b74116c 100644 --- a/spec/listeners/action_cable_listener_spec.rb +++ b/spec/listeners/action_cable_listener_spec.rb @@ -121,9 +121,7 @@ describe ActionCableListener do it 'sends message to account admins, inbox agents' do expect(ActionCableBroadcastJob).to receive(:perform_later).with( - a_collection_containing_exactly( - agent.pubsub_token, admin.pubsub_token - ), + ["account_#{account.id}"], 'contact.deleted', contact.push_event_data.merge(account_id: account.id) )