diff --git a/app/listeners/action_cable_listener.rb b/app/listeners/action_cable_listener.rb index fc4e16960..065124705 100644 --- a/app/listeners/action_cable_listener.rb +++ b/app/listeners/action_cable_listener.rb @@ -3,23 +3,22 @@ class ActionCableListener < BaseListener def conversation_created(event) conversation, account, timestamp = extract_conversation_and_account(event) - members = conversation.inbox.members.pluck(:pubsub_token) - send_to_members(members, CONVERSATION_CREATED, conversation.push_event_data) + send_to_administrators(account.administrators, CONVERSATION_CREATED, conversation.push_event_data) + send_to_agents(conversation.inbox.members, CONVERSATION_CREATED, conversation.push_event_data) end def conversation_read(event) conversation, account, timestamp = extract_conversation_and_account(event) - members = conversation.inbox.members.pluck(:pubsub_token) - send_to_members(members, CONVERSATION_READ, conversation.push_event_data) + send_to_administrators(account.administrators, CONVERSATION_READ, conversation.push_event_data) + send_to_agents(conversation.inbox.members, CONVERSATION_READ, conversation.push_event_data) end def message_created(event) message, account, timestamp = extract_message_and_account(event) conversation = message.conversation - contact = conversation.contact - members = conversation.inbox.members.pluck(:pubsub_token) - send_to_members(members, MESSAGE_CREATED, message.push_event_data) - send_to_contact(contact, MESSAGE_CREATED, message) + send_to_administrators(account.administrators, MESSAGE_CREATED, message.push_event_data) + send_to_agents(conversation.inbox.members, MESSAGE_CREATED, message.push_event_data) + send_to_contact(conversation.contact, MESSAGE_CREATED, message) end def message_updated(event) @@ -33,28 +32,48 @@ class ActionCableListener < BaseListener def conversation_reopened(event) conversation, account, timestamp = extract_conversation_and_account(event) - members = conversation.inbox.members.pluck(:pubsub_token) - send_to_members(members, CONVERSATION_REOPENED, conversation.push_event_data) + send_to_administrators(account.administrators, CONVERSATION_REOPENED, conversation.push_event_data) + send_to_agents(conversation.inbox.members, CONVERSATION_REOPENED, conversation.push_event_data) end def conversation_lock_toggle(event) conversation, account, timestamp = extract_conversation_and_account(event) - members = conversation.inbox.members.pluck(:pubsub_token) - send_to_members(members, CONVERSATION_LOCK_TOGGLE, conversation.lock_event_data) + send_to_administrators(account.administrators, CONVERSATION_LOCK_TOGGLE, conversation.lock_event_data) + send_to_agents(conversation.inbox.members, CONVERSATION_LOCK_TOGGLE, conversation.lock_event_data) end def assignee_changed(event) conversation, account, timestamp = extract_conversation_and_account(event) - members = conversation.inbox.members.pluck(:pubsub_token) - send_to_members(members, ASSIGNEE_CHANGED, conversation.push_event_data) + send_to_administrators(account.administrators, ASSIGNEE_CHANGED, conversation.push_event_data) + send_to_agents(conversation.inbox.members, ASSIGNEE_CHANGED, conversation.push_event_data) + end + + def contact_created(event) + contact, account, timestamp = extract_contact_and_account(event) + send_to_administrators(account.administrators, CONTACT_CREATED, contact.push_event_data) + send_to_agents(account.agents, CONTACT_CREATED, contact.push_event_data) + end + + def contact_updated(event) + contact, account, timestamp = extract_contact_and_account(event) + send_to_administrators(account.administrators, CONTACT_UPDATED, contact.push_event_data) + send_to_agents(account.agents, CONTACT_UPDATED, contact.push_event_data) end private - def send_to_members(members, event_name, data) - return if members.blank? + def send_to_administrators(admins, event_name, data) + admin_tokens = admins.pluck(:pubsub_token) + return if admin_tokens.blank? - ::ActionCableBroadcastJob.perform_later(members, event_name, data) + ::ActionCableBroadcastJob.perform_later(admin_tokens, event_name, data) + end + + def send_to_agents(agents, event_name, data) + agent_tokens = agents.pluck(:pubsub_token) + return if agent_tokens.blank? + + ::ActionCableBroadcastJob.perform_later(agent_tokens, event_name, data) end def send_to_contact(contact, event_name, message) @@ -64,8 +83,4 @@ class ActionCableListener < BaseListener ::ActionCableBroadcastJob.perform_later([contact.pubsub_token], event_name, message.push_event_data) end - - def push(pubsub_token, data) - # Enqueue sidekiq job to push event to corresponding channel - end end diff --git a/app/listeners/base_listener.rb b/app/listeners/base_listener.rb index 8b1037446..5d800b456 100644 --- a/app/listeners/base_listener.rb +++ b/app/listeners/base_listener.rb @@ -10,4 +10,9 @@ class BaseListener message = event.data[:message] [message, message.account, event.timestamp] end + + def extract_contact_and_account(event) + contact = event.data[:contact] + [contact, contact.account, event.timestamp] + end end diff --git a/app/models/account.rb b/app/models/account.rb index 35cada140..55e86ee65 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -38,9 +38,12 @@ class Account < ApplicationRecord after_create :notify_creation after_destroy :notify_deletion - def channel - # This should be unique for account - 'test_channel' + def agents + users.where(account_users: { role: :agent }) + end + + def administrators + users.where(account_users: { role: :administrator }) end def all_conversation_tags diff --git a/app/models/contact.rb b/app/models/contact.rb index 9687bcda5..087951205 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -25,6 +25,8 @@ class Contact < ApplicationRecord include Pubsubable include Avatarable include AvailabilityStatusable + include Events::Types + validates :account_id, presence: true validates :email, allow_blank: true, uniqueness: { scope: [:account_id], case_sensitive: false } validates :identifier, allow_blank: true, uniqueness: { scope: [:account_id] } @@ -36,6 +38,8 @@ class Contact < ApplicationRecord has_many :messages, dependent: :destroy before_validation :downcase_email + after_create :dispatch_create_event + after_update :dispatch_update_event def get_source_id(inbox_id) contact_inboxes.find_by!(inbox_id: inbox_id).source_id @@ -53,11 +57,22 @@ class Contact < ApplicationRecord def webhook_data { id: id, - name: name + name: name, + avatar: avatar_url } end def downcase_email email.downcase! if email.present? end + + private + + def dispatch_create_event + Rails.configuration.dispatcher.dispatch(CONTACT_CREATED, Time.zone.now, contact: self) + end + + def dispatch_update_event + Rails.configuration.dispatcher.dispatch(CONTACT_UPDATED, Time.zone.now, contact: self) + end end diff --git a/config/initializers/languages.rb b/config/initializers/languages.rb index 9a67467ab..30da5b9a7 100644 --- a/config/initializers/languages.rb +++ b/config/initializers/languages.rb @@ -11,7 +11,7 @@ LANGUAGES_CONFIG = { 6 => { name: 'Italian', iso_639_3_code: 'ita', iso_639_1_code: 'it' }, 7 => { name: 'Japanese', iso_639_3_code: 'jpn', iso_639_1_code: 'ja' }, 8 => { name: 'Korean', iso_639_3_code: 'kor', iso_639_1_code: 'ko' }, - 9 => { name: 'Portugues', iso_639_3_code: 'por', iso_639_1_code: 'pt' }, + 9 => { name: 'Portuguese', iso_639_3_code: 'por', iso_639_1_code: 'pt' }, 10 => { name: 'Russian', iso_639_3_code: 'rus', iso_639_1_code: 'ru' }, 11 => { name: 'Chinese', iso_639_3_code: 'zho', iso_639_1_code: 'zh' }, 12 => { name: 'Spanish', iso_639_3_code: 'spa', iso_639_1_code: 'es' }, diff --git a/lib/events/types.rb b/lib/events/types.rb index 4e34509df..4adb3915f 100644 --- a/lib/events/types.rb +++ b/lib/events/types.rb @@ -13,6 +13,9 @@ module Events::Types CONVERSATION_LOCK_TOGGLE = 'conversation.lock_toggle' ASSIGNEE_CHANGED = 'assignee.changed' + CONTACT_CREATED = 'contact.created' + CONTACT_UPDATED = 'contact.updated' + ACCOUNT_CREATED = 'account.created' ACCOUNT_DESTROYED = 'account.destroyed' diff --git a/spec/listeners/action_cable_listener_spec.rb b/spec/listeners/action_cable_listener_spec.rb new file mode 100644 index 000000000..4b85f3084 --- /dev/null +++ b/spec/listeners/action_cable_listener_spec.rb @@ -0,0 +1,29 @@ +require 'rails_helper' +describe ActionCableListener do + let(:listener) { described_class.instance } + let!(:account) { create(:account) } + let!(:admin) { create(:user, account: account, role: :administrator) } + let!(:inbox) { create(:inbox, account: account) } + let!(:agent) { create(:user, account: account, role: :agent) } + let!(:conversation) { create(:conversation, account: account, inbox: inbox, assignee: agent) } + let!(:message) do + create(:message, message_type: 'outgoing', + account: account, inbox: inbox, conversation: conversation) + end + let!(:event) { Events::Base.new(event_name, Time.zone.now, message: message) } + + before do + create(:inbox_member, inbox: inbox, user: agent) + end + + describe '#message_created' do + let(:event_name) { :'message.created' } + + it 'sends message to account admins, inbox agents and the contact' do + expect(ActionCableBroadcastJob).to receive(:perform_later).with([admin.pubsub_token], 'message.created', message.push_event_data) + expect(ActionCableBroadcastJob).to receive(:perform_later).with([agent.pubsub_token], 'message.created', message.push_event_data) + expect(ActionCableBroadcastJob).to receive(:perform_later).with([conversation.contact.pubsub_token], 'message.created', message.push_event_data) + listener.message_created(event) + end + end +end