Migrating from Mandrill to SendGrid

Recently The Rocket Science Group, the company behind both Mandrill and MailChimp, decided to change things up. They decided to roll Mandrill, their transactional E-Mail service, into MailChimp as a paid addon available to paid MailChimp accounts only. A lot of people freaked out or got really upset, most of them focusing on the fact that many people who were using Mandrill for free or close to it, were going to have to start paying at least $40 per month. That’s $20 per month for a MailChimp account, which they might not even have a use for, and $20 per month for the lowest tier of the Mandrill transactional email addon.

I was upset too. Not because of the additional cost, but because of the way Mandrill users were treated. An email went out to all Mandrill users on February 24th, mandating that all existing users needed to have a paid MailChimp account set up and connected to Mandrill by April 27th. That gave nine weeks.

Nine weeks isn’t a lot of time, and Rocket Science knew this. Is it enough time to set up a MailChimp account, link it to your Mandrill account, and pay them the extra money every month? Yes. Was it enough time to research an alternative, set up an account elsewhere, rewrite all your transactional email code to use a new API, train users to use a new interface at this new solution, test all the new code, and deploy? Not really. At least not in many cases.

However, that’s exactly what I did. Not because I was upset at the extra monthly cost, but because I didn’t like being treated like that.

I started with some simple research to find alternatives. As it turned out, plenty of other people were doing the same research and posting their findings, which greatly simplified the process. What I found is that since my usage was pretty straight forward, almost any of the available alternatives would work for me. I ended up choosing SendGrid.

The actual development wasn’t particularly interesting.  The APIs are different, as you would expect, so all the code needed to be changed but was ultimately similar enough to be pretty simple.

One of our hangups came with tags. In Mandrill we used tags to label various kinds of E-Mails, what server the E-Mail was triggered from, etc. We use those to help us track where deliverability issues occur, as well as to help us track down bugs when they happen. The problem was that SendGrid didn’t have these. Luckily, SendGrid DOES have what they call “Unique Arguments“. Basically, they let us do the same thing, adding in our own unique key/value pairs, with the only downside being that their web app doesn’t give you much in the way of working with those (like viewing all bounces with a specific value for one of the arguments).

And that seems to be the only real downside so far. The web app for SendGrid doesn’t seem to be quite as powerful or fully functional as the one Mandrill has. Having said that, delivery, responsiveness, speed, etc all seem completely on par. I’ll happily give up the zoomy UI though, if they’ll treat their customers with a little more respect.

Being Understanding in this Digital Age

This has been an interesting week for me. I’ve worked every day from a hospital room. To try to keep a very long story somewhat short, my grandma was in the ER Sunday, the experience was bad and they dismissed her rather than taking the time to actually figure out the problem. This resulted in her being BACK in the ER (a different ER; fool me once and all that) as 12:30am Monday morning, getting admitted to the hospital a few hours later, and being under acute care ever since.

It’s rather severe. She’ll likely be in the hospital another week or two, but the prognosis is starting to look up.

It’s been incredibly hard on my immediate family. My grandpa has severe Alzheimer’s, and while there are many things he cannot remember, he never seems to forget that his wife of nearly 68 years is in the hospital. Not for even a second. Unfortunately, he can’t stay at the hospital with her all day every day, because he needs to have some routine to help keep him on track. This means that my dad has been taking care of grandpa, and playing shuttle service to bring him to the hospital every day and take him back home every evening.

Emotions have been high as well. Everyone here cares about my grandma greatly, and that can cause logic to be clouded by emotion, making everyone a little more touchy and on edge. Especially when things weren’t looking so good.

So what does all this have to do with being understanding? Well, that comes down to some of the communications I’ve received this week. The ones from people that have no idea where I’m at or what I’m going through.

They tend to start out innocent enough. Someone asking me about one of my WordPress plugins, possibly sending me a product or service they’d like me to review, or even sending me a legitimate work proposal.

Unfortunately, any of those kinds of things that came through this week have been summarily ignored. I’m not sorry about that. None of those things are important enough to take even a few minutes of attention away from my grandma and what she’s going through. I suppose I could have responded with some short blurb explaining what was going on, but I stand by my actions as being perfectly acceptable. And yes, I’d ignore them all again (and probably will for at least another week).

Receiving, and ignoring, those messages didn’t bother me at all though. Like I said, they didn’t know where I was or what I was going through. The frustration really started yesterday (or more accurately last night), when I started to open and read some of the more recent messages. Some of then had taken on an angry tone; “if you don’t care about this, then…”, “You’ll never get my work if you don’t respond”, or “People said you were reliable, but I guess they were wrong.”

