Manage tag and community mod lists in Mailchimp (#2362)
* add moderation email list columns * automate tag moderator mailing list * reorder logic for tag mod list * add community mod list * remove trusted privileges when reverting a user to a regular member * automatically make tag mods community mods * fix merge conflicts * add community view * make methods less complex based on code climate sugggestion * add specs * refactor tag moderator module * fix spec
This commit is contained in:
parent
1c285ba2c5
commit
f637d9e02b
12 changed files with 244 additions and 28 deletions
2
Envfile
2
Envfile
|
|
@ -109,6 +109,8 @@ variable :HONEYCOMB_API_KEY, :String, default: "Optional"
|
|||
variable :MAILCHIMP_API_KEY, :String, default: "Optional-valid"
|
||||
variable :MAILCHIMP_NEWSLETTER_ID, :String, default: "Optional"
|
||||
variable :MAILCHIMP_SUSTAINING_MEMBERS_ID, :String, default: "Optional"
|
||||
variable :MAILCHIMP_TAG_MODERATORS_ID, :String, default: "Optional"
|
||||
variable :MAILCHIMP_COMMUNITY_MODERATORS_ID, :String, default: "Optional"
|
||||
|
||||
# Email digest frequency
|
||||
variable :PERIODIC_EMAIL_DIGEST_MAX, :Integer, default: 0
|
||||
|
|
|
|||
|
|
@ -22,8 +22,10 @@ class Internal::TagsController < Internal::ApplicationController
|
|||
|
||||
def update
|
||||
@tag = Tag.find(params[:id])
|
||||
add_moderator if params[:tag][:tag_moderator_id]
|
||||
remove_moderator if params[:tag][:remove_moderator_id]
|
||||
@add_user_id = params[:tag][:tag_moderator_id]
|
||||
@remove_user_id = params[:tag][:remove_moderator_id]
|
||||
add_moderator if @add_user_id
|
||||
remove_moderator if @remove_user_id
|
||||
@tag.update!(tag_params)
|
||||
redirect_to "/internal/tags/#{params[:id]}"
|
||||
end
|
||||
|
|
@ -31,12 +33,14 @@ class Internal::TagsController < Internal::ApplicationController
|
|||
private
|
||||
|
||||
def remove_moderator
|
||||
User.find(params[:tag][:remove_moderator_id]).remove_role :tag_moderator, @tag
|
||||
user = User.find(@remove_user_id)
|
||||
user.update(email_tag_mod_newsletter: false)
|
||||
AssignTagModerator.remove_tag_moderator(user, @tag)
|
||||
end
|
||||
|
||||
def add_moderator
|
||||
user_id = params[:tag][:tag_moderator_id]
|
||||
AssignTagModerator.add_tag_moderators([user_id], [@tag.id])
|
||||
User.find(@add_user_id).update(email_tag_mod_newsletter: true)
|
||||
AssignTagModerator.add_tag_moderators([@add_user_id], [@tag.id])
|
||||
end
|
||||
|
||||
def tag_params
|
||||
|
|
|
|||
|
|
@ -1,11 +1,34 @@
|
|||
module AssignTagModerator
|
||||
def self.add_trusted_role(user)
|
||||
user.add_role :trusted
|
||||
user.update(email_community_mod_newsletter: true)
|
||||
MailchimpBot.new(user).manage_community_moderator_list
|
||||
end
|
||||
|
||||
def self.add_to_chat_channel(user)
|
||||
ChatChannel.find_by(slug: "tag-moderators").add_users(user) if user.chat_channels.find_by(slug: "tag-moderators").blank?
|
||||
end
|
||||
|
||||
def self.add_tag_mod_role(user, tag)
|
||||
user.update(email_tag_mod_newsletter: true) if user.email_tag_mod_newsletter == false
|
||||
user.add_role(:tag_moderator, tag)
|
||||
MailchimpBot.new(user).manage_tag_moderator_list
|
||||
end
|
||||
|
||||
def self.add_tag_moderators(user_ids, tag_ids)
|
||||
user_ids.each_with_index do |user_id, index|
|
||||
user = User.find(user_id)
|
||||
tag = Tag.find(tag_ids[index])
|
||||
user.add_role(:tag_moderator, tag)
|
||||
ChatChannel.find_by(slug: "tag-moderators").add_users(user) if user.chat_channels.find_by(slug: "tag-moderators").blank?
|
||||
add_tag_mod_role(user, tag)
|
||||
add_trusted_role(user)
|
||||
add_to_chat_channel(user)
|
||||
NotifyMailer.tag_moderator_confirmation_email(user, tag.name).deliver unless tag.name == "go"
|
||||
end
|
||||
end
|
||||
|
||||
def self.remove_tag_moderator(user, tag)
|
||||
user.remove_role(:tag_moderator, tag)
|
||||
user.update(email_tag_mod_newsletter: false) if user.email_tag_mod_newsletter == true
|
||||
MailchimpBot.new(user).manage_tag_moderator_list
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ class MailchimpBot
|
|||
return true unless Rails.env.production? || Rails.env.test?
|
||||
|
||||
upsert_to_membership_newsletter
|
||||
manage_community_moderator_list
|
||||
manage_tag_moderator_list
|
||||
upsert_to_newsletter
|
||||
end
|
||||
|
||||
|
|
@ -45,6 +47,60 @@ class MailchimpBot
|
|||
success
|
||||
end
|
||||
|
||||
def manage_community_moderator_list
|
||||
return false unless user.has_role?(:trusted)
|
||||
|
||||
success = false
|
||||
status = user.email_community_mod_newsletter ? "subscribed" : "unsubscribed"
|
||||
begin
|
||||
gibbon.lists(ApplicationConfig["MAILCHIMP_COMMUNITY_MODERATORS_ID"]).members(target_md5_email).upsert(
|
||||
body: {
|
||||
email_address: user.email,
|
||||
status: status,
|
||||
merge_fields: {
|
||||
NAME: user.name.to_s,
|
||||
USERNAME: user.username.to_s,
|
||||
TWITTER: user.twitter_username.to_s,
|
||||
GITHUB: user.github_username.to_s,
|
||||
IMAGE_URL: user.profile_image_url.to_s
|
||||
}
|
||||
},
|
||||
)
|
||||
success = true
|
||||
rescue Gibbon::MailChimpError => e
|
||||
report_error(e)
|
||||
end
|
||||
success
|
||||
end
|
||||
|
||||
def manage_tag_moderator_list
|
||||
return false unless user.tag_moderator?
|
||||
|
||||
success = false
|
||||
tags = user.roles.where(name: "tag_moderator").map { |t| Tag.find(t.resource_id).name }
|
||||
status = user.email_tag_mod_newsletter ? "subscribed" : "unsubscribed"
|
||||
begin
|
||||
gibbon.lists(ApplicationConfig["MAILCHIMP_TAG_MODERATORS_ID"]).members(target_md5_email).upsert(
|
||||
body: {
|
||||
email_address: user.email,
|
||||
status: status,
|
||||
merge_fields: {
|
||||
NAME: user.name.to_s,
|
||||
USERNAME: user.username.to_s,
|
||||
TWITTER: user.twitter_username.to_s,
|
||||
GITHUB: user.github_username.to_s,
|
||||
IMAGE_URL: user.profile_image_url.to_s,
|
||||
TAGS: tags.join(", ")
|
||||
}
|
||||
},
|
||||
)
|
||||
success = true
|
||||
rescue Gibbon::MailChimpError => e
|
||||
report_error(e)
|
||||
end
|
||||
success
|
||||
end
|
||||
|
||||
def upsert_to_membership_newsletter
|
||||
return false unless a_sustaining_member?
|
||||
|
||||
|
|
@ -80,6 +136,36 @@ class MailchimpBot
|
|||
success
|
||||
end
|
||||
|
||||
def unsub_sustaining_member
|
||||
return unless user.tag_moderator?
|
||||
|
||||
gibbon.lists(ApplicationConfig["MAILCHIMP_TAG_MODERATORS_ID"]).members(target_md5_email).update(
|
||||
body: {
|
||||
status: "unsubscribed"
|
||||
},
|
||||
)
|
||||
end
|
||||
|
||||
def unsub_community_mod
|
||||
return unless user.has_role?(:trusted)
|
||||
|
||||
gibbon.lists(ApplicationConfig["MAILCHIMP_COMMUNITY_MODERATORS_ID"]).members(target_md5_email).update(
|
||||
body: {
|
||||
status: "unsubscribed"
|
||||
},
|
||||
)
|
||||
end
|
||||
|
||||
def unsub_tag_mod
|
||||
return unless a_sustaining_member?
|
||||
|
||||
gibbon.lists(ApplicationConfig["MAILCHIMP_SUSTAINING_MEMBERS_ID"]).members(target_md5_email).update(
|
||||
body: {
|
||||
status: "unsubscribed"
|
||||
},
|
||||
)
|
||||
end
|
||||
|
||||
def unsubscribe_all_newsletters
|
||||
success = false
|
||||
begin
|
||||
|
|
@ -88,13 +174,9 @@ class MailchimpBot
|
|||
status: "unsubscribed"
|
||||
},
|
||||
)
|
||||
if a_sustaining_member?
|
||||
gibbon.lists(ApplicationConfig["MAILCHIMP_SUSTAINING_MEMBERS_ID"]).members(target_md5_email).update(
|
||||
body: {
|
||||
status: "unsubscribed"
|
||||
},
|
||||
)
|
||||
end
|
||||
unsub_tag_mod
|
||||
unsub_sustaining_member
|
||||
unsub_community_mod
|
||||
success = true
|
||||
rescue Gibbon::MailChimpError => e
|
||||
report_error(e)
|
||||
|
|
|
|||
|
|
@ -406,6 +406,10 @@ class User < ApplicationRecord
|
|||
MailchimpBot.new(self).unsubscribe_all_newsletters
|
||||
end
|
||||
|
||||
def tag_moderator?
|
||||
roles.where(name: "tag_moderator").any?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def send_welcome_notification
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ class UserPolicy < ApplicationPolicy
|
|||
email_digest_periodic
|
||||
email_follower_notifications
|
||||
email_membership_newsletter
|
||||
email_tag_mod_newsletter
|
||||
email_community_mod_newsletter
|
||||
email_mention_notifications
|
||||
email_connect_messages
|
||||
email_newsletter
|
||||
|
|
|
|||
|
|
@ -53,11 +53,25 @@ module Moderator
|
|||
end
|
||||
|
||||
def remove_privileges
|
||||
@user.remove_role :trusted
|
||||
@user.remove_role :video_permission
|
||||
@user.remove_role :tag_moderator
|
||||
@user.remove_role :workshop_pass
|
||||
@user.remove_role :pro
|
||||
remove_mod_roles
|
||||
remove_tag_moderator_role
|
||||
end
|
||||
|
||||
def remove_mod_roles
|
||||
@user.remove_role :trusted
|
||||
@user.remove_role :tag_moderator
|
||||
@user.update(email_tag_mod_newsletter: false)
|
||||
MailchimpBot.new(user).manage_tag_moderator_list
|
||||
@user.update(email_community_mod_newsletter: false)
|
||||
MailchimpBot.new(user).manage_community_moderator_list
|
||||
end
|
||||
|
||||
def remove_tag_moderator_role
|
||||
@user.remove_role :tag_moderator
|
||||
MailchimpBot.new(user).manage_tag_moderator_list
|
||||
end
|
||||
|
||||
def create_note(reason, content)
|
||||
|
|
@ -76,28 +90,47 @@ module Moderator
|
|||
user.add_role :banned
|
||||
remove_privileges
|
||||
when "Warn"
|
||||
user.add_role :warned
|
||||
user.remove_role :banned
|
||||
remove_privileges
|
||||
warned
|
||||
when "Comment Ban"
|
||||
user.add_role :comment_banned
|
||||
user.remove_role :banned
|
||||
remove_privileges
|
||||
comment_banned
|
||||
when "Regular Member"
|
||||
remove_negative_roles
|
||||
user.remove_role :pro
|
||||
regular_member
|
||||
when "Trusted"
|
||||
remove_negative_roles
|
||||
user.remove_role :pro
|
||||
user.add_role :trusted
|
||||
add_trusted_role
|
||||
when "Pro"
|
||||
remove_negative_roles
|
||||
user.add_role :trusted
|
||||
add_trusted_role
|
||||
user.add_role :pro
|
||||
end
|
||||
create_note(role, note)
|
||||
end
|
||||
|
||||
def comment_banned
|
||||
user.add_role :comment_banned
|
||||
user.remove_role :banned
|
||||
remove_privileges
|
||||
end
|
||||
|
||||
def regular_member
|
||||
remove_negative_roles
|
||||
user.remove_role :pro
|
||||
remove_mod_roles
|
||||
end
|
||||
|
||||
def warned
|
||||
user.add_role :warned
|
||||
user.remove_role :banned
|
||||
remove_privileges
|
||||
end
|
||||
|
||||
def add_trusted_role
|
||||
user.add_role :trusted
|
||||
user.update(email_community_mod_newsletter: true)
|
||||
MailchimpBot.new(user).manage_community_moderator_list
|
||||
end
|
||||
|
||||
def remove_negative_roles
|
||||
user.remove_role :banned if user.banned
|
||||
user.remove_role :warned if user.warned
|
||||
|
|
|
|||
|
|
@ -15,6 +15,18 @@
|
|||
<%= f.label :email_membership_newsletter, "Send me sustaining membership newsletter emails" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if current_user.tag_moderator? %>
|
||||
<div class="sub-field">
|
||||
<%= f.check_box :email_tag_mod_newsletter %>
|
||||
<%= f.label :email_tag_mod_newsletter, "Send me tag moderator newsletter emails" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if current_user.has_role?(:trusted) %>
|
||||
<div class="sub-field">
|
||||
<%= f.check_box :email_community_mod_newsletter %>
|
||||
<%= f.label :email_community_mod_newsletter, "Send me community moderator newsletter emails" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="sub-field">
|
||||
<%= f.check_box :email_comment_notifications %>
|
||||
<%= f.label :email_comment_notifications, "Send me an email when someone replies to me in a comment thread" %>
|
||||
|
|
|
|||
|
|
@ -139,7 +139,6 @@ Rails.application.routes.draw do
|
|||
resources :rating_votes, only: [:create]
|
||||
resources :page_views, only: %i[create update]
|
||||
resources :buffer_updates, only: [:create]
|
||||
|
||||
get "/notifications/:filter" => "notifications#index"
|
||||
get "/notifications/:filter/:org_id" => "notifications#index"
|
||||
patch "/onboarding_update" => "users#onboarding_update"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
class AddMailchimpListsToUsers < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :users, :email_tag_mod_newsletter, :boolean, default: false
|
||||
add_column :users, :email_community_mod_newsletter, :boolean, default: false
|
||||
end
|
||||
end
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2019_04_04_102732) do
|
||||
ActiveRecord::Schema.define(version: 2019_04_05_190915) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
|
|
@ -779,6 +779,7 @@ ActiveRecord::Schema.define(version: 2019_04_04_102732) do
|
|||
t.string "email"
|
||||
t.boolean "email_badge_notifications", default: true
|
||||
t.boolean "email_comment_notifications", default: true
|
||||
t.boolean "email_community_mod_newsletter", default: false
|
||||
t.boolean "email_connect_messages", default: true
|
||||
t.boolean "email_digest_periodic", default: true, null: false
|
||||
t.boolean "email_follower_notifications", default: true
|
||||
|
|
@ -786,6 +787,7 @@ ActiveRecord::Schema.define(version: 2019_04_04_102732) do
|
|||
t.boolean "email_mention_notifications", default: true
|
||||
t.boolean "email_newsletter", default: true
|
||||
t.boolean "email_public", default: false
|
||||
t.boolean "email_tag_mod_newsletter", default: false
|
||||
t.boolean "email_unread_notifications", default: true
|
||||
t.string "employer_name"
|
||||
t.string "employer_url"
|
||||
|
|
|
|||
|
|
@ -8,16 +8,27 @@ class FakeGibbonRequest < Gibbon::Request
|
|||
def members(*args)
|
||||
super
|
||||
end
|
||||
|
||||
def tag_mods(*args)
|
||||
super
|
||||
end
|
||||
|
||||
def community_mods(*args)
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe MailchimpBot do
|
||||
let(:user) { create(:user, :ignore_after_callback) }
|
||||
let(:article) { create(:article, user_id: user.id) }
|
||||
let(:my_gibbon_client) { instance_double(FakeGibbonRequest) }
|
||||
let(:tag) { create(:tag, name: "tag name", bg_color_hex: Faker::Color.hex_color, text_color_hex: Faker::Color.hex_color, supported: true) }
|
||||
|
||||
before do
|
||||
allow(Gibbon::Request).to receive(:new) { my_gibbon_client }
|
||||
allow(my_gibbon_client).to receive(:lists) { my_gibbon_client }
|
||||
allow(my_gibbon_client).to receive(:tag_mods) { my_gibbon_client }
|
||||
allow(my_gibbon_client).to receive(:community_mods) { my_gibbon_client }
|
||||
allow(my_gibbon_client).to receive(:members) { my_gibbon_client }
|
||||
allow(my_gibbon_client).to receive(:upsert).and_return(true)
|
||||
end
|
||||
|
|
@ -82,6 +93,42 @@ RSpec.describe MailchimpBot do
|
|||
end
|
||||
end
|
||||
|
||||
describe "manage community moderator list" do
|
||||
it "returns false if user isn't a community moderator" do
|
||||
expect(described_class.new(user).manage_community_moderator_list).to be(false)
|
||||
end
|
||||
|
||||
it "sends proper information" do
|
||||
user.update(email_community_mod_newsletter: true)
|
||||
user.add_role :trusted
|
||||
described_class.new(user).manage_community_moderator_list
|
||||
expect(my_gibbon_client).to have_received(:upsert).
|
||||
with(hash_including(
|
||||
body: hash_including(
|
||||
status: "subscribed",
|
||||
),
|
||||
))
|
||||
end
|
||||
end
|
||||
|
||||
describe "manage tag moderator list" do
|
||||
it "returns false if user isn't a tag moderator" do
|
||||
expect(described_class.new(user).manage_community_moderator_list).to be(false)
|
||||
end
|
||||
|
||||
it "sends proper information" do
|
||||
user.update(email_tag_mod_newsletter: true)
|
||||
user.add_role(:tag_moderator, tag)
|
||||
described_class.new(user).manage_tag_moderator_list
|
||||
expect(my_gibbon_client).to have_received(:upsert).
|
||||
with(hash_including(
|
||||
body: hash_including(
|
||||
status: "subscribed",
|
||||
),
|
||||
))
|
||||
end
|
||||
end
|
||||
|
||||
describe "#upsert_to_membership_newsletter" do
|
||||
it "returns false if user isn't a sustaining member" do
|
||||
expect(described_class.new(user).upsert_to_membership_newsletter).to be(false)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue