]> cat aescling's git repositories - mastodon.git/blob - app/services/notify_service.rb
49022a844e9e1fe867e1ff389b92bbfb0649346b
[mastodon.git] / app / services / notify_service.rb
1 # frozen_string_literal: true
2
3 class NotifyService < BaseService
4 def call(recipient, activity)
5 @recipient = recipient
6 @activity = activity
7 @notification = Notification.new(account: @recipient, activity: @activity)
8
9 return if recipient.user.nil? || blocked?
10
11 create_notification!
12 push_notification! if @notification.browserable?
13 push_to_conversation! if direct_message?
14 send_email! if email_enabled?
15 rescue ActiveRecord::RecordInvalid
16 return
17 end
18
19 private
20
21 def blocked_mention?
22 FeedManager.instance.filter?(:mentions, @notification.mention.status, @recipient.id)
23 end
24
25 def blocked_favourite?
26 false
27 end
28
29 def blocked_follow?
30 false
31 end
32
33 def blocked_reblog?
34 @recipient.muting_reblogs?(@notification.from_account)
35 end
36
37 def blocked_follow_request?
38 false
39 end
40
41 def following_sender?
42 return @following_sender if defined?(@following_sender)
43 @following_sender = @recipient.following?(@notification.from_account) || @recipient.requested?(@notification.from_account)
44 end
45
46 def optional_non_follower?
47 @recipient.user.settings.interactions['must_be_follower'] && !@notification.from_account.following?(@recipient)
48 end
49
50 def optional_non_following?
51 @recipient.user.settings.interactions['must_be_following'] && !following_sender?
52 end
53
54 def direct_message?
55 @notification.type == :mention && @notification.target_status.direct_visibility?
56 end
57
58 def response_to_recipient?
59 @notification.target_status.in_reply_to_account_id == @recipient.id && @notification.target_status.thread&.direct_visibility?
60 end
61
62 def from_staff?
63 @notification.from_account.local? && @notification.from_account.user.present? && @notification.from_account.user.staff?
64 end
65
66 def optional_non_following_and_direct?
67 direct_message? &&
68 @recipient.user.settings.interactions['must_be_following_dm'] &&
69 !from_staff? &&
70 !following_sender? &&
71 !response_to_recipient?
72 end
73
74 def hellbanned?
75 @notification.from_account.silenced? && !following_sender?
76 end
77
78 def from_self?
79 @recipient.id == @notification.from_account.id
80 end
81
82 def domain_blocking?
83 @recipient.domain_blocking?(@notification.from_account.domain) && !following_sender?
84 end
85
86 def blocked?
87 blocked = @recipient.suspended? # Skip if the recipient account is suspended anyway
88 blocked ||= from_self? # Skip for interactions with self
89 blocked ||= domain_blocking? # Skip for domain blocked accounts
90 blocked ||= @recipient.blocking?(@notification.from_account) # Skip for blocked accounts
91 blocked ||= @recipient.muting_notifications?(@notification.from_account)
92 blocked ||= hellbanned? # Hellban
93 blocked ||= optional_non_follower? # Options
94 blocked ||= optional_non_following? # Options
95 blocked ||= optional_non_following_and_direct? # Options
96 blocked ||= conversation_muted?
97 blocked ||= send("blocked_#{@notification.type}?") # Type-dependent filters
98 blocked
99 end
100
101 def conversation_muted?
102 if @notification.target_status
103 @recipient.muting_conversation?(@notification.target_status.conversation)
104 else
105 false
106 end
107 end
108
109 def create_notification!
110 @notification.save!
111 end
112
113 def push_notification!
114 return if @notification.activity.nil?
115
116 Redis.current.publish("timeline:#{@recipient.id}", Oj.dump(event: :notification, payload: InlineRenderer.render(@notification, @recipient, :notification)))
117 send_push_notifications!
118 end
119
120 def push_to_conversation!
121 return if @notification.activity.nil?
122 AccountConversation.add_status(@recipient, @notification.target_status)
123 end
124
125 def send_push_notifications!
126 subscriptions_ids = ::Web::PushSubscription.where(user_id: @recipient.user.id)
127 .select { |subscription| subscription.pushable?(@notification) }
128 .map(&:id)
129
130 ::Web::PushNotificationWorker.push_bulk(subscriptions_ids) do |subscription_id|
131 [subscription_id, @notification.id]
132 end
133 end
134
135 def send_email!
136 return if @notification.activity.nil?
137 NotificationMailer.public_send(@notification.type, @recipient, @notification).deliver_later(wait: 2.minutes)
138 end
139
140 def email_enabled?
141 @recipient.user.settings.notification_emails[@notification.type.to_s]
142 end
143 end
This page took 0.136263 seconds and 4 git commands to generate.