Just how fucking important do you think you are?

Not that I need to justify myself, but I think pointing out my internal responses to these statements helps underline how ludicrous they really are:

  • It’s not that I don’t care about whatever it was you were writing about, I just don’t care enough to put it above my family. Deal with it.
  • I don’t want your work anyway. Even if I was looking for work, working for an impatient, self-important, pain in the butt, isn’t my idea of fun.
  • I’m glad to hear people said I’m reliable. Right now, my family finds me incredibly so. I’m glad that me not responding to you in 48 hours gives you the right to judge me differently.

The truth is, we’ve all come to expect a level of accessibility that I think has become unreasonable and unsustainable. Technology has made it so that most of us, myself included, walk around with our E-Mail, Twitter, Facebook, etc in our pocket. We tend to check it habitually, and therefore respond quickly. Often within minutes or hours.

The problem is that, as we all know, doing something consistently builds expectation. People now expect a response within an hour, think themselves patient if they wait half a day, and feel like you’re purposely ignoring or slighting them if it takes longer. The distance the electronics place between us makes it easy to never take the time to think about where the person on the other end of your communication is, what they’re doing, or what they’re going through.

I have to think that not a single one of these people would have barged into my grandma’s hospital room to give me their message, expecting me to stop dealing with family and put my attention on them. Yet essentially that’s what they asked of me.

Expectations of availability have gotten out of control. When do they afford us time for ourselves? When do we get to focus on something so important that we don’t want to be bothered?

Try to remember that even though there is often technology between you and someone else, it’s still a person you are dealing with. A person that has to go through the same kind of crap as you sometimes. Be understanding.

WordPress Security – The Big Picture and What You Need

I’m pretty passionate about WordPress, I’m pretty passionate about security, and I’m heavily involved in both. I’ve been working with WordPress for over ten years and helping build WordPress for over eight. I’m also on the WordPress core security team and have recently taken a lead role working on the iThemes Security plugin.

There has been a lot happening around WordPress security lately. Even the Federal Bureau of Investigation (FBI) has weighed in with a Public Service Announcement. An article by The Register covering that PSA was recently brought to my attention through Facebook, and honestly caused quite a stir.

First, the URL itself ends in “word_press_is_atrocious”. Ignoring the fact that WordPress is a single word, the word atrocious is never used in the article itself. It’s just a good, scarey URL. Even without using that word though, the article scared a lot of people. It ends with this gem:

WordPress hacking is a favourite pastime of lazy hackers and exploit kit -slingers who seek to achieve maximum carnage for minimum effort.

Is that really the case?

I think that the maximum carnage part is obvious. Numbers put WordPress at somewhere between 20 and 25 percent of the web, so if you want to be able to affect literally tens of millions of sites at once, you want to compromise WordPress.

Having said that, minimum effort is also accurate and explainable. Minimum effort because you only have to target a single system. Minimum effort because when you find an exploit, even one that’s already been patched, there are going to be sites out there that are vulnerable because people don’t upgrade. Minimum effort because you can stand on the shoulders of giants, since so many people are working to do exactly what you’re doing.

Sound scarey? It’s really not. Especially not for you! It’s tougher for the project as a whole…I’ll try to explain.

In the last couple years, the target on our back has grown because we’ve grown. But we’ve made a lot of progress toward being more secure. It goes FAR beyond patching a security hole. The biggest insecurities come from those that don’t update and from insecure plugins or themes. So we focused on those.

Now we have auto updates. When a new security release of WordPress is released (the y in x.x.y), WordPress updates to it automatically. Of course, some people complained about this, but ultimately (and statistically) WordPress sites on the whole are much more secure now.

We’ve also put some pretty serious systems in place for handling plugin vulnerabilities. We have plugins@wordpress.org and security@wordpress.org that can be E-Mailed if a problem is discovered. We have a plugin team that can review it, and if necessary remove it from the repo while a fix is worked on. When a fix is released, if it makes sense, we can even push the update automatically like we can with security releases of core.

We take this EXTREMELY seriously. We don’t want to update a plugin and break a site, so we don’t force everyone to the latest version. Instead we require a security patch be applied to each branch of the plugin and only update you to what you already had…but SECURE! BOOM! Isn’t that nice? I mean, people complain, but again: WordPress sites as a whole are more secure.

