# frozen_string_literal: true class Transaction::SignalNotification include ChecksHumanChanges def initialize(item, params = {}) @item = item @params = params end def perform return if Setting.get('import_mode') return if %w[Ticket Ticket::Article].exclude?(@item[:object]) return if @params[:disable_notification] return if !ticket return if !signal_notifications_enabled? return if !signal_channel collect_signal_recipients.each do |user| SignalNotificationJob.perform_later( ticket_id: ticket.id, article_id: @item[:article_id], user_id: user.id, type: @item[:type], changes: human_changes(@item[:changes], ticket, user) ) end end private def ticket @ticket ||= Ticket.find_by(id: @item[:object_id]) end def article return if !@item[:article_id] @article ||= begin art = Ticket::Article.find_by(id: @item[:article_id]) return unless art sender = Ticket::Article::Sender.lookup(id: art.sender_id) if sender&.name == 'System' return if @item[:changes].blank? && art.preferences[:notification] != true return if art.preferences[:notification] != true end art end end def current_user @current_user ||= User.lookup(id: @item[:user_id]) || User.lookup(id: 1) end def signal_notifications_enabled? Setting.get('signal_notification_enabled') == true end def signal_channel @signal_channel ||= begin channel_id = Setting.get('signal_notification_channel_id') return unless channel_id Channel.find_by(id: channel_id, area: 'Signal::Account', active: true) end end def collect_signal_recipients recipients = [] possible_recipients = possible_recipients_of_group(ticket.group_id) mention_users = Mention.where(mentionable_type: @item[:object], mentionable_id: @item[:object_id]).map(&:user) mention_users.each do |user| next if !user.group_access?(ticket.group_id, 'read') possible_recipients.push(user) end if ticket.owner_id != 1 possible_recipients.push(ticket.owner) end possible_recipients_with_ooo = Set.new(possible_recipients) possible_recipients.each do |user| add_out_of_office_replacement(user, possible_recipients_with_ooo) end possible_recipients_with_ooo.each do |user| next if recipient_is_current_user?(user) next if !user.active? next if !user_has_signal_notifications_enabled?(user) next if user.signal_uid.blank? next if !should_notify_for_event?(user) recipients.push(user) end recipients.uniq(&:id) end def possible_recipients_of_group(group_id) Rails.cache.fetch("User/signal_notification/possible_recipients_of_group/#{group_id}/#{User.latest_change}", expires_in: 20.seconds) do User.group_access(group_id, 'full').sort_by(&:login) end end def add_out_of_office_replacement(user, recipients) replacement = user.out_of_office_agent return unless replacement return unless TicketPolicy.new(replacement, ticket).agent_read_access? recipients.add(replacement) end def recipient_is_current_user?(user) return false if @params[:interface_handle] != 'application_server' return true if article&.updated_by_id == user.id return true if !article && @item[:user_id] == user.id false end def user_has_signal_notifications_enabled?(user) user.preferences.dig('signal_notifications', 'enabled') == true end def should_notify_for_event?(user) event_type = @item[:type] return false if event_type.blank? event_key = case event_type when 'create' then 'create' when 'update', 'update.merged_into', 'update.received_merge', 'update.reaction' then 'update' when 'reminder_reached' then 'reminder_reached' when 'escalation', 'escalation_warning' then 'escalation' else return false end user.preferences.dig('signal_notifications', 'events', event_key) == true end end