From de16ad120286284901d196300daff319d9ba6a57 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 31 Oct 2024 21:56:00 +0530 Subject: [PATCH 1/6] feat: add email service --- app/services/ses/email_service.rb | 42 +++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 app/services/ses/email_service.rb diff --git a/app/services/ses/email_service.rb b/app/services/ses/email_service.rb new file mode 100644 index 00000000..6dc9512d --- /dev/null +++ b/app/services/ses/email_service.rb @@ -0,0 +1,42 @@ +class SES::EmailService < BaseAwsService + # { + # to: [emails], + # from: someemail@example.com, + # reply_to: reply@example.com, + # subject: "Some subject", + # html: "HTML content", + # text: "Text content", + # headers: { + # 'List-Unsubscribe': "", + # } + # } + def send(params) + parsed_headers = params[:headers].map do |key, value| + { name: key, value: value } + end + + @ses_client.send_email( + from_email_address: params[:from], + destination: { + to_addresses: params[:to] + }, + reply_to_addresses: params[:reply_to], + content: { + simple: { + subject: { + data: params[:subject] + }, + body: { + text: { + data: params[:text] + }, + html: { + data: params[:html] + } + }, + headers: parsed_headers + } + } + ) + end +end From 252e2aaa1c2636598a5530d5f4a06d3d1d3e5c28 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 31 Oct 2024 21:57:16 +0530 Subject: [PATCH 2/6] refactor: better docs and reorg --- app/services/ses/email_service.rb | 61 +++++++++++++++++-------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/app/services/ses/email_service.rb b/app/services/ses/email_service.rb index 6dc9512d..ff81b83f 100644 --- a/app/services/ses/email_service.rb +++ b/app/services/ses/email_service.rb @@ -1,42 +1,47 @@ class SES::EmailService < BaseAwsService - # { - # to: [emails], - # from: someemail@example.com, - # reply_to: reply@example.com, - # subject: "Some subject", - # html: "HTML content", - # text: "Text content", - # headers: { - # 'List-Unsubscribe': "", - # } - # } + # Send an email using Amazon SES + # + # @param [Hash] params Email parameters + # @option params [Array] :to Recipient email addresses + # @option params [String] :from Sender email address + # @option params [String] :reply_to Reply-to email address + # @option params [String] :subject Email subject line + # @option params [String] :html HTML email content + # @option params [String] :text Plain text email content + # @option params [Hash] :headers Additional email headers + # + # @return [AWS::SES::Types::SendEmailResponse] Response from SES API + # + # @example Basic usage + # email_service.send( + # to: ['user@example.com'], + # from: 'sender@example.com', + # reply_to: 'reply@example.com', + # subject: 'Hello', + # html: '

HTML content