In the specific case sited in the Register article, they are talking about WP Super Cache. If we use their numbers, there are one million sites affected by this vulnerability. Remember, that’s out of over sixty million sites that run WordPress. And what do you need to be secure again? Simply update the plugin. A few clicks in your dashboard. Unfortunately, some people will put off the update, leaving their site vulnerable to attack rather than installing the update quickly and fixing the problem.

The good news is, we can push out patches to all one million sites in ONE DAY. All those sites will be secure again, even though it was a plugin that had the vulnerability.

So that’s the big picture, but I said it was easier for you, didn’t I? What can you do? There are lots of things, but let me list out the biggest ones for you so you can tick them off:

  1. Check your site daily and update things.
  2. Use strong passwords. This means getting something like 1password or Lastpass because you can’t have 50 character random passwords that are different for every site without having a way to manage those. In this same vein, usernames aren’t secret. Don’t worry about your username, just make sure your password is strong.
  3. Limiting login attempts is great. It’s NOT a replacement for a strong password, but it helps with brute force attacks. None of the recent big (meaning affecting lots of sites) vulnerabilities were from brute force attacks, but they still happen. If you have a strong password, brute force is more likely to take down your server than result in a compromised site. Obviously you still want to avoid this.

There’s obviously more you can do. Security is complex, nuanced, and tedious. But if you do those three things, you’ll be most of the way there.

Header image credit smlp.co.uk, on Flickr

Adding your WordPress Plugin to GitHub

I’ve started putting my plugins on Github so it’s easier for developers to contribute. One of the big benefits of version control is the history, so I would hate to lose that on the move to git. The good news? I didn’t have to. The better news? It was actually easier than you might think. The instructions below are for GitHub but could easily be adapted to any git repo.

Start by setting up svn2git. You need to have git-svn, ruby, and rubygems istalled to use it:

sudo apt-get install git-core git-svn ruby rubygems

Then you can install the svn2git ruby gem:

sudo gem install svn2git

Now create your new repo on Github, but make sure to create an empty repo. Do not check the “Initialize this repository with a README” checkbox, and do not have it set up a .gitignore file or a license file. If the repo isn’t empty, the import process will not work.

GitHub New Repo

Now clone your new repo to your local system, and don’t worry about the warning that the repo is empty:

$ git clone git@github.com:{username}/{repository-name}.git
Cloning into '{repository-name}'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done

Now you need to create an authors.txt file so that the users that committed to your plugin get proper credit in the Github repo. You can get the list of authors using this command, making sure to fill in the correct location of your WordPress.org plugin repository:

svn log --quiet  http://plugins.svn.wordpress.org/{your-plugin} | grep -E "r[0-9]+ \| .+ \|" | awk '{print $3}' | sort | uniq > ~/authors.txt

You’ll get a file that looks something like this:


If you see “plugin-master” in there, that’s the account that created your WordPress.org repo. I usually just credit that to myself. Now you need to modify that authors.txt file, setting a Github account for each username. You can set the github account E-Mail as well as the display name. The format should look like this:

aaroncampbell = Aaron D. Campbell <aaron@example.com>
plugin-master = Aaron D. Campbell <aaron@example.com>

Now that you’ve updated and saved the authors.txt file, you can use it in the next step. Start by changing to the directory you cloned the Github repo into. Now for the magic. There are two options, one is simpler and takes longer to run, one is faster and more complex. Read both and choose which makes sense for you:

The simple option is to run this svn2git command, making sure to fill in the correct location of your WordPress.org plugin repository and the authors.txt file you created:

svn2git http://plugins.svn.wordpress.org/{your-plugin} --authors ~/authors.txt --no-minimize-url

This command will take quite a while. The WordPress.org repository is quite large and it takes a long time to process that much history. The good news is, if you’re willing to take a couple extra steps, you can speed this process up a lot. We can do this by giving svn2git a subset of revisions to check. Start by running this command:

svn log --limit 1 -r 1:HEAD http://plugins.svn.wordpress.org/{your-plugin}

The item listed there should have a revision number like r41107, which was when your plugin was started. Run this command to similarly find the most recent revision for your plugin:

svn log --limit 1 -r HEAD:1 http://plugins.svn.wordpress.org/{your-plugin}

Now you can plug those into the command below, using just the numbers and dropping the leading r, and run the same magic but in a fraction of the time:

svn2git http://plugins.svn.wordpress.org/{your-plugin} --authors ~/authors.txt --no-minimize-url --revision {oldest-revision}:{newest-revision}

