Skip to content

Commit 15a8b4b

Browse files
committed
Convert GOV.UK Notify jobs to Sidekiq
This adds Sidekiq-only versions of the `EmailDeliveryJob`, `SMSDeliveryJob` and `NotifyDeliveryJob` jobs, to support the migration to using Sidekiq directly. Using Sidekiq directly doesn't support named parameters in jobs, so we now have to pass a JSON-serializable hash containing the parameters that are passed to the `GovukNotifyPersonalisation` class. I'd like to refactor this further to add safeguards to ensure the right keys are used, but for now I didn't want to change too much here. Jira-Issue: MAV-7288
1 parent 5245f64 commit 15a8b4b

21 files changed

Lines changed: 532 additions & 606 deletions
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# frozen_string_literal: true
2+
3+
class EmailDeliverySidekiqJob < NotifyDeliverySidekiqJob
4+
include GovukNotifyThrottlingConcern
5+
6+
def perform(template_name, params)
7+
EmailDeliveryJob.new.perform(template_name, **fetch_params(params))
8+
end
9+
end
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# frozen_string_literal: true
2+
3+
require "notifications/client"
4+
5+
# This is a temporary copy of `NotifyDeliveryJob` that will be removed when
6+
# all jobs have been converted to Sidekiq.
7+
class NotifyDeliverySidekiqJob < ApplicationJobSidekiq
8+
TEAM_ONLY_API_KEY_MESSAGE =
9+
"Can’t send to this recipient using a team-only API key"
10+
11+
sidekiq_options queue: :notifications
12+
13+
def fetch_params(params)
14+
{
15+
academic_year: params["academic_year"],
16+
consent: (id = params["consent_id"]) && Consent.find(id),
17+
consent_form: (id = params["consent_form_id"]) && ConsentForm.find(id),
18+
disease_types: params["disease_types"],
19+
parent: (id = params["parent_id"]) && Parent.find(id),
20+
patient: (id = params["patient_id"]) && Patient.find(id),
21+
programme_types: params["programme_types"] || [],
22+
sent_by: (id = params["sent_by_user_id"]) && User.find(id),
23+
session: (id = params["session_id"]) && Session.find(id),
24+
team: (id = params["team_id"]) && Team.find(id),
25+
team_location: (id = params["team_location_id"]) && TeamLocation.find(id),
26+
vaccination_record:
27+
(id = params["vaccination_record_id"]) && VaccinationRecord.find(id)
28+
}
29+
end
30+
31+
def self.client
32+
@client ||=
33+
Notifications::Client.new(
34+
Settings.govuk_notify["#{Settings.govuk_notify.mode}_key"]
35+
)
36+
end
37+
38+
def self.deliveries
39+
@deliveries ||= []
40+
end
41+
42+
def self.send_via_notify? = Settings.govuk_notify&.enabled
43+
44+
def self.send_via_test? = Rails.env.test?
45+
46+
class UnknownTemplate < StandardError
47+
end
48+
end
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# frozen_string_literal: true
2+
3+
class SMSDeliverySidekiqJob < NotifyDeliverySidekiqJob
4+
include GovukNotifyThrottlingConcern
5+
6+
def perform(template_name, params)
7+
SMSDeliveryJob.new.perform(template_name, **fetch_params(params))
8+
end
9+
end

app/lib/already_had_notification_sender.rb

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,17 @@ def call
2929
).parents_with_consent
3030

3131
parents_with_consent.each do |parent, consent|
32+
params = {
33+
"parent_id" => parent.id,
34+
"vaccination_record_id" => vaccination_record.id,
35+
"consent_id" => consent.id
36+
}
37+
3238
if parent.phone_receive_updates
33-
SMSDeliveryJob.perform_later(
34-
:vaccination_already_had,
35-
parent:,
36-
vaccination_record:,
37-
consent:
38-
)
39+
SMSDeliverySidekiqJob.perform_async("vaccination_already_had", params)
3940
end
4041

41-
EmailDeliveryJob.perform_later(
42-
:vaccination_already_had,
43-
parent:,
44-
vaccination_record:,
45-
consent:
46-
)
42+
EmailDeliverySidekiqJob.perform_async("vaccination_already_had", params)
4743

