chore: Add controllers for conversation participants (#6462)

Co-authored-by: Aswin Dev P.S <aswindevps@gmail.com>
Co-authored-by: Sojan Jose <sojan@chatwoot.com>
This commit is contained in:
Pranav Raj S
2023-02-15 16:33:31 -08:00
committed by GitHub
parent 949ddf68ba
commit 7044eda281
34 changed files with 546 additions and 63 deletions

View File

@@ -4,7 +4,7 @@ module AssignmentHandler
included do
before_save :ensure_assignee_is_from_team
after_commit :notify_assignment_change, :process_assignment_activities
after_commit :notify_assignment_change, :process_assignment_changes
end
private
@@ -36,6 +36,11 @@ module AssignmentHandler
end
end
def process_assignment_changes
process_assignment_activities
process_participant_assignment
end
def process_assignment_activities
user_name = Current.user.name if Current.user.present?
if saved_change_to_team_id?
@@ -44,4 +49,10 @@ module AssignmentHandler
create_assignee_change_activity(user_name)
end
end
def process_participant_assignment
return unless saved_change_to_assignee_id? && assignee_id.present?
conversation_participants.find_or_create_by!(user_id: assignee_id)
end
end

View File

@@ -0,0 +1,53 @@
module UserAttributeHelpers
extend ActiveSupport::Concern
def available_name
self[:display_name].presence || name
end
def availability_status
current_account_user&.availability_status
end
def auto_offline
current_account_user&.auto_offline
end
def inviter
current_account_user&.inviter
end
def active_account_user
account_users.order(active_at: :desc)&.first
end
def current_account_user
# We want to avoid subsequent queries in case where the association is preloaded.
# using where here will trigger n+1 queries.
account_users.find { |ac_usr| ac_usr.account_id == Current.account.id } if Current.account
end
def account
current_account_user&.account
end
def administrator?
current_account_user&.administrator?
end
def agent?
current_account_user&.agent?
end
def role
current_account_user&.role
end
# Used internally for Chatwoot in Chatwoot
def hmac_identifier
hmac_key = GlobalConfig.get('CHATWOOT_INBOX_HMAC_KEY')['CHATWOOT_INBOX_HMAC_KEY']
return OpenSSL::HMAC.hexdigest('sha256', hmac_key, email) if hmac_key.present?
''
end
end

View File

@@ -86,6 +86,7 @@ class Conversation < ApplicationRecord
has_many :mentions, dependent: :destroy_async
has_many :messages, dependent: :destroy_async, autosave: true
has_one :csat_survey_response, dependent: :destroy_async
has_many :conversation_participants, dependent: :destroy_async
has_many :notifications, as: :primary_actor, dependent: :destroy_async
before_save :ensure_snooze_until_reset

View File

@@ -0,0 +1,41 @@
# == Schema Information
#
# Table name: conversation_participants
#
# id :bigint not null, primary key
# created_at :datetime not null
# updated_at :datetime not null
# account_id :bigint not null
# conversation_id :bigint not null
# user_id :bigint not null
#
# Indexes
#
# index_conversation_participants_on_account_id (account_id)
# index_conversation_participants_on_conversation_id (conversation_id)
# index_conversation_participants_on_user_id (user_id)
# index_conversation_participants_on_user_id_and_conversation_id (user_id,conversation_id) UNIQUE
#
class ConversationParticipant < ApplicationRecord
validates :account_id, presence: true
validates :conversation_id, presence: true
validates :user_id, presence: true
validates :user_id, uniqueness: { scope: [:conversation_id] }
validate :ensure_inbox_access
belongs_to :account
belongs_to :conversation
belongs_to :user
before_validation :ensure_account_id
private
def ensure_account_id
self.account_id = conversation&.account_id
end
def ensure_inbox_access
errors.add(:user, 'must have inbox access') if conversation && conversation.inbox.assignable_agents.exclude?(user)
end
end

View File

@@ -34,7 +34,8 @@ class Notification < ApplicationRecord
conversation_creation: 1,
conversation_assignment: 2,
assigned_conversation_new_message: 3,
conversation_mention: 4
conversation_mention: 4,
participating_conversation_new_message: 5
}.freeze
enum notification_type: NOTIFICATION_TYPES
@@ -94,7 +95,7 @@ class Notification < ApplicationRecord
I18n.t('notifications.notification_title.conversation_creation', display_id: primary_actor.display_id, inbox_name: primary_actor.inbox.name)
when 'conversation_assignment'
I18n.t('notifications.notification_title.conversation_assignment', display_id: primary_actor.display_id)
when 'assigned_conversation_new_message'
when 'assigned_conversation_new_message', 'participating_conversation_new_message'
I18n.t(
'notifications.notification_title.assigned_conversation_new_message',
display_id: conversation.display_id,
@@ -109,7 +110,11 @@ class Notification < ApplicationRecord
# rubocop:enable Metrics/CyclomaticComplexity
def conversation
return primary_actor.conversation if %w[assigned_conversation_new_message conversation_mention].include? notification_type
return primary_actor.conversation if %w[
assigned_conversation_new_message
participating_conversation_new_message
conversation_mention
].include? notification_type
primary_actor
end

View File

@@ -48,6 +48,7 @@ class User < ApplicationRecord
include Rails.application.routes.url_helpers
include Reportable
include SsoAuthenticatable
include UserAttributeHelpers
devise :database_authenticatable,
:registerable,
@@ -76,6 +77,8 @@ class User < ApplicationRecord
has_many :assigned_conversations, foreign_key: 'assignee_id', class_name: 'Conversation', dependent: :nullify
alias_attribute :conversations, :assigned_conversations
has_many :csat_survey_responses, foreign_key: 'assigned_agent_id', dependent: :nullify
has_many :conversation_participants, dependent: :destroy_async
has_many :participating_conversations, through: :conversation_participants, source: :conversation
has_many :inbox_members, dependent: :destroy_async
has_many :inboxes, through: :inbox_members, source: :inbox
@@ -110,60 +113,10 @@ class User < ApplicationRecord
self.uid = email
end
def active_account_user
account_users.order(active_at: :desc)&.first
end
def current_account_user
# We want to avoid subsequent queries in case where the association is preloaded.
# using where here will trigger n+1 queries.
account_users.find { |ac_usr| ac_usr.account_id == Current.account.id } if Current.account
end
def available_name
self[:display_name].presence || name
end
# Used internally for Chatwoot in Chatwoot
def hmac_identifier
hmac_key = GlobalConfig.get('CHATWOOT_INBOX_HMAC_KEY')['CHATWOOT_INBOX_HMAC_KEY']
return OpenSSL::HMAC.hexdigest('sha256', hmac_key, email) if hmac_key.present?
''
end
def account
current_account_user&.account
end
def assigned_inboxes
administrator? ? Current.account.inboxes : inboxes.where(account_id: Current.account.id)
end
def administrator?
current_account_user&.administrator?
end
def agent?
current_account_user&.agent?
end
def role
current_account_user&.role
end
def availability_status
current_account_user&.availability_status
end
def auto_offline
current_account_user&.auto_offline
end
def inviter
current_account_user&.inviter
end
def serializable_hash(options = nil)
super(options).merge(confirmed: confirmed?)
end