mirror of
https://github.com/discourse/discourse.git
synced 2025-05-26 05:34:56 +08:00
FIX: No method error in WebhooksController#sendgrid
(#31495)
When an email is sent by sendgrid to an email address with an invalid host, the webhook payload does not contain the "status" field: ``` [ { "bounce_classification": "Unclassified", "email": "noemail@this.does.not.exist.tld", "event": "bounce", "reason": "unable to get mx info: failed to get IPs from PTR record: lookup <nil>: unrecognized address", "sg_event_id": "Ym91bmNlLTQtNTA0ODUxOTUtZXVvMmlLeGRTYXlQRjRZRTQtLUk3QS0w", "sg_message_id": "euo2iKxdSayPF4YE4--I7A.recvd-5f54b5d587-pczjm-1-67BADEEA-6.0", "smtp-id": "<870b3a2a-160c-4fc8-bc9a-bd0d5b943b81@forum.umbraco.com>", "timestamp": 1740300320, "tls": 0, "type": "blocked" } ] ``` When the `status` field is missing, it results in a `NoMethodError (undefined method `[]' for nil:NilClass)` error in the controller method. In this commit, we will specifically handle the webhook event from sendgrid when the email address's domain is invalid. Co-Authored-By: @nul800sebastiaan
This commit is contained in:

committed by
GitHub

parent
b02e87b8c4
commit
209d289772
@ -25,7 +25,12 @@ class WebhooksController < ActionController::Base
|
|||||||
message_id = Email::MessageIdService.message_id_clean((event["smtp-id"] || ""))
|
message_id = Email::MessageIdService.message_id_clean((event["smtp-id"] || ""))
|
||||||
to_address = event["email"]
|
to_address = event["email"]
|
||||||
error_code = event["status"]
|
error_code = event["status"]
|
||||||
|
|
||||||
if event["event"] == "bounce"
|
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]
|
if error_code[Email::SMTP_STATUS_TRANSIENT_FAILURE]
|
||||||
process_bounce(message_id, to_address, SiteSetting.soft_bounce_score, error_code)
|
process_bounce(message_id, to_address, SiteSetting.soft_bounce_score, error_code)
|
||||||
else
|
else
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
RSpec.describe WebhooksController do
|
RSpec.describe WebhooksController do
|
||||||
before { Discourse.redis.flushdb }
|
before { Discourse.redis.flushdb }
|
||||||
|
|
||||||
let(:email) { "em@il.com" }
|
fab!(:email) { "em@il.com" }
|
||||||
let(:message_id) { "12345@il.com" }
|
fab!(:message_id) { "12345@il.com" }
|
||||||
|
|
||||||
describe "#mailgun" do
|
describe "#mailgun" do
|
||||||
let(:token) { "705a8ccd2ce932be8e98c221fe701c1b4a0afcb8bbd57726de" }
|
let(:token) { "705a8ccd2ce932be8e98c221fe701c1b4a0afcb8bbd57726de" }
|
||||||
@ -82,10 +82,10 @@ RSpec.describe WebhooksController do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe "#sendgrid" do
|
describe "#sendgrid" do
|
||||||
it "works" do
|
fab!(:user) { Fabricate(:user, email:) }
|
||||||
user = Fabricate(:user, email: email)
|
fab!(:email_log) { Fabricate(:email_log, user:, message_id: message_id, to_address: email) }
|
||||||
email_log = Fabricate(:email_log, user: user, message_id: message_id, to_address: email)
|
|
||||||
|
|
||||||
|
it "works" do
|
||||||
post "/webhooks/sendgrid.json",
|
post "/webhooks/sendgrid.json",
|
||||||
params: {
|
params: {
|
||||||
"_json" => [
|
"_json" => [
|
||||||
@ -106,6 +106,26 @@ RSpec.describe WebhooksController do
|
|||||||
expect(email_log.user.user_stat.bounce_score).to eq(SiteSetting.hard_bounce_score)
|
expect(email_log.user.user_stat.bounce_score).to eq(SiteSetting.hard_bounce_score)
|
||||||
end
|
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
|
it "verifies signatures" do
|
||||||
SiteSetting.sendgrid_verification_key =
|
SiteSetting.sendgrid_verification_key =
|
||||||
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE83T4O/n84iotIvIW4mdBgQ/7dAfSmpqIM8kF9mN1flpVKS3GRqe62gw+2fNNRaINXvVpiglSI8eNEc6wEA3F+g=="
|
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE83T4O/n84iotIvIW4mdBgQ/7dAfSmpqIM8kF9mN1flpVKS3GRqe62gw+2fNNRaINXvVpiglSI8eNEc6wEA3F+g=="
|
||||||
|
Reference in New Issue
Block a user