Skip to content

Instantly share code, notes, and snippets.

@jorgemanrubia
Last active July 20, 2023 19:57
Show Gist options
  • Save jorgemanrubia/5f0ee2d1561e2dcd112887e91873b4d2 to your computer and use it in GitHub Desktop.
Save jorgemanrubia/5f0ee2d1561e2dcd112887e91873b4d2 to your computer and use it in GitHub Desktop.
AFFECTED_TOPICS_BY_ACCOUNT_ID = { 123 => [ 4, 5, 6] }
class SpamIncidentMailer < ApplicationMailer
include ActionView::Helpers
def notification(account, topic_ids)
subject = "Emails between HEY users marked as spam"
urls = topic_ids.collect do |topic_id|
"https://app.hey.com/topics/#{topic_id}"
end
recipient = account.primary_owner.contact
mail \
subject: subject,
to: recipient.email_address,
from: "The HEY Team <support@hey.com>",
reply_to: "support@hey.com",
body: notification_body(account.primary_owner.name.split(" ").first, urls)
end
def notification_body(name, urls)
<<~TEXT
Hi #{name},
A recent change resulted in HEY flagging emails from other HEY users as spam. Unfortunately, this problem affected these emails in your account:
#{urls.collect { |url| "- #{url}" }.join("\n")}
We have already fixed the problem and removed the spam flag from all the affected emails.
We are really sorry that this problem impacted you. Please feel free to reply to this email if you need any further clarification or help with anything else.
The HEY team
TEXT
end
end
AFFECTED_TOPICS_BY_ACCOUNT_ID.each do |account_id, topic_ids|
SpamIncidentMailer.notification(Account.find(account_id), topic_ids).deliver_now
end
class AffectedEmailProcessor
attr_reader :affected_topics_by_account_id
def initialize(from_entry_id, limit_date)
@from_entry_id = from_entry_id
@limit_date = limit_date
@affected_topics_by_account_id = Hash.new { |h, k| h[k] = [] }
end
def process
Entry.where("id <= ?", @from_entry_id).preload(:receipt, :creator).find_each(order: :desc) do |entry|
if affected?(entry)
fix(entry)
end
if entry.id % 1000 == 0
show_status_at entry
end
if entry.created_at < @limit_date
puts "No more accounts to process"
show_status_at entry
break
end
end
end
private
AUTHENTICATION_HEADER_VALUE = /(home|work)-mx\.app\.hey\.com;\s+none/
def affected?(entry)
entry.inbound? && hey_user?(entry) && entry.spam? && has_internal_spam_header?(entry)
end
def hey_user?(entry)
entry.creator.email_address =~ /@hey.com$/ || entry.creator.user?
end
def has_internal_spam_header?(entry)
entry.receipt.inbound_email.mail["Authentication-Results"].to_s =~ AUTHENTICATION_HEADER_VALUE
end
def fix(entry)
topic = entry.topic
topic.ham!
@affected_topics_by_account_id[topic.account_id] << topic.id
end
def show_status_at(entry)
puts "#{entry.created_at} - #{entry.id}. Affected: #{@affected_topics_by_account_id.inspect}"
end
end
# https://app.hey.com/topics/968107472#__entry_1035879760 # Entry processed right after the initial mitigation
ActiveRecord::Base.logger = ActiveSupport::Logger.new(nil)
from_entry_id = 1035879760
Time.zone = "UTC"
limit_date = Time.zone.parse("2023-05-17 05:18 UTC")
processor = AffectedEmailProcessor.new(from_entry_id, limit_date)
processor.process
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment