Eric / Brooklyn

Random 5

Operator as Methods

Web Accounts

Honeypot Bots

Stripe and Tap

Git Save

Whitespace Problems

Ruby Exits

Appending in Javascript

Sendgrid Ban

Clean URLs

Integer Division

Multi-tab Websockets

Bad Content

JS Data Chutzpah

Responsive tables

Concerns

Cookies

Emoji Bits

Git

Ruby vs. Ruby

Extending Devise

Rails UJS

ENV Variables

See All

How to get banned from SendGrid in 10 seconds

Nov 2020

Be Careful what you tell your computers to do, because they’ll do it.

I’m making a web app using Rails, and the gem Faker allows us to work with dummy user data before actual non-dummies Log On.

I was using the Harry Potter flavor of Faker’s dummy data, so my users had names like Fluffle BippleBap and emails like fbibblebap@gmail.com.

When a user creates an account, she gets a welcome email. Rails ActionMailer makes this nice and easy.

Since we’re in Rails Land, of course we’re using Devise - this allows us to create and manage user accounts with ease.

Controllers and Models

Since we’ve outsourced our account creation to Devise, we don’t have immediate access to a create action in the users_controller - Devise has it’s own controllers.

But we want to send a user an email after her account is created - seems like this could live happily in the create action that we don’t have.

So we seem to have at least 2 options.

  1. We can extend the Devise registrations_controller and add an after_action to the create action that sends a welcome email. I probably should have done this.
  2. We can add an after_create callback in the User model that sends the email. Needless to say, this is what I did.

Now this toxic seed was planted weeks before it grew into a full banning from SendGrid, thanks in part to another handy Rails gem called Letter Opener.

Instead of sending an actual email to fbipplebap@gmail.com, Letter Opener just shows us a pretend HTML email in our browser.

The Main Event

So we’re using Letter Opener in our development environment, but not for our staging environment, because in staging, we want to see that emails actually get delivered.

Now you can probably see where this is headed. Here are the magical 10 seconds that led to my banning:

On my Heroku dashboard for the staging site, I added the SendGrid add-on. (3 seconds)

Then, I seeded the staging database: rails db:seed . (3 seconds)

Then, 100 Harry Potter dummies were created. The after_create callback mentioned above is fired 100 times, and 100 emails are sent to Harry Potters. And 100 emails bounce. (4 seconds)

I set up my computer to fail. And SendGrid’s computer is smart enough to notice my 100% bounce rate, and promptly banned me.

A Better Approach

Instead of the after_create callback on the model, I could have extended the Devise controller, and used an after_action .

The difference between these two approaches may seem minor, but the difference between being banned and not being banned is major.

The after_create method will fire any time a record is created for the corresponding model - i.e. User.create This could happen from the console, the seed file, or from inside a controller somewhere. My self-inflicted damage happened in the seed file.

If I had used an after_action in a controller, I would have been safe. This is because the controller action is only called from a specific route - when the user actually interacts with the UI. The controller action is unrelated to me calling User.create somewhere else in my code.

Another Approach

Use real emails! This was actually my first fix. I created an alias email in the Google Apps admin (t@bounce.so) that gets forwarded and skips the inbox. And in the seed file, just used something that looked like this:

100.times do |i|
	u = User.new
	u.email = "t+#{i}@bounce.so"
	u.save
end

Post Morten

SendGrid, please unban me!