FEATURE: add support for One-Click unsubscribe (RFC 8058)

We were missing the "List-Unsubscribe-Post" header in emails we sent to allow Yahoo / GMail and others to automagically show a link to unsubscribe.

Internal ref - t/144713
This commit is contained in:
zogstrip 2024-12-31 15:04:42 +01:00 committed by Régis Hanol
parent 25351bdb8e
commit 4d889f2ef8
3 changed files with 15 additions and 3 deletions

View File

@ -223,10 +223,14 @@ module Email
def header_args def header_args
result = {} result = {}
if @opts[:add_unsubscribe_link] if @opts[:add_unsubscribe_link]
unsubscribe_url = if unsubscribe_url = @template_args[:unsubscribe_url].presence
@template_args[:unsubscribe_url].presence || @template_args[:user_preferences_url] result["List-Unsubscribe"] = "<#{unsubscribe_url}>"
result["List-Unsubscribe"] = "<#{unsubscribe_url}>" result["List-Unsubscribe-Post"] = "List-Unsubscribe=One-Click"
else
result["List-Unsubscribe"] = "<#{@template_args[:user_preferences_url]}>"
end
end end
result["X-Discourse-Post-Id"] = @opts[:post_id].to_s if @opts[:post_id] result["X-Discourse-Post-Id"] = @opts[:post_id].to_s if @opts[:post_id]

View File

@ -335,6 +335,12 @@ RSpec.describe Email::MessageBuilder do
expect(message_with_unsubscribe.header_args["List-Unsubscribe"]).to be_present expect(message_with_unsubscribe.header_args["List-Unsubscribe"]).to be_present
end end
it "has the List-Unsubscribe-Post header" do
expect(message_with_unsubscribe.header_args["List-Unsubscribe-Post"]).to eq(
"List-Unsubscribe=One-Click",
)
end
it "has the unsubscribe url in the body" do it "has the unsubscribe url in the body" do
expect(message_with_unsubscribe.body).to match("/t/1234/unsubscribe") expect(message_with_unsubscribe.body).to match("/t/1234/unsubscribe")
end end

View File

@ -200,6 +200,7 @@ RSpec.describe UserNotifications do
expect(email.html_part.body.to_s).to be_present expect(email.html_part.body.to_s).to be_present
expect(email.text_part.body.to_s).to be_present expect(email.text_part.body.to_s).to be_present
expect(email.header["List-Unsubscribe"].to_s).to match(/\/email\/unsubscribe\/\h{64}/) expect(email.header["List-Unsubscribe"].to_s).to match(/\/email\/unsubscribe\/\h{64}/)
expect(email.header["List-Unsubscribe-Post"].to_s).to eq("List-Unsubscribe=One-Click")
expect(email.header["X-Discourse-Topic-Ids"].to_s).to eq( expect(email.header["X-Discourse-Topic-Ids"].to_s).to eq(
"#{another_popular_topic.id},#{popular_topic.id}", "#{another_popular_topic.id},#{popular_topic.id}",
) )
@ -437,6 +438,7 @@ RSpec.describe UserNotifications do
expect(email.header["List-Unsubscribe"].to_s).to match( expect(email.header["List-Unsubscribe"].to_s).to match(
/http:\/\/test.localhost\/forum\/email\/unsubscribe\/\h{64}/, /http:\/\/test.localhost\/forum\/email\/unsubscribe\/\h{64}/,
) )
expect(email.header["List-Unsubscribe-Post"].to_s).to eq("List-Unsubscribe=One-Click")
topic_url = "http://test.localhost/forum/t/#{popular_topic.slug}/#{popular_topic.id}" topic_url = "http://test.localhost/forum/t/#{popular_topic.slug}/#{popular_topic.id}"
expect(html).to include(topic_url) expect(html).to include(topic_url)