', + # text: 'Text content', + # headers: {'List-Unsubscribe' => ''} + # ) def send(params) - parsed_headers = params[:headers].map do |key, value| - { name: key, value: value } - end + # Convert header hash to SES format + parsed_headers = params.fetch(:headers, {}).map { |key, value| { name: key, value: value } } - @ses_client.send_email( + email_payload = { from_email_address: params[:from], - destination: { - to_addresses: params[:to] - }, + destination: { to_addresses: params[:to] }, reply_to_addresses: params[:reply_to], content: { simple: { - subject: { - data: params[:subject] - }, + subject: { data: params[:subject] }, body: { - text: { - data: params[:text] - }, - html: { - data: params[:html] - } + text: { data: params[:text] }, + html: { data: params[:html] } }, headers: parsed_headers } } - ) + } + + @ses_client.send_email(email_payload) end end From 9cb3ccf9bec3d07344204f0d749e5bfa10923b21 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 31 Oct 2024 22:08:51 +0530 Subject: [PATCH 3/6] feat: add configuration set --- app/services/ses/email_service.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/services/ses/email_service.rb b/app/services/ses/email_service.rb index ff81b83f..0691b3ee 100644 --- a/app/services/ses/email_service.rb +++ b/app/services/ses/email_service.rb @@ -39,9 +39,14 @@ def send(params) }, headers: parsed_headers } - } + }, + configuration_set_name: configuration_set } @ses_client.send_email(email_payload) end + + def configuration_set + @configuration_set ||= AppConfig.get("AWS_SES_CONFIGURATION_SET") + end end From df61350fc26996f8a6a4ffdb9d33b73782d7140a Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 31 Oct 2024 22:26:12 +0530 Subject: [PATCH 4/6] refactor: separate payload generation --- app/services/ses/email_service.rb | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/app/services/ses/email_service.rb b/app/services/ses/email_service.rb index 0691b3ee..41177331 100644 --- a/app/services/ses/email_service.rb +++ b/app/services/ses/email_service.rb @@ -23,13 +23,20 @@ class SES::EmailService < BaseAwsService # headers: {'List-Unsubscribe' => ''} # ) def send(params) - # Convert header hash to SES format + payload = build_email_payload(params) + + @ses_client.send_email(payload) + end + + private + + def build_email_payload(params) parsed_headers = params.fetch(:headers, {}).map { |key, value| { name: key, value: value } } - email_payload = { + { from_email_address: params[:from], destination: { to_addresses: params[:to] }, - reply_to_addresses: params[:reply_to], + reply_to_addresses: [ params[:reply_to] ], content: { simple: { subject: { data: params[:subject] }, @@ -42,8 +49,6 @@ def send(params) }, configuration_set_name: configuration_set } - - @ses_client.send_email(email_payload) end def configuration_set From e2a1f49b503fab7eb23bc38b803325cdf2dd2a75 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 1 Nov 2024 10:21:10 +0530 Subject: [PATCH 5/6] feat: add bulk_send method --- app/services/ses/email_service.rb | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/app/services/ses/email_service.rb b/app/services/ses/email_service.rb index 41177331..298cba4d 100644 --- a/app/services/ses/email_service.rb +++ b/app/services/ses/email_service.rb @@ -28,6 +28,37 @@ def send(params) @ses_client.send_email(payload) end + def bulk_send(params) + bulk_entries = params[:recipients].map do |recipient| + { + destination: { to_addresses: [ recipient[:email] ] }, + replacement_email_content: { + replacement_template: { + replacement_template_data: { + unsubscribe_link: recipient[:unsubscribe_link] + }.to_json + } + }, + replacement_headers: params.fetch(:headers, {}).map { |key, value| { name: key, value: value } } + } + end + + payload = { + from_email_address: params[:from], + reply_to_addresses: [ params[:reply_to] ], + default_content: { + template: { + template_content: { + subject: params[:subject], + text: params[:text], + html: params[:html] + } + } + }, + configuration_set_name: configuration_set + } + end + private def build_email_payload(params) From 70e65b84c161eda785e564fd8714255f16dd418d Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 1 Nov 2024 14:19:44 +0530 Subject: [PATCH 6/6] feat: remove bulk email --- app/services/ses/email_service.rb | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/app/services/ses/email_service.rb b/app/services/ses/email_service.rb index 298cba4d..41177331 100644 --- a/app/services/ses/email_service.rb +++ b/app/services/ses/email_service.rb @@ -28,37 +28,6 @@ def send(params) @ses_client.send_email(payload) end - def bulk_send(params) - bulk_entries = params[:recipients].map do |recipient| - { - destination: { to_addresses: [ recipient[:email] ] }, - replacement_email_content: { - replacement_template: { - replacement_template_data: { - unsubscribe_link: recipient[:unsubscribe_link] - }.to_json - } - }, - replacement_headers: params.fetch(:headers, {}).map { |key, value| { name: key, value: value } } - } - end - - payload = { - from_email_address: params[:from], - reply_to_addresses: [ params[:reply_to] ], - default_content: { - template: { - template_content: { - subject: params[:subject], - text: params[:text], - html: params[:html] - } - } - }, - configuration_set_name: configuration_set - } - end - private def build_email_payload(params)