From 040aab1d7b6867cf6442ac0bb7c868ee38173520 Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Mar 2025 11:03:49 -0400 Subject: [PATCH 01/10] Update default sender and reply-to address in ApplicationMailer to use SendGrid credentials. This change enhances email configuration by specifying a dedicated reply-to address for improved communication. --- app/mailers/application_mailer.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 4c4b94ba..a0ef06f5 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -2,6 +2,7 @@ class ApplicationMailer < ActionMailer::Base prepend_view_path 'app/views/mailers' - default from: Rails.application.credentials.dig(:devise, :mailer_sender) + default from: Rails.application.credentials.dig(:sendgrid, :mailer_sender), + reply_to: 'lsa-evaluate-support@umich.edu' layout 'mailer' end From c70ca6bead30955a0bee9e18132a651313829c47 Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Mar 2025 11:04:26 -0400 Subject: [PATCH 02/10] Enhance ResultsMailer to conditionally set reply-to address based on container's contact email. This change improves email communication by ensuring replies are directed to the appropriate contact when available. --- app/mailers/results_mailer.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/mailers/results_mailer.rb b/app/mailers/results_mailer.rb index 797e0b7d..91680d92 100644 --- a/app/mailers/results_mailer.rb +++ b/app/mailers/results_mailer.rb @@ -36,9 +36,15 @@ def entry_evaluation_notification(entry, round) subject = "Evaluation Results for \"#{@entry.title}\" - #{@contest_description.name}" - mail( + # Set mail options - override reply_to if container has a contact email + mail_options = { to: @user.email, subject: subject - ) + } + + # Override reply_to with container's contact_email if present + mail_options[:reply_to] = @contact_email if @container.contact_email.present? + + mail(mail_options) end end From bf0c3fb27c84d85084cbe6b49dbe26c18cf53a5d Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Mar 2025 11:06:25 -0400 Subject: [PATCH 03/10] Refactor TestMailer to accept a dynamic recipient email and set default sender and reply-to addresses. This change enhances email testing flexibility and improves configuration by allowing custom recipient addresses while maintaining a default for testing purposes. --- app/mailers/test_mailer.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/mailers/test_mailer.rb b/app/mailers/test_mailer.rb index 7c471b73..43d5075b 100644 --- a/app/mailers/test_mailer.rb +++ b/app/mailers/test_mailer.rb @@ -1,7 +1,11 @@ class TestMailer < ApplicationMailer - def test_email + def test_email(recipient_email = nil) + @message = 'This is a test email from LSA Evaluate to verify email configuration.' + @sender = Rails.application.credentials.dig(:sendgrid, :mailer_sender) + @reply_to = 'lsa-wads-rails-email-test@umich.edu' + mail( - to: 'test-t68vvtnfc@srv1.mail-tester.com', + to: recipient_email || 'lsa-wads-rails-email-test@umich.edu', subject: 'Test Email from LSA Evaluate' ) end From 1c6793ec1cb059c90c33437737805cc0779002af Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Mar 2025 11:07:31 -0400 Subject: [PATCH 04/10] Add Rake task for sending test emails to verify configuration This new task allows users to send a test email to a specified recipient or a default sender configured in the application. It includes error handling for missing recipient emails and provides feedback on the email sending process, enhancing the email testing capabilities in the application. --- lib/tasks/email.rake | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 lib/tasks/email.rake diff --git a/lib/tasks/email.rake b/lib/tasks/email.rake new file mode 100644 index 00000000..f68e7f15 --- /dev/null +++ b/lib/tasks/email.rake @@ -0,0 +1,28 @@ +namespace :email do + desc 'Send a test email to verify configuration' + task :test, [ :email ] => :environment do |_t, args| + recipient = args[:email] || Rails.application.credentials.dig(:sendgrid, :mailer_sender) + + if recipient.nil? + puts 'ERROR: No recipient email provided and no default contact email configured.' + puts 'Usage: rake email:test[recipient@example.com]' + exit 1 + end + + puts 'Sending test email to #{recipient}...' + begin + email = TestMailer.test_email(recipient).deliver_now + puts 'Test email sent successfully!' + puts "Message ID: #{email.message_id}" + puts "From: #{email.from.first}" + puts "Reply-To: #{email.reply_to&.first || 'Not set'}" + puts 'Headers:' + email.header.fields.each do |field| + puts " #{field.name}: #{field.value}" unless field.name =~ /content-/i + end + rescue => e + puts "ERROR: Failed to send test email: #{e.message}" + puts e.backtrace.join("\n") + end + end +end From 5461ecdb6473bfafc8cad07eda4a38da4e99bdfa Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Mar 2025 11:09:44 -0400 Subject: [PATCH 05/10] Update Rake task to send test emails asynchronously using deliver_later This change modifies the email sending method in the Rake task to use deliver_later instead of deliver_now, allowing for asynchronous email delivery. This enhancement improves performance and user experience by offloading the email sending process. --- lib/tasks/email.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tasks/email.rake b/lib/tasks/email.rake index f68e7f15..2f10ea9f 100644 --- a/lib/tasks/email.rake +++ b/lib/tasks/email.rake @@ -11,7 +11,7 @@ namespace :email do puts 'Sending test email to #{recipient}...' begin - email = TestMailer.test_email(recipient).deliver_now + email = TestMailer.test_email(recipient).deliver_later puts 'Test email sent successfully!' puts "Message ID: #{email.message_id}" puts "From: #{email.from.first}" From 0e7a687b50c8609486cebf633b74191928f264c5 Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Mar 2025 11:10:31 -0400 Subject: [PATCH 06/10] Enhance test email templates for improved clarity and configuration details This update modifies the HTML and adds a new text template for the test email sent by TestMailer. The changes include a clearer subject line, dynamic message content, and detailed email configuration information, such as sender and reply-to addresses. This enhancement ensures users receive comprehensive feedback on their email settings and improves the overall user experience. --- app/views/test_mailer/test_email.html.erb | 17 ++++++++++++++--- app/views/test_mailer/test_email.text.erb | 13 +++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 app/views/test_mailer/test_email.text.erb diff --git a/app/views/test_mailer/test_email.html.erb b/app/views/test_mailer/test_email.html.erb index ed843f9d..f14272dd 100644 --- a/app/views/test_mailer/test_email.html.erb +++ b/app/views/test_mailer/test_email.html.erb @@ -4,8 +4,19 @@ -