Once that runs, everything has been imported and committed, and all you need to do is push it to up to Github. Make sure to push the tags as well:

git push
git push --tags

That’s it! Your WordPress plugin, along with all it’s history, is now on Github.

Search Engine Optimization (SEO) in Simple Terms

First let me say that search engine optimization is a very complex subject. There are people who really know what they are doing and plenty of people that don’t. This writeup will not get you to the point where you really understand it all, and I highly recommend that you budget for a professional, but this will be a good start for people that are just starting and need to know what they can do.

Search Engine Optimization, in simple terms, breaks down into two sections; onsite and offsite. Onsite is well within your control and is the first thing you should focus on. Offsite is harder to control and is something you will focus more on later.


First, make a list of key phrases that you want to rank well for in search engines. Usually these should be two to five words long. It is not realistic for you to think that your site will rank for a term like “jewelery” (you’d be competing against Jared, Tiffany, Kay, etc), but you may rank very well for something like “vintage typewriter jewelry”. Make sure to be reasonable about what you can and cannot compete for.

I recommend using a something like Google’s Adwords Keyword Tool to research your terms. Obviously more traffic is good, but remember to check who you are competing against and always ask yourself “will my perfect client really search for this term?”. Also try to keep an open mind. Take a look at other terms that Google things are related to the one you put in. Remember that you are likely far more knowledgeable about your products/services than your clients, which means they will likely be using different terminology when searching.

You need to also try to understand what I call key phrase clusters. For example, when I checked out “Vintage Typewriter Jewelry” I found that it is searched for 140 times per month. That’s not a lot. However, I also saw that “Typewriter Key Jewelry” is searched 880 times per month (seven times as often). I also saw that “Vintage Typewriter Key Jewelry” is searched 91 times per month and immediately I saw a key phrase cluster. Basically, there are three phrases that are all basically the same, and if we are careful we can target them all at once. How? Well, we use the all inclusive “Vintage Typewriter Key Jewelry” phrase. Take a look:

  • Vintage Typewriter Key Jewelry” = “Vintage Typewriter Key Jewelry” which is searched 91 times per month
  • “Vintage Typewriter Key Jewelry” = “Typewriter Key Jewelry” which is searched 880 times per month
  • Vintage Typewriter Key Jewelry” = “Vintage Typewriter Jewelry” which is searched 140 times per month

By using the one phrase regularly on a site you can actually target all three. Search engines can easily understand that someone searching for “Vintage Typewriter Jewelry” may be interested in “Vintage Typewriter Key Jewelry”.

This takes time. Quite a bit of time. It takes time to build a list of key phrases (or key phrase clusters). There’s really no way around that. The thing is…it will pay off.

So, once you have your list, when/where do you use these? The answer in short is…everywhere. You don’t want to “keyword stuff” which basically means to put them where they don’t make sense, but you do want to use them regularly. When you write articles, when you write product descriptions, even when you write something on other sites and link back to yours. These are supposedly phrases that describe something you are an authority on, so be authoritative!


Offsite is something you have less control over. The basics are that you want other sites to link to you. These are called “inbound links” and are a metric that search engines use directly to rate your authority on any given phrase. Often getting a link can be as easy as asking. Sometimes a site would link to you if they just knew about you. Asking is simple and effective, but remember that buying inbound links will get you penalized in search engines (I cannot be more clear than this: Do not buy links to your site).

The simplest way I can explain it is this: An inbound link is worth more to you if the site it’s coming from has content related to yours. It’s worth even more if the page it’s on contains one or more of your target key phrases, and more still if the link itself contains one of your key phrases. For example, this is ok: “I saw some great vintage typewriter key jewelry today, click here to see it.” This is WAY better: “I saw some great vintage typewriter key jewelry today!”

You can help to curate incoming links by doing a few things:

  • First and foremost you get incoming links by creating good content. If someone sees a good article on your site, they will link to it. I cannot stress enough that this is the absolute best thing you can do. If you take nothing else from this entire article, please just remember that quality content is the key.
  • Approach sites whose users would be interested in your content and ask for a link. Make sure to be specific when you ask. It’s ok to say that you’d like the link text to be _____. The worst they can do is say no.
  • Become active on other sites and link back to your own site. I don’t mean spam, I mean really be active.
  • Other sites are looking for content too, so consider doing a guest post for another site that links to yours.

This is by no means a definitive or exhaustive guide, but hopefully it’s enough to not only get you started, but carry you through for a while.