4844
consent.update!(
4945
patient_already_vaccinated_notification_sent_at: Time.current

app/lib/notifier/consent.rb

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@ def initialize(consent)
1010
def send_confirmation(session:, triage:, sent_by:)
1111
return unless send_notification?
1212

13-
params = { consent:, session:, sent_by: }
13+
params = {
14+
"consent_id" => consent.id,
15+
"session_id" => session.id,
16+
"sent_by_user_id" => sent_by.id
17+
}
1418

1519
if triage
16-
send_triage_email(triage, params)
20+
send_triage_email(triage, session, params)
1721
elsif consent.requires_triage?
1822
send_consent_email(:triage, params)
1923
elsif consent.response_refused?
@@ -34,38 +38,38 @@ def send_notification?
3438
!consent.via_self_consent?
3539
end
3640

37-
def send_triage_email(triage, params)
38-
template = triage_email_template(triage, params[:session])
39-
EmailDeliveryJob.perform_later(template, **params)
41+
def send_triage_email(triage, session, params)
42+
template_name = triage_email_template(triage, session)
43+
EmailDeliverySidekiqJob.perform_async(template_name, params)
4044
end
4145

4246
def triage_email_template(triage, session)
4347
if triage.safe_to_vaccinate?
4448
if programme.mmr? && patient_on_last_dose?(session)
45-
:triage_vaccination_will_happen_mmr_second_dose
49+
"triage_vaccination_will_happen_mmr_second_dose"
4650
else
47-
:triage_vaccination_will_happen
51+
"triage_vaccination_will_happen"
4852
end
4953
elsif triage.do_not_vaccinate?
50-
:triage_vaccination_wont_happen
54+
"triage_vaccination_wont_happen"
5155
elsif triage.delay_vaccination?
52-
:triage_delay_vaccination
56+
"triage_delay_vaccination"
5357
elsif triage.invite_to_clinic?
54-
resolve_email_template(:triage_vaccination_at_clinic, triage.team)
58+
resolve_email_template("triage_vaccination_at_clinic", triage.team)
5559
elsif triage.keep_in_triage?
56-
:consent_confirmation_triage
60+
"consent_confirmation_triage"
5761
end
5862
end
5963

6064
def send_consent_email(type, params)
61-
template = :"consent_confirmation_#{type}"
62-
EmailDeliveryJob.perform_later(template, **params)
65+
template_name = "consent_confirmation_#{type}"
66+
EmailDeliverySidekiqJob.perform_async(template_name, params)
6367
end
6468

6569
def send_consent_sms(type, consent, params)
6670
if consent.parent.phone_receive_updates
67-
template = :"consent_confirmation_#{type}"
68-
SMSDeliveryJob.perform_later(template, **params)
71+
template_name = "consent_confirmation_#{type}"
72+
SMSDeliverySidekiqJob.perform_async(template_name, params)
6973
end
7074
end
7175

@@ -76,7 +80,7 @@ def send_consent_email_and_sms(type, consent, params)
7680

7781
def resolve_email_template(template_name, team)
7882
ods_code = team.organisation.ods_code.downcase
79-
template_names = [:"#{template_name}_#{ods_code}", template_name]
83+
template_names = ["#{template_name}_#{ods_code}", template_name]
8084
template_names.find { NotifyTemplate.exists?(it, channel: :email) }
8185
end
8286

app/lib/notifier/consent_form.rb

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,24 @@ def send_confirmation
3131

3232
def send_unknown_contact_details_warning(patient:)
3333
patient.parents.each do |parent|
34+
params = {
35+
"consent_form_id" => consent_form.id,
36+
"parent_id" => parent.id,
37+
"patient_id" => patient.id
38+
}
39+
3440
if parent.email.present?
35-
EmailDeliveryJob.perform_later(
36-
:consent_unknown_contact_details_warning,
37-
consent_form:,
38-
parent:,
39-
patient:
41+
EmailDeliverySidekiqJob.perform_async(
42+
"consent_unknown_contact_details_warning",
43+
params
4044
)
4145
end
4246

4347
next unless parent.phone.present? && parent.phone_receive_updates
4448

45-
SMSDeliveryJob.perform_later(
46-
:consent_unknown_contact_details_warning,
47-
consent_form:,
48-
parent:,
49-
patient:
49+
SMSDeliverySidekiqJob.perform_async(
50+
"consent_unknown_contact_details_warning",
51+
params
5052
)
5153
end
5254
end
@@ -56,32 +58,50 @@ def send_unknown_contact_details_warning(patient:)
5658
attr_reader :consent_form
5759

5860
def send_confirmation_given(programme_types: nil, disease_types: nil)
59-
params = { consent_form: }
60-
params[:programme_types] = programme_types if programme_types
61-
params[:disease_types] = disease_types if disease_types
61+
params = { "consent_form_id" => consent_form.id }
62+
params["programme_types"] = programme_types if programme_types
63+
params["disease_types"] = disease_types if disease_types
6264

6365
if consent_form.health_answers_require_triage?
64-
EmailDeliveryJob.perform_later(:consent_confirmation_triage, **params)
66+
EmailDeliverySidekiqJob.perform_async(
67+
"consent_confirmation_triage",
68+
params
69+
)
6570
elsif consent_form.session&.clinic? || consent_form.session&.completed?
66-
EmailDeliveryJob.perform_later(:consent_confirmation_clinic, **params)
71+
EmailDeliverySidekiqJob.perform_async(
72+
"consent_confirmation_clinic",
73+
params
74+
)
6775
else
68-
EmailDeliveryJob.perform_later(:consent_confirmation_given, **params)
76+
EmailDeliverySidekiqJob.perform_async(
77+
"consent_confirmation_given",
78+
params
79+
)
6980

7081
if consent_form.parent_phone_receive_updates
71-
SMSDeliveryJob.perform_later(:consent_confirmation_given, **params)
82+
SMSDeliverySidekiqJob.perform_async(
83+
"consent_confirmation_given",
84+
params
85+
)
7286
end
7387
end
7488
end
7589

7690
def send_confirmation_refused(programme_types: nil, disease_types: nil)
77-
params = { consent_form: }
78-
params[:programme_types] = programme_types if programme_types
79-
params[:disease_types] = disease_types if disease_types
91+
params = { "consent_form_id" => consent_form.id }
92+
params["programme_types"] = programme_types if programme_types
93+
params["disease_types"] = disease_types if disease_types
8094

81-
EmailDeliveryJob.perform_later(:consent_confirmation_refused, **params)
95+
EmailDeliverySidekiqJob.perform_async(
96+
"consent_confirmation_refused",
97+
params
98+
)
8299

83100
if consent_form.parent_phone_receive_updates
84-
SMSDeliveryJob.perform_later(:consent_confirmation_refused, **params)
101+
SMSDeliverySidekiqJob.perform_async(
102+
"consent_confirmation_refused",
103+
params
104+
)
85105
end
86106
end
87107
end

app/lib/notifier/patient.rb

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,18 @@ def send_clinic_invitation(
148148

149149
template_name = find_clinic_template_name(type, team:)
150150

151-
params = { academic_year:, patient:, programme_types:, sent_by:, team: }
151+
base_params = {
152+
"academic_year" => academic_year,
153+
"patient_id" => patient.id,
154+
"programme_types" => programme_types,
155+
"sent_by_user_id" => sent_by.id,
156+
"team_id" => team.id
157+
}
152158

153159
parents.each do |parent|
154-
EmailDeliveryJob.perform_later(template_name, parent:, **params)
155-
SMSDeliveryJob.perform_later(template_name, parent:, **params)
160+
params = base_params.merge("parent_id" => parent.id)
161+
EmailDeliverySidekiqJob.perform_async(template_name, params)
162+
SMSDeliverySidekiqJob.perform_async(template_name, params)
156163
end
157164

158165
clinic_notification
@@ -226,16 +233,22 @@ def send_consent_notification(
226233
disease_types = programmes_to_send_for.flat_map(&:disease_types).presence
227234

228235
parents.each do |parent|
229-
params = { disease_types:, parent:, patient:, programme_types:, sent_by: }
236+
params = {
237+
"disease_types" => disease_types,
238+
"parent_id" => parent.id,
239+
"patient_id" => patient.id,
240+
"programme_types" => programme_types,
241+
"sent_by_user_id" => sent_by&.id
242+
}
230243

231244
if session
232-
params[:session] = session
245+
params["session_id"] = session.id
233246
else
234-
params[:team_location] = team_location
247+
params["team_location_id"] = team_location.id
235248
end
236249

237-
EmailDeliveryJob.perform_later(email_template, **params)
238-
SMSDeliveryJob.perform_later(sms_template, **params)
250+
EmailDeliverySidekiqJob.perform_async(email_template, params)
251+
SMSDeliverySidekiqJob.perform_async(sms_template, params)
239252
end
240253

241254
PatientStatusUpdaterJob.perform_async(patient.id)
@@ -254,9 +267,9 @@ def generate_consent_templates(
254267

255268
base_template =
256269
if is_school && CONSENT_REMINDER_TYPES.include?(type)
257-
:consent_school_reminder
270+
"consent_school_reminder"
258271
else
259-
:"consent_#{is_school ? "school" : "clinic"}_#{type}"
272+
"consent_#{is_school ? "school" : "clinic"}_#{type}"
260273
end
261274

262275
# We can only handle a single programme group or variant in the template.
@@ -300,7 +313,7 @@ def generate_consent_templates(
300313
)
301314
template || base_template
302315
elsif is_school
303-
:consent_school_reminder
316+
"consent_school_reminder"
304317
end
305318

306319
[email_template, sms_template]
@@ -321,7 +334,7 @@ def resolve_consent_template(
321334

322335
combinations
323336
.lazy
324-
.map { |parts| :"#{base_template}_#{parts.join("_")}" }
337+
.map { |parts| "#{base_template}_#{parts.join("_")}" }
325338
.detect { NotifyTemplate.exists?(it, channel:) }
326339
end
327340

@@ -351,10 +364,8 @@ def programmes_to_send_clinic_invitation_for(
351364
end
352365

353366
def find_clinic_template_name(type, team:)
354-
template_names = [
355-
:"clinic_#{type}_#{team.organisation.ods_code.downcase}",
356-
:"clinic_#{type}"
357-
]
367+
ods_code = team.organisation.ods_code.downcase
368+
template_names = ["clinic_#{type}_#{ods_code}", "clinic_#{type}"]
358369

359370
template_names.find { NotifyTemplate.exists?(it, channel: :email) }
360371
end

0 commit comments

Comments
 (0)