Implement Mailchimp unsubscribe webhook (#5804) [deploy]

This commit is contained in:
Michael Kohl 2020-02-12 02:25:48 +07:00 committed by GitHub
parent 0119918237
commit 050a2e2726
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 0 deletions

View file

@ -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

View file

@ -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

View file

@ -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]

View file

@ -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