Implement Mailchimp unsubscribe webhook (#5804) [deploy]
This commit is contained in:
parent
0119918237
commit
050a2e2726
4 changed files with 67 additions and 0 deletions
|
|
@ -0,0 +1,30 @@
|
|||
class IncomingWebhooks::MailchimpUnsubscribesController < ApplicationController
|
||||
class InvalidListID < StandardError; end
|
||||
|
||||
LIST_MAPPINGS = {
|
||||
mailchimp_newsletter_id: :email_newsletter,
|
||||
mailchimp_sustaining_members_id: :email_membership_newsletter,
|
||||
mailchimp_tag_moderators_id: :email_tag_mod_newsletter,
|
||||
mailchimp_community_moderators_id: :email_community_mod_newsletter
|
||||
}.freeze
|
||||
|
||||
def create
|
||||
not_authorized unless valid_secret?
|
||||
user = User.find_by!(email: params.dig(:data, :email))
|
||||
user.update(email_type => false)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def valid_secret?
|
||||
params[:secret] == SiteConfig.mailchimp_incoming_webhook_secret
|
||||
end
|
||||
|
||||
def email_type
|
||||
list_id = params.dig(:data, :list_id)
|
||||
key = LIST_MAPPINGS.keys.detect { |k| SiteConfig.public_send(k) == list_id }
|
||||
raise InvalidListID unless key
|
||||
|
||||
LIST_MAPPINGS[key]
|
||||
end
|
||||
end
|
||||
|
|
@ -37,6 +37,10 @@ class SiteConfig < RailsSettings::Base
|
|||
field :mailchimp_tag_moderators_id, type: :string, default: ""
|
||||
field :mailchimp_community_moderators_id, type: :string, default: ""
|
||||
|
||||
# Mailchimp webhook secret. Part of the callback URL in the Mailchimp settings.
|
||||
# <https://mailchimp.com/developer/guides/about-webhooks/#Webhooks_security>
|
||||
field :mailchimp_incoming_webhook_secret, type: :string, default: ""
|
||||
|
||||
# Email digest frequency
|
||||
field :periodic_email_digest_max, type: :integer, default: 0
|
||||
field :periodic_email_digest_min, type: :integer, default: 2
|
||||
|
|
|
|||
|
|
@ -150,6 +150,10 @@ Rails.application.routes.draw do
|
|||
resources :reads, only: [:create]
|
||||
end
|
||||
|
||||
namespace :incoming_webhooks do
|
||||
post "/mailchimp/:secret/unsubscribe", to: "mailchimp_unsubscribes#create", as: :mailchimp_unsubscribe
|
||||
end
|
||||
|
||||
resources :messages, only: [:create]
|
||||
resources :chat_channels, only: %i[index show create update]
|
||||
resources :chat_channel_memberships, only: %i[create update destroy]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe "IncomingWebhooks::MailchimpUnsubscribesController", type: :request do
|
||||
let(:user) { create(:user, email_digest_periodic: true) }
|
||||
|
||||
describe "POST /webhooks/mailchimp/:secret/unsubscribe" do
|
||||
let(:secret) { "secret" }
|
||||
let(:list_id) { "1234" }
|
||||
let(:params) { { data: { email: user.email, list_id: list_id } } }
|
||||
|
||||
before do
|
||||
allow(SiteConfig).to receive(:mailchimp_incoming_webhook_secret).and_return(secret)
|
||||
end
|
||||
|
||||
it "return not authorized if the secret is incorrect" do
|
||||
expect do
|
||||
post "/incoming_webhooks/mailchimp/wrong_secret/unsubscribe", params: params
|
||||
end.to raise_error(Pundit::NotAuthorizedError)
|
||||
end
|
||||
|
||||
it "unsubscribes the user if the secret is correct" do
|
||||
SiteConfig.mailchimp_newsletter_id = list_id
|
||||
|
||||
expect do
|
||||
post "/incoming_webhooks/mailchimp/#{secret}/unsubscribe", params: params
|
||||
end.to change { user.reload.email_newsletter }.from(true).to(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue