Skip to content

Commit

Permalink
Implement Mailchimp unsubscribe webhook (#5804) [deploy]
Browse files Browse the repository at this point in the history
  • Loading branch information
citizen428 committed Feb 11, 2020
1 parent 0119918 commit 050a2e2
Show file tree
Hide file tree
Showing 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
4 changes: 4 additions & 0 deletions app/models/site_config.rb
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions config/routes.rb
Expand Up @@ -150,6 +150,10 @@
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]
Expand Down
29 changes: 29 additions & 0 deletions spec/requests/incoming_webhooks/mailchimp/unsubscribe_spec.rb
@@ -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

0 comments on commit 050a2e2

Please sign in to comment.