diff --git a/app/controllers/webhooks_controller.rb b/app/controllers/webhooks_controller.rb index 021aea1c014..0e64fd14a40 100644 --- a/app/controllers/webhooks_controller.rb +++ b/app/controllers/webhooks_controller.rb @@ -25,7 +25,12 @@ class WebhooksController < ActionController::Base message_id = Email::MessageIdService.message_id_clean((event["smtp-id"] || "")) to_address = event["email"] error_code = event["status"] + if event["event"] == "bounce" + # Sendgrid does not provide status field for emails that can't be delivered due to the recipient's server not existing + # so we set the error code to 5.1.2 which translates to permanent failure bad destination system address. + error_code = "5.1.2" if !error_code && event["type"] == "blocked" + if error_code[Email::SMTP_STATUS_TRANSIENT_FAILURE] process_bounce(message_id, to_address, SiteSetting.soft_bounce_score, error_code) else diff --git a/spec/requests/webhooks_controller_spec.rb b/spec/requests/webhooks_controller_spec.rb index 48f094a7f97..73e73dff72d 100644 --- a/spec/requests/webhooks_controller_spec.rb +++ b/spec/requests/webhooks_controller_spec.rb @@ -3,8 +3,8 @@ RSpec.describe WebhooksController do before { Discourse.redis.flushdb } - let(:email) { "em@il.com" } - let(:message_id) { "12345@il.com" } + fab!(:email) { "em@il.com" } + fab!(:message_id) { "12345@il.com" } describe "#mailgun" do let(:token) { "705a8ccd2ce932be8e98c221fe701c1b4a0afcb8bbd57726de" } @@ -82,10 +82,10 @@ RSpec.describe WebhooksController do end describe "#sendgrid" do - it "works" do - user = Fabricate(:user, email: email) - email_log = Fabricate(:email_log, user: user, message_id: message_id, to_address: email) + fab!(:user) { Fabricate(:user, email:) } + fab!(:email_log) { Fabricate(:email_log, user:, message_id: message_id, to_address: email) } + it "works" do post "/webhooks/sendgrid.json", params: { "_json" => [ @@ -106,6 +106,26 @@ RSpec.describe WebhooksController do expect(email_log.user.user_stat.bounce_score).to eq(SiteSetting.hard_bounce_score) end + it "sets the bounce error code to 5.1.2 when payload's `event` is `bounce`, `type` is `blocked` and `status` is blank" do + post "/webhooks/sendgrid.json", + params: { + "_json" => [ + { + "email" => email, + "smtp-id" => "<12345@il.com>", + "event" => "bounce", + "type" => "blocked", + }, + ], + } + + expect(response.status).to eq(200) + + email_log.reload + expect(email_log.bounced).to eq(true) + expect(email_log.bounce_error_code).to eq("5.1.2") + end + it "verifies signatures" do SiteSetting.sendgrid_verification_key = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE83T4O/n84iotIvIW4mdBgQ/7dAfSmpqIM8kF9mN1flpVKS3GRqe62gw+2fNNRaINXvVpiglSI8eNEc6wEA3F+g=="