99 lines
4.5 KiB
Ruby
99 lines
4.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class NotificationService
|
|
extend TopicMailerHelper
|
|
extend MapMailerHelper
|
|
# for strip_tags
|
|
include ActionView::Helpers::SanitizeHelper
|
|
|
|
def self.renderer
|
|
renderer ||= ApplicationController.renderer.new(
|
|
http_host: ENV['MAILER_DEFAULT_URL'],
|
|
https: Rails.env.production? ? true : false
|
|
)
|
|
end
|
|
|
|
def self.get_settings_for_event(entity, event_type, event)
|
|
case event_type
|
|
when TOPIC_ADDED_TO_MAP
|
|
subject = added_to_map_subject(entity, event.map)
|
|
template = 'topic_mailer/added_to_map'
|
|
when TOPIC_CONNECTED_1
|
|
subject = connected_subject(event.topic1)
|
|
template = 'topic_mailer/connected'
|
|
when TOPIC_CONNECTED_2
|
|
subject = connected_subject(event.topic2)
|
|
template = 'topic_mailer/connected'
|
|
end
|
|
|
|
{ template: template, subject: subject }
|
|
end
|
|
|
|
def self.send_for_follows(follows, entity, event_type, event)
|
|
return if follows.empty?
|
|
settings = get_settings_for_event(entity, event_type, event)
|
|
# we'll prbly want to put the body into the actual loop so we can pass the current user in as a local
|
|
body = renderer.render(template: settings[:template], locals: { entity: entity, event: event }, layout: false)
|
|
follows.each do |follow|
|
|
case event_type
|
|
when TOPIC_ADDED_TO_MAP
|
|
next unless TopicPolicy.new(follow.user, entity).show? && MapPolicy.new(follow.user, event.map).show?
|
|
next if follow.user.has_map_open(event.map)
|
|
# note, the caveat to this fork related code is that no future updates will be sent
|
|
# either. only the notifications for the initial fork should be squashed like this
|
|
next if event.map.source_id # if map is a fork, send notification for that instead
|
|
when TOPIC_CONNECTED_1, TOPIC_CONNECTED_2
|
|
next unless SynapsePolicy.new(follow.user, event).show?
|
|
next if follow.user.has_map_with_synapse_open(event)
|
|
end
|
|
# this handles email and in-app notifications, in the future, include push
|
|
follow.user.notify(settings[:subject], body, event, false, event_type, follow.user.emails_allowed, event.user)
|
|
# push could be handled with Actioncable to send transient notifications to the UI
|
|
# the receipt from the notify call could be used to link to the full notification
|
|
end
|
|
end
|
|
|
|
def self.notify_followers(entity, event_type, event, reason_filter = nil, exclude_follows = nil)
|
|
follows = entity.follows.active.where.not(user_id: event.user.id)
|
|
|
|
follows = follows.where.not(id: exclude_follows) unless exclude_follows.nil?
|
|
|
|
if reason_filter.class == String && FollowReason::REASONS.include?(reason_filter)
|
|
follows = follows.joins(:follow_reason).where('follow_reasons.' + reason_filter => true)
|
|
elsif reason_filter.class == Array
|
|
# TODO: throw an error here if all the reasons aren't valid
|
|
follows = follows.joins(:follow_reason).where(reason_filter.map { |r| "follow_reasons.#{r} = 't'" }.join(' OR '))
|
|
end
|
|
send_for_follows(follows, entity, event_type, event)
|
|
follows.map(&:id)
|
|
end
|
|
|
|
def self.access_request(request)
|
|
subject = access_request_subject(request.map)
|
|
body = renderer.render(template: 'map_mailer/access_request', locals: { map: request.map, request: request }, layout: false)
|
|
request.map.user.notify(subject, body, request, false, MAP_ACCESS_REQUEST, true, request.user)
|
|
end
|
|
|
|
def self.access_approved(request)
|
|
subject = access_approved_subject(request.map)
|
|
body = renderer.render(template: 'map_mailer/access_approved', locals: { map: request.map }, layout: false)
|
|
request.user.notify(subject, body, request, false, MAP_ACCESS_APPROVED, true, request.map.user)
|
|
end
|
|
|
|
def self.invite_to_edit(user_map)
|
|
subject = invite_to_edit_subject(user_map.map)
|
|
body = renderer.render(template: 'map_mailer/invite_to_edit', locals: { map: user_map.map, inviter: user_map.map.user }, layout: false)
|
|
user_map.user.notify(subject, body, user_map, false, MAP_INVITE_TO_EDIT, true, user_map.map.user)
|
|
end
|
|
|
|
# note: this is a global function, probably called from the rails console with some html body
|
|
def self.message_from_devs(subject, body, opts = {})
|
|
users = opts[:users] || User.all
|
|
obj = opts[:obj] || nil
|
|
sanitize_text = opts[:sanitize_text] || false
|
|
notification_code = opts[:notification_code] || MESSAGE_FROM_DEVS
|
|
send_mail = opts[:send_mail] ? true : false
|
|
sender = opts[:sender] || User.find_by(email: 'ishanshapiro@gmail.com')
|
|
Mailboxer::Notification.notify_all(users, subject, body, obj, sanitize_text, notification_code, send_mail, sender)
|
|
end
|
|
end
|