Test Email from LSA Evaluate

-

This is a test email to verify email authentication settings.

-

Sent at: <%= Time.current %>

+

Email Configuration Test

+ +

<%= @message %>

+ +

This message confirms your email settings are working correctly.

+ +

Email Configuration:

+
    +
  • From: <%= @sender %>
  • +
  • Reply-To: <%= @reply_to %>
  • +
+ +

This is a system-generated email. Please do not reply directly to this message.

+

If you need assistance, please contact <%= @reply_to %>.

diff --git a/app/views/test_mailer/test_email.text.erb b/app/views/test_mailer/test_email.text.erb new file mode 100644 index 00000000..2dc18b4b --- /dev/null +++ b/app/views/test_mailer/test_email.text.erb @@ -0,0 +1,13 @@ +Email Configuration Test +====================== + +<%= @message %> + +This message confirms your email settings are working correctly. + +Email Configuration: +- From: <%= @sender %> +- Reply-To: <%= @reply_to %> + +This is a system-generated email. Please do not reply directly to this message. +If you need assistance, please contact <%= @reply_to %>. From 78f9d82a25acbc292c99aba3180a9c750f31f1dc Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Mar 2025 11:12:48 -0400 Subject: [PATCH 07/10] Update Rails credentials with a new encrypted value for enhanced security and configuration management. This change ensures sensitive information is securely stored and managed across environments, following best practices for credential management. --- config/credentials.yml.enc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc index 458606c0..6730a1ce 100644 --- a/config/credentials.yml.enc +++ b/config/credentials.yml.enc @@ -1 +1 @@ -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--wlmyBkvLQbJ3NpxO--KRT/3b9dTgKWH0i4WblbxA== \ No newline at end of file +Ozdt6Gzg1WvHJ/Ski+BIenR42AmRQEQHQKqHh/B2fq/vvfE8OOFb6OuscU9QvkMpfT/M+K2qwLBiNHiC6C6TQc2rTn8nW8Op/5TFXaLEm6iwoOTSHy65ftB69ffSpFacv10e3cyEGq48JKqAAKqnY+nacKMBxkCl8kbtiWxNLd+GOhKSoPaJYl+6FR4FN4POK5ZiPkt9fmrwbriVvr4KDuE/KcFXGGsbyI1ADl0TEUKjz+8PYqgbzE8VGBq1Q6Leg7p2+6Ez9E2E+mjPE21eHdftuZR9iGVArmyJ4ydxz1ziV40g3Hq9YHfxpPOW39OqQORt9XFoqYWvl8/KkFCyne/LvxM18XcJCIWvmAoo04o81ARL1UwMLLMqsMg2L5A8Vs4wNQ31P348fW4IgEKpuQzMV9PKGRMkdEQhlk+7g1c8ihEdzkFqo5LzL33JH3S6qIb9i8caiBaZ+ST/BHzYWxXf/on1VRe9EOj8q+YNwYh34e4DPFHxKSP5qQvxApN1lBd3pUzroOPm5n+DhTHCh9BVFBO7Nc6oW1gEm4hRJ4dkoC00sTyxYJaWXeywzng7bwAh/gfj0kQzHOHdmjpB/aZds2ER5CyTaBoygvMypwOSwbZEvkrxIKyeLkefWey/Dq+Geohb+R74bvta+3k29fO75Nk259uCGZVHJJQc+Zm6/7W0EJgUhRJcrl/f1fEdy914kwXLviaH3uezYCRLyJWPOhyakhuuoNXn/l0V3ZmJpBACfJH/24X3Hh5Wks8fvHyQkVF9PpRLslPRzgSgnV/lLy+go+El66X/XlNwHo2VWNYeHt7GxlaNchBraVEVAZkWOc4h27PXzfjEOXg882n7vDX7VESA8mrGBe/OyHhMGsypq7RULXv+zvRI9kxQNPd6WL7sDzrlG0A2P1qv4axniWCONX6A9iI6u7oDqN1O3klMB4V3NUuHe3SKo8qaWqLMvzj8H4OQbnmql4f0AHM91qsD77x+1W1TxLg0EtMMfbkDP8XrEhvlQjWvzT6ek/KWLrYisBXgLMAdcAetB9CP8UXrAsHHMgj9/fApAGi+ve/9a045MGMX+iXuTorUo6iLhatOc763e4EsmL1nzqL7CPZ/kiZ7hAqHYh7bfGKnd3Q4LMCLM0w/Tb+oz5XVFs18og/feCPdrCZSkGyoB9p/7EvfzQfpEprfIcfx4XbaqU5KXb5NI3lRmGu1d6D/Jl/sy1YWzXItFzizce0fduPhWuiWhFU9XqrI8Nbz/oaMypi1eeWt3by7pcewdu/bw5o0fWEco/wVJ/k/iJNjBiP4ZIZ2bu54KaBrXZ6C9m1hgUpXO7pbJf24I9b7/PAaWnrGD5LAdsM/v9otT5JLAmmWfggq494FYv04wfGQhw4TVqg27wGKOcGYFRsWYnEFB7UF0V1u0GVnYJQQokepC6UYc5Cegft3yrsN9dF+CgfKuQ/tZCneKkr9/Er9knRJSC4TE6sLm3axtpUBZq2+ImfkSB/JyYOxQruGQr1AVKWmXvcHhqVQtQLPJqC7EOjLAgUCWoskfCaH06Y+uNb4eoHB+A7gpvbz2ViiHQl9YJa1xE6PTarZKy0JmJFfO8Wlx3oUuCw+MjDHbTfhvCICmV4yL7/j6JGp0XHacD84N/HFQUoFniTOgCB+zMWK6zJTcyrVZbC4kJ6eK6uV+cIeDx5uX87VpE+yNFB/SbYQWe6oCDcRTDEqdId27b2AM2VVb/HE5mbea1pNc+7iG1irwPUs4sRTmfkE4RXJVIfiS6WIGGE32CpjXhVLsW+zD0CmEPRsC9X8hfxoAz0lPngb+ltm7SsqOzt8cz/QGE0BvIVL8NQHSud6GfugBuBtKIpwz7RncAwYtBQXdiekt2vh7n+4FYRAEXskdVbvlGq+Fd3oODhfvrluZnsy4yEXH16+Hzr5PYkhYiakgzUGt4g8aMUci4TQLAeL5X6qf3dUIt3LOucXla2zBErCmT3Yyo8fN2ag9jPkys5pOrLagcIMGgwuq3DikjaYOR9NPe1LVzmRirI8NU6GPG25a+UU27guBkj8XoZDQc9MQCaE3JtGTeaBG+7/C7P6B43xOlKZe2D3VJVOIQs2ThHv4G3TUFeeMHcxAHzbYNvuvSO8MXPVJKOROSZjooF9UQKJtdQzen1uHV2BhGp2IseCeY07oObqhUbgiq9VhXcpAPNZmpUn9aj/U8wobAWA6VkN/zJsEUCkZFnYTNOWX1r13dJp4fy6DFaNnlbprODpU2kfY+OcIfTT+6rrQcxz/y0QZBWole7OaNmMU8YfSJ1p/B6nogriRftkalM2U7oF2ZtYLxouKj5oq3eXB/I96AaUEpFz0bVnkARAG/RZI3/pqxPTM2OzOnJVLS5b0UIbzHhDJUpHRrLSF5hIq+tifcGlG4mIsO/eqjfx9xt73begtXv0TRRB/k2NWHaMzbVTgeCLLGXmeGREKmXdSPH/28v/SpuZeCrT2M2x3gy7p+bCwkyLjYBaprP8F/zP7sJxQ+5GJTmtHHSq9D3aVIjXDgmGwc8BQDmeBlrJ0cVQ7QM8S52Ddz2QfnOMHtMlvtk9ODcOguawHdnU8NhsFM++biOG6E04dMaYleFBwSbwTCh5UaYI1r2Cnul+YBveyB2S8hKms9fXfKyx0tzUjJ5QWWCjFeinDhaKyLY9oKiQv8l1bnnft9Ln4EOreOFq3neaaNKOH5A76E1OEHsh03rP/aCqk0CP2pxEff2oiv9pkM6iZrFhiZQRkwbPGEKqItOSMPBEZJdCB96rWeaJ0OMx4fO9gfFqSqZnrLz+Js3b2k6oWMto2J4pCiwTutJFslaoZmafeTdH+9T5GBDdP7c6JsWVi8KGhPlwgYHL6LFHm8BOnkAZXO9bWn60Tu1jIBDSMveY6vShZptcQTzg/lCUTgU7Wtz9V6SiE8sTLYOSuyntyn0jHPFAb6H/TtXoeFNeEyI6VRS7NxvsNvwXqZogCHN0izk3gvjPF9qqsXWQramvHo3LjMeSMVvaQh7Nfo4OZd520jFps8lcnq3dhCxXqNTk6TO27YTLsMuv36NO+EnXewAsfYew8o/FYOeT5vWsWRuoIfijGbykAAtrloZ8bgfenVZ0lKEY8RzCWsh9jzi/Uy+7f5imCeRKuHIBMlITxo67fuZoS/KUDXSR2bcclJVdMDfiLEBNk+SzwrnDe2D6+9P5n8Om3mcCS1ChOs2ikjfFELggEgtr2lwUyLykCif38tyfvoQqsqKWcOLymbEfM0FV3M/w6XlEUUSM/DOynLJitUKj35wB90oCjpBuxbW1qXqixmW3e4DF4uszoCWZ5r1WD7m3vWT47k7k5WE0PFMagvO0aLDEYVnhdZiCeL0G+3T0p2z1Z0zgb59OXM5XQnoWa39JNIDjSJgQQLLHXvzeYE5xHKRDpKh81e0vVVQ1l9JMYZuYiDVoQLBScrGv/B1gKxiW0guTKAVmji+Solg3XLzF1s+a/B8DjQLklJqr7eLIhQ19hKfaSgolw0T2XfV8buTsTqGFcz2ky500HxMOVKk3Q5Zh1giCXjtgCTqantm+pSN8DiKCtungU6ZIrkNnI+TgATB8sik0wadAcoKjWMCcJhr7dCeYrWI3fGlzejBmJERFUjMkFGfm5r4XjJ4RPDAabx/x1zeAI0iZow6+g5ayKyF+1oH6CERlEf+xXoAEl1F0dEAASyNOX74ywuFi4QXw7EqIyoDlcIJhHeY16XEQCad5ytraFO261SSsHO7W3VAmo4XMauXLIYGEwBId9xi5usQyZbfogCPs1b0dy7MhNgy/Wl+PqHFTGUIBoG/nQtbiTGF779Ibo00tg7ouimkyLNda4BwYe5NiTobVFnTeOF2I1QKFXlfp/9W2F9l3A9vmRONZfSwkqEa4pqc444QapPejkkouL0tlJxgF0MsqfVno53Ud4sItfId+0eUGzDOS8xqYqGzYi9zvywB039a6TKOWz5ZQEGhVv1ic0VkdUhJq7JuOWgEcAhpF8y5u9efoP1J1IWtfAbe7UPI3fH6aB87e9+kmQdKw/law0Z/+CFcrBvr0a5teYbRR6M32kaXxm7p79ML3TasRnRtU+3E+RgMdrE800Q5UogBR2TkYDRLoUE68eZYZan1fd91h55kbOYKFiluy68QWE8wJ/Y38pyHiaWk5QIcOhMFy8shQLblhMWtxUamP9GuU/x3kFt+thtvmgZ1kidEcw2qeDaTbUBZnVJ7pusqHWMyLKaEZY2IIV4zZ5HscG/jUaGZC1Me08+ccP6i0PpILPTR5MRrpfAluMEK46dKb9OG1V/h40Nddm54KzTXF+k0EOXNqJGnNmOOy6Cbj1AxUKraoFjRDctTfGXUex0eKMye5i6jC5VDit51Vi78OqsIBfXNKs0SsbaQ6AEfO3JEQF6W+OCjPfcnjG829ZWT3GCSjW/E++kvF4DiIKmqhg4j/B/KkUriOTLGoG66Jp71sTmLLhg0eJEMwpGhKjXk70y8x5x9eOsOq9opfXzltBMjMqI88IOejBwxqlMfRqk9qep4kzmSB8MU9/yEN81mr/ANdfWc25Vfc1XlfmekpDXyB/VuVLpeCPwBuiF9CQQANU9sW1pj5c3xhgW4HvaaANRvzn5p8+llIAcf96o+dywNIyhaboJFt61G4zCtPc+s1SANyWvqcVubG2ECd0bnYEOolu+S4ESi+xGK8spJXcSRWzQE7IHn9lFOWOeMq9Ts2myyV7AuqtleURm6bD+hzZGvxmbrmavwbrKzj8uSIR39oUJMMbwwJ5loTH9aMgJbPBaRFa+ZzoazTh7ILd6uA4CsdnQ/D3SyI/AXSv2YXflCqPybcNy9ZIgTHaySaHTk0XUG/PYFHKLX6kducxlQlIe6EX3HSurHx8U7oP07Q1hLJ+HQvikv3X7gxEhRmwH0mnjMMOvaS2TyVeuuu8GTOQfZL6yD4m+u1RtaxKHdVbFyykf0mdrRPZobEGxjYhHgb1nl3SSsMqoDDIYqtxW2vhagKWFuulMqRg95j3SumJUmkl7V1pF1AGEVoqFvB8w+alYm1BNcYIBNwULtRi4V3lNZOWRLGXnFIMp35+PrygzPTrYUlUEmrjA5vCnD0Asz4AYc7VmeTTV5gAXoUhh+zqfGMZKIy04vm1ANKTQpZABLxp+dIjGn/93LuwWZXyZiGIWCus3Qd5e1MZ3Zz7tKzrSQRdJMAk1XIRPeJIPIHG0szyiMqIz+V1ii3uoXAm9izFjuTo9vltg6y2dX4OirHAsZp1RBBxoHZgEfQkBJwC0SibOJlLT8h1cgRbGuuV/74ofhJjhr5ob7Vc34qQt0JO4kIdXVCQ9putRL4mh2nX18rCT4/6uAQ4MfWMqDxl6tPkR42N+PSw5xiKJ3pzmsDeh9QVpSA3fN6E0BYqWDmLP+veNmK7rITAP5ua1sFHAuoXd6ndGKIScazI+u68SaqRGCcY8Irj/IIG4QhwhtAJYBzAn2X46gUM8iDFDbcagp6wV1/yCU5BPI1H+COVyHh5eXte8/pIgwy479AUSYbIGjiV7DuQrrGyUH9myQYxN+OyCoqzhWye7DIrJ5J9omFwWZFN4aIrgswniGN0FoxS2p9XWNY7UfbFgOfh/Lj3JLUOi8SzDcdbDvo0biCByTlPKDNtVue+VhYMM/TlhhY3wBZJ9hABMEHCL3QY+fA94T2EDMT/Lm3cbgMczQQmBBF3ofvgtASP0cwXFQjf4VUMTSSKFZ85xPQ4QAOBfBVOrO8F6ISjDZ58W8XJ0X/st7garQ8/EL/UX9xKQkNNKpR9seSUROxjiY130I0pzHpkMa00eC1DzB6Wknk40mJeWpFZosjYe3URaYsRZGLHAIYGxodyY7I0Gv3Vtkf6aZ18hvWGfmQ9MTfkrdNWFO0Ssqoa0WVhECPNYztdKZZysQcGVxVKFxfyebKvw0OaSfgnhJVRHZa5t+hGjSDFla/07+YiQAUBE3JpuxR/PQI3VH92+HgH3Nxpus5Fup3ccQR5KMZDuJunswX7vi3r3YqYazB5rhHKQtZxyX4RVR09g4e9OP2YZ3SIyV69iwLD6xdaizoOUdiJU0q46ANk6ZQ/sk0VFVVtSLQB7ZCLhidPcpcdD8PKVhY6nJJtGJ6Xi13+NVu1WvwgZDpb3nL5Bgz42eAChBAVNVEX7g+2DzHmMHmTwZN6/qg+wR+p/mvozW6OvpWxfY9YMSbRH8KlCJwLxSdbaxd6VXFs2KNfltCl9nSK16NoJPcf2MU8zE33uMrmMWXZfjIvCeeHC+uFerORyNtjpPXF8dpIlR7nqwZX2WoXC0nqR81xymMskR0pDAJfl2C59g/GScjFAgUwYztsj48dvJJxo37IqSXCfyuZ15fZvbltTkMpVlBTqNM3HtobshhD/mSjNtKRsfQiQMYtzlJQgACOEOK5OTsLoik9IuipeHgB6mRxo6/GEsiUOqEm50PzE8pWM9Og0o68VmRaxSytAsuNJ/GuJQePi3Acxy4fZLj5QnjfH7j00xir6z0okt6WwFVu7jrOOTXgJ3lIUo14sS13KkvD+lYzq2C/L3hOxknoMznwlOWaWBcudyjy15vqwXcHblt756lfVBzC1Y2O2hfNbvsiPMravV4mgCLnPMfD9ckc2fNCpv2uvOYBBpjaBbtq+H/BWgL/RULScti+WygeucvhKnkePSO/L6p/6KxgA63E12Gx+V5rv1Vg1w7ftcgwNPTLwOowQQ+sZH3F+mvNIFH0FNbYhNZ612l0CMqhXyVL4NWJF5RupGUT5zThSTbSzdoD/efIPiiZk0+c8nPMOZM053rK/FJMWQGP2xs3NvhCz2IohdKDRcP00qcDRh62MQmzIDSK9SkX5I7YFAH/trh9YSykkFvLOvyM+K4HJZbxfy0shqGzNKpj9yQ3EArl+9dRFmzXvDJyoqTemvR2Nh593V9hHVFAChZUDlIyo2w7TaLRhaNeucFNVHpWeAxvkzACxQxwr4MTq54YVVRa6Gqi+IiSndNehFKiYA+5U0lQxbiTpZ1GkkHtRAY2Gf4jOB9PtIZZUN8O98wYWvVgw5Na3eTa06/N+7YCxKIRzz4hEWam7xY9bnWGKmg7vLd4KcRSzzHNiZ1xOLJfpk5VhoasQCv06iiL+u1Ufc86WADIlLw9fY6UYudhtTzkWTYC/Nxehef6baaRunLRF5vzJx1bJAUpaqS2twaepikzQ5Rai9NAyibY07X08myo1kbze76SAgCzZYRZ2zirQlcP34NGJxSjRyyMFs/53dB5H/ON7mjy577I/Z94H/sakcD7Ckt/d69FumSkOOUNbP585yz0NsT2IcS2NpFQzIBOvF07LtH+0j4EE/3qCRFKpoA6SyTyMKmOdalVP+PvYYYGcTZTkOoRocYqEMFQtVS9uVXBuyla1h/xCmhtwBEhd3P2OhyxIfGJawJYM6ftUL5m09VH3edZUw0vXm2FDZZwx6clDYySdJ4mf8X+W1udBpTYlI5N1j4zOF7k/RhiUQgT0MwrxKLS1jOkDDiHwERViCJ57i9tF6UXe22Amei3hNTIpIgRaIy73+TXJASmcRpkiLpqs1huYH14Q3vVoEJM2MBymJm1YHwrqPeFJwHOJsVPUpUBJaYukovWEVHtiUlI0ckbMYcHfG+0d/PqbClN17UN/3UfbXopVgbPZLzGihffGhEqCNTZlKORvZQXEog2CJqVdQm6RCZuWYaREHQNBbMlv8qmaGRp71qgdXz9gnKwyyOgG2e+Q9yzYynWTgN0VJECVBZlepQU2DFEvqSW1hO/orXJRfx76KqTkvV03sEEzWaXz8jS+6XsszkPPfXWsozRGjEDJe9nGwBnJ9n5olwzDvajxMmdKtNUkvEc9whZavZ4B8/OSU0gBZmre3E1NTz4hKyFpqpgFU9Mw2Zb5KiuKU0SDKwOAc58jKChFKfjP9MU18C4OcTxqKtHiQdJ1PYL8sEV8l3FHJkkwLanRmrwku9I5ZEiAEf80Pp4xSfeKP0UW9YcSoYpCPYgZPPEb8nPue+y7F/e+FFKBudeuYDxaiNxpmnLTIjXwus9Rpecf/wyR7JcoSBte40M4rRMXb/sJAcRU9z2JOGm8ValPC0Z45G9AcI6bUczk9EBxeZ/sof3SVOkeZDQHgKUAFVTTUgXMhO68b+C/aqOpUZ69Y+pwHVtDD+g4npuLzGjuDJTfDCI1WoBgGk1DHbYCPW74PTtpsA/YnKgsxxicViLmzpyB0Yy5SVvlu2DsKrYnruxtSG/12uwRfpYKBhbfVnVqWNpTdzODoQLnWeaAb0DuWiZH0hlD6j8NlEzgVYwPk4w150HPCxo6sPE8JWpuPGa+mjOuA+9vyVRxZYVO6XRbRMXqYLFVu+Yj/toO26lkgeabNz0EsWhcsG7NOsKDGJn70eQh5dAiWnwXh/f4f0YZUxA38tjqa31G7nZiMdHa5BZ854NmzeNybvkR9K5/SkiR+CPa22TWwbz2pj+dOQfGDSgmeyT3Rr4RgAX3CTwcEI62QpSimMtpPXV9AX2nc7pLiN119/wdTo2ljp1PsQn9ZWiB3bSd98ZG860HstrM8xTf8TVuarobKiHndXf7Uw/MM03jhr972WjhtHQ792aYSKZhwQq2ZeM/+YSWcHyfXnAQ2KrdGkNdDwvWFXo5ISzzMLCFkGiQCIb9xu/xINsFKeIJrU4zWwLaAko7yjBMrx2Y3115rxIgn8ahABjFOKVkX3HkMDBfiHRWkI0K2CF3kLZbW0PxBzqzdNkomSiKoPynrPxlGQ+hm9dSM0StbXJQc86vPKe/TJaYSNjy92hD2kP0cb6zt/pHXFQJZXx7ibknJ8ijuwTUmh4kYJH0ytehVR8syULFklftGK6Tfya/EkV977wta9x5zRsggyK+5sEaQkRvBSO41MyzfvEsV2XL1rTRuOHSoyxmPCHYuEwBnn7rgpgVLq7uweyRpXjLyXuK/mLjzOReUCxYpBFomM5kbjElVXFI8m5O0KZHrw5MeIQLtGzcvkLdyvSisibVk8SITqgKCkobQuMMgRTBl2DsYUAUXNnIMc2ul3KbV4Vd5KRReEarIpRemEw4dWEDNAsYXnTdF+nwcvGb5GQeeNZEdwQVm4vT40rMwS9jAyz2ifCh1KQb2MOn5OSTT7a4gxqjbelCZZ8GcsdwNJmtfdCIw+pTVoiPswg5OnM1IwJPzXUq/po08hzZ1L4WMavNhcOFB/wWnYAVu82/ipfRrLKYlOTCXdjBoKAblGPKXO1icGtcV89YQfDmrGqf7lYW2KklVLSBb4ohWTp7Z27XGnCGL1rMuMTW4phUw7rHE1sU6Ku1fSBDE6FHzpcUhoYWWLEk66LJhrTf8135O+DjECIQ3wkGJ0litSOrQGdKZi39PntfFg0npk3JkVgjiA2bWM2My0chn5oCGYwqiXXsgm/l28zmbc5m73dCZ6lyxCyhFzBxuIUjP/3PzjGhkv//b3J0EhYqPIjT7hEy9iGam5qxVfQB2FjVupe3py6599k3iaL1kYa4poS5/g+cJ1DGsho+XNJxmomiuxRQ2cqR/ZMZAkhfCJf77H9xLWGlNI1aNTXAzyTtbdGz2hvOtWnbVZDmolHi9BDvuV6laQDSgBIaE/ZEBfbH6Was6j/pOcU7RVCECid/vrVbF1ZN5G8JEfYjhNbCwPp1LkxFHRA1QPmPjtZ2CBXYpnVYk2QOt1DdvOxc66ULHblQTEUOuSqdOSlw4yqAlYbiErnb9t9XJXZcdvghPi6KhkmdbPMOW6rfq1EcHt4R95Ha6QTOSKw3R/FnuHTqzRaG9mYdxOq9JFz58UsnKkW8Ww3zbY--O0aD10SfbDNqDsP2--8pomoxzkmiluz48X1YvX1Q== \ No newline at end of file From b13f6555834033bc4e884d2d0efd6e40ad14081a Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Mar 2025 11:27:52 -0400 Subject: [PATCH 08/10] Improve test email feedback in Rake task by providing default values for message ID and sender information. This change enhances user experience by ensuring that users receive clear and informative output, even when certain email fields are not set. --- lib/tasks/email.rake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tasks/email.rake b/lib/tasks/email.rake index 2f10ea9f..7eed2053 100644 --- a/lib/tasks/email.rake +++ b/lib/tasks/email.rake @@ -13,8 +13,8 @@ namespace :email do begin email = TestMailer.test_email(recipient).deliver_later puts 'Test email sent successfully!' - puts "Message ID: #{email.message_id}" - puts "From: #{email.from.first}" + puts "Message ID: #{email.message_id || 'Not set'}" + puts "From: #{email.from.first || 'Not set'}" puts "Reply-To: #{email.reply_to&.first || 'Not set'}" puts 'Headers:' email.header.fields.each do |field| From 1b6f698773a3c79d8245fee960e9c182073ecb0d Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Mar 2025 11:39:53 -0400 Subject: [PATCH 09/10] Enhance Rake task for sending test emails by adding queue option for Sidekiq. This update allows users to choose between direct email delivery and queuing via Sidekiq, improving flexibility in email testing. Additionally, it provides detailed message information before sending, enhancing user feedback and experience. --- lib/tasks/email.rake | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/tasks/email.rake b/lib/tasks/email.rake index 7eed2053..fdc82e9f 100644 --- a/lib/tasks/email.rake +++ b/lib/tasks/email.rake @@ -1,25 +1,46 @@ namespace :email do + # You can choose whether to queue the email through Sidekiq or send it directly: + # For direct delivery: + # bin/rails email:test[your@email.com] + # + # To queue through Sidekiq (add true as a second argument): + # bin/rails email:test[your@email.com,true] + desc 'Send a test email to verify configuration' - task :test, [ :email ] => :environment do |_t, args| + task :test, [ :email, :queue ] => :environment do |_t, args| recipient = args[:email] || Rails.application.credentials.dig(:sendgrid, :mailer_sender) + queue_delivery = args[:queue]&.downcase == 'true' if recipient.nil? puts 'ERROR: No recipient email provided and no default contact email configured.' - puts 'Usage: rake email:test[recipient@example.com]' + puts 'Usage: rake email:test[recipient@example.com] or rake email:test[recipient@example.com,true] to queue via Sidekiq' exit 1 end - puts 'Sending test email to #{recipient}...' + puts "Sending test email to #{recipient}..." begin - email = TestMailer.test_email(recipient).deliver_later - puts 'Test email sent successfully!' - puts "Message ID: #{email.message_id || 'Not set'}" - puts "From: #{email.from.first || 'Not set'}" - puts "Reply-To: #{email.reply_to&.first || 'Not set'}" + # First build the mail object to inspect its properties + mail = TestMailer.test_email(recipient) + + # Print message details before sending + puts 'Message details:' + puts " From: #{mail.from.first || 'Not set'}" + puts " Reply-To: #{mail.reply_to&.first || 'Not set'}" + puts " Subject: #{mail.subject || 'Not set'}" puts 'Headers:' - email.header.fields.each do |field| + mail.header.fields.each do |field| puts " #{field.name}: #{field.value}" unless field.name =~ /content-/i end + + # Now deliver the message based on the queue parameter + if queue_delivery + puts 'Queuing email delivery through Sidekiq...' + mail.deliver_later + puts 'Email successfully queued in Sidekiq!' + else + mail.deliver_now + puts 'Test email sent directly (bypassing Sidekiq)!' + end rescue => e puts "ERROR: Failed to send test email: #{e.message}" puts e.backtrace.join("\n") From 72b32b02d71dcc413c2ca62f78c269218555c7a6 Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Mar 2025 11:46:54 -0400 Subject: [PATCH 10/10] Refactor Rake task for sending test emails to improve message inspection logic. The update separates the handling of queued and direct email delivery, allowing for message details to be printed only when sending directly. This enhances user feedback and maintains clarity in the email sending process. --- lib/tasks/email.rake | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/tasks/email.rake b/lib/tasks/email.rake index fdc82e9f..a0778394 100644 --- a/lib/tasks/email.rake +++ b/lib/tasks/email.rake @@ -19,25 +19,25 @@ namespace :email do puts "Sending test email to #{recipient}..." begin - # First build the mail object to inspect its properties - mail = TestMailer.test_email(recipient) - - # Print message details before sending - puts 'Message details:' - puts " From: #{mail.from.first || 'Not set'}" - puts " Reply-To: #{mail.reply_to&.first || 'Not set'}" - puts " Subject: #{mail.subject || 'Not set'}" - puts 'Headers:' - mail.header.fields.each do |field| - puts " #{field.name}: #{field.value}" unless field.name =~ /content-/i - end - - # Now deliver the message based on the queue parameter if queue_delivery + # For queued delivery, don't inspect the message before sending puts 'Queuing email delivery through Sidekiq...' - mail.deliver_later + TestMailer.test_email(recipient).deliver_later puts 'Email successfully queued in Sidekiq!' else + # For direct delivery, we can inspect the message + mail = TestMailer.test_email(recipient) + + # Print message details before sending + puts 'Message details:' + puts " From: #{mail.from.first || 'Not set'}" + puts " Reply-To: #{mail.reply_to&.first || 'Not set'}" + puts " Subject: #{mail.subject || 'Not set'}" + puts 'Headers:' + mail.header.fields.each do |field| + puts " #{field.name}: #{field.value}" unless field.name =~ /content-/i + end + mail.deliver_now puts 'Test email sent directly (bypassing Sidekiq)!' end