How to build HubSpot workflows that respond to clicks to offsite links in emails

HubSpot’s workflow tooling is simple and powerful, but there’s one thing it doesn’t do out of the box.

For every qualifying person, I’ll use a workflow to send a welcome email containing a unique registration URL. I also want to send an automatic reminder after a few days if he/she doesn’t click the link.

Simple, right? Well, no.

  • Even though it’s possible to see whether a user has clicked a link in a particular email, it’s not possible to build workflow triggers directly off those clicks.
  • I don’t have access to the destination domain, so I can’t track visits.
  • I can’t rely on CSS or HTML to identify the link.

To make this possible, I now do the following:

  1. Create a redirection page and link to that page instead
  2. Create an event that tracks any user’s visits to that URL pattern
  3. Create a smart list containing everyone who has experienced that event
  4. Use that smart list to trigger workflow unenrollment

Here’s an example.

In my new emails, I’ll create a page on my HubSpot domain called “redirect” and link to “”, track the visit, then redirect to “”.

Here’s a public gist containing the template for creating this page. Create a new template with that code, then create a landing page based on that template. You’ll want a new page for every specific redirection use case so you can track clicks properly.

You can use it to redirect everyone with or without a query string. To redirect everyone to the exact same URL, fill in the “Destination URL” value.

To redirect everyone to the same URL but with different query strings, also fill in the “URL parameter in original URL” value. In the above example, this would be the letters “p1”. It will grab the attached value in the original URL (“v1” above) and re-attach it to the destination URL.

Then create an event that tracks visits to that page, like this:


Then create a smart list to keep track of everyone who has encountered that event, like this:


Finally, set the new smart list as the unenrollment trigger for the original workflow.

Questions? Holler on Twitter @superstrong

The absolute basics of an education service (PII, COPPA, and consent)

Some education bloggers are in a wax about personally identifiable information (PII) and consent when it comes to data collection among education apps. They are either uncomfortable with any collection of PII, uncomfortable about how it gets shared (privacy), or uncomfortable about how it’s secured (security).

Regardless of the angle, there’s something incredibly basic about PII that doesn’t seem to be understood widely.

1. Login and password require an email address (PII)

If you run a website where a user wants to generate or store data, wants the data to be private, and want to return to it later, you need some sort of “account” mechanism with a password. And because you want to be able to send that user a password reset (among other basics), you need to store an email address.

2. COPPA restricts collecting email address from minors

Neither an email address nor a password (which is encrypted) needs to contain anything personally identifiable about the user. Still, COPPA considers email address PII, and also prohibits websites from collecting PII for anyone under 13. This is effectively the age of consent.

3. To comply with COPPA, websites must ask for birth date (PII)

As a result, websites don’t store an email address for a child under 13. To comply, education websites might ask the user for a birth date. Some websites stop there and prohibit account creation. Others might use a parent/child account creation framework to let a parent create an account, then create and manage a child’s account until age 13, after which the child has the right to take over his/her own account and attach an email address.

4. FERPA extends protections to student data in institutional settings

FERPA adds additional complexity by restricting data used in institutional settings, so you’ll also see institutional products raise the age of consent from 13 to 18.

Why does all this matter?

PII sounds scary — and sometimes it is. Facebook collects an awful lot of personal information about someone, and with a dismal record of privacy and transparency. So do Instagram and Twitter. So do schools.

But PII can also refer to the basics — email and birth date. The mere presence of PII doesn’t make a service scary, it makes it a functioning service.

Furthermore, when a company says it will never share data without consent, some bloggers take that to mean it’s a vague, blanket approval, without digging into a particular product or service. Why people continue to debate these principles without looking at the actual products people use — and the data involved — is beyond me. It’s fuzzy thinking. Education is too important for blind rhetoric.

In my company’s case, “consent” (as used in our pithy marketing materials) refers to specific actions, such as using an email address to sign in to multiple places (explicit action and consent to share data to the additional application) and sharing pieces of data with another user (explicit action and consent to share specific data with a specific person). These are specific product features, not nefarious settings.

We’re building something about as learner-centered as it gets: minimal PII stored, learners in control of their accounts and data, and explicit consent for specific actions. You don’t help learners by shielding them from data, you help them by empowering them with it responsibly.

If bloggers want to write about PII assuming the worst possible intentions in products collecting it, they’re free to do so. But they should know they might be completely wrong in their assumptions, irresponsible with their influence, and counterproductive as a result.

Some of My Best Zapier Recipes (Zaps)

Zapier has become my answer to any quick project need, and a must-have for hack days. It’s “If This Then That” but dramatically more powerful, and for many more services—especially the tools we use at work. And it lets me scratch an itch without having to beg a developer to do it for me.

Here are a few of my favorite problem solvers from the past year.

1. Gmail -> HubSpot

Outcome: When replying to someone who wants to stay in touch, I can say “I’ll add you to our newsletter” and actually do so with a couple keystrokes.

How: In Gmail create a label called “newsletter”.

In Zapier, trigger on any new email in a thread. Mailbox/tag name is your new label. Search String is “from:<your email address” (without quotes). {{The Email}} to be added as a HubSpot Contact is {{To Address}}.

To trigger the Zap, apply the label to the thread.

2. Web Hook (Retrieve Poll) -> Email

Outcome: When a particular phrase is mentioned on Hacker News, email me.

How: There’s a third-party site that provides full-text search for Hacker News. You can poll it with your search. The Web hook URL is:"<search term>"&tags=comment

Key: hits

My email looks like this:

Subject: Hacker News mention of <phrase>




3. RSS -> Buffer

Outcome: When new jobs are posted in Resumator (our applicant tracking system), they are tweeted out on our jobs-specific Twitter feed, @knewton_jobs.

How: Resumator provides an XML feed. A web developer on my team built a simple script that translates it into a proper RSS feed. Zapier then posts new entries to Buffer, which sends the tweets.

Pretty straightforward. There are two delays: (1) Resumator only updates their XML feed once/day, (2) Buffer by nature won’t post things immediately. The Buffer delay is helpful because we don’t know exactly when Resumator will update its feed and we want tweets to go out when people are likely to see them (e.g., weekday mornings).

4. Gmail -> HipChat

Outcome: when someone (especially our security team) sends a critical email, they can include a keyword in the subject line will automatically blast a notification to everyone in chat.

How: We use Hubot, and the account has its own email address. We use that address for this Zap. First, we make sure it’s a member of any groups that are likely to need this email relayed to chat, such as all of the tech organization or the entire company.

Next, we create a Zap for every particular list mapped to a specific HipChat room. Here are the Zap’s Gmail rules:
Mailbox/tag name: INBOX
Search String: list:<group email address> (subject:”Broadcast” OR subject:”Outage” OR subject:”Alert”)

HipChat rules:
Room: <room of choice>
From: {{from_name}}
Message: @here Email Subject: {{subject}} - {{message_url}}
Notify: yes
Message format: text

(Note: the @here notification does not work if the message is sent in HTML format)

The {{message_url}} is the email’s unique URL in Gmail. Assuming the recipient is logged into the relevant Gmail account, clicking the link should open up the email directly.

If that turns out to be buggy because people are logged into multiple Gmail accounts, you can instead provide a link to a Gmail search of the message’s ID (the last part of message_url), which will return results showing only the matching message.

5. Web Hook router (Web Hook -> Web Hook -> many HipChat rooms)

Outcome: Notifications from our custom build system are filtered for matching rules and send to various HipChat rooms with color coding for success or failure. By doing it in Zapier we were able to test the idea, deploy, and validate, to the point where additional teams have started asking for them.

How: I created two Web Hook -> HipChat Zaps for every type of alert that needed to get sent, one for success messages (green HipChat background), one for failures (red background).

Each Zap filters for the message it needs (any necessary environment/stack restrictions plus a success message or lack thereof) and fires its notification.

Unfortunately, each Zap automatically assigns its own Web Hook as the starting point. Rather than have the developer keep adding a new endpoint for every new Zap I whip up, I created a Web Hook -> Web Hook Zap that acts like a router. The developer wired up the first POST endpoint. The second part of that “router” Zap relays the POSt message to _every other subsequent Zap_ I create.

So whereas a single Zapier Web Hook looks like this:

You can hit many of that once like this:,asfjaf8,af89awf,asdf89/
Payload Type: form

(Those are all fake values. Don’t hit them!)

Making the Song: Layers of the Earth

I first drafted notes for this blog post about 5 years ago but shelved it because we were too busy doing other things. Recently I stumbled upon those notes and am excited to finally document some of the fun work that went into making this educational rap song.

Layers of the Earth by educationalrap

Most songs Ben and I produced for Rhythm, Rhyme, Results — the educational rap company we started in Cambridge, MA — were collaborations that involved a network of contributors scattered across the country. Ben usually led the creative side, either writing lyrics himself or at least editing them, while I focused on “business stuff” but sometimes joined the creative fun and managed production once Ben started law school.

This song was a great example of our typical collaboration style and went something like this:

  1. Our summer intern researched the topic and sketched the outline


  2. We bought the instrumental from a producer in Atlanta, a Berklee College of Music graduate we met because she responded to our first Craigslist ad

  3. I edited the outline and assigned lyric writing to a talented guy in Brooklyn, who also sent back an audio demo

  4. I edited his lyric, recorded another audio demo, and sent to Ben, who was at this point getting his JD/MBA at Stanford. Note: you’ll understand why I kept myself in the producer’s chair most of the time.

  5. Ben edited the lyric and send accompanying notes, including emails like:

    "throw your hands up for your turf" plays well in kettering, but if this ever gets to a place with actual gang activity, that quickly becomes a volatile lyric.

    throw your hands up for the layers of the earth
    throw your hands up for what’s below the surf(ace)
    throw your hands up cuz we’re gonna discuss
    the inner core, outer core, mantle, and crust

    "the heat will make you sick"… no it won’t, it will f***king kill you. how about "the heat will burn you up"? i don’t think the "trip"/"sick" rhyme was worth it anyway.

    9 to 4000 degrees sounds like a range of 3991 degrees. i think we at least want to go with 4-9000 and hope they can figure out we mean 4000.

    "awesome" might be a better adjective than "rotten"… if "bottom" can be pronounced so that the first vowel is the same as the first vowel in "awesome" it will be a more convincing rhyme.

  6. I sent the lyric and audio demo to a singer/songwriter (now a lawyer) from Miami whom Ben performed with as an undergraduate at Harvard
  7. He sent back his own audio demo, which blew us away. He created it with GarageBand and his laptop’s built-in mic.

  8. We recorded everything with a producer in his studio in Arlington, MA. (The producer is now a professional composer in Los Angeles, where he makes songs for movies and commercials like this, this, and this).
  9. We mastered at M-Works in Cambridge.

And there you have it.

You can hear Layers of the Earth and more science songs in the Science Collection, which also racked up a Parents’ Choice Award. When you buy a song from the site you get the full track in four versions (regular, slowed down, missing vocabulary words, and instrumental), plus worksheets for students that include an answer key for teachers.

What is a junior marketing associate?

A few years ago I discovered something that seemed bizarre: marketing degree programs at well-known universities don’t teach online marketing, especially startup marketing. At the time I was interviewing recent graduates for a junior marketing role and discovered they had basically no idea what they were doing.

The person I eventually hired had studied the 4 Ps and learned about brand management but had never edited a website, looked at Google Analytics, paid for traffic, written original content for the web, or even used Excel.

In the last few years I’ve continued to look back and wonder what would make the ideal junior marketer. What does a company require of a graduate? What can a college student do to prepare for a job in online marketing, especially at a startup?

My guidelines

My general rule for a team member: you must be able to write, design, or code. If you are not designing or coding, you must be a first-class writer.

Why? Because I want to spend my time helping someone become a better marketer, and I can’t do that if I’m spending my time correcting everyday writing.

Prerequisites (before applying for a job)

There are some more things I would rather not teach someone. These are prerequisites.

  • What is the internet, what is a host/server, what is a web page?

Bonus points if you’re familiar with HTML and CSS. Tumblr and GA are free: if you’re really excited to work in marketing, why haven’t you tried it, yet?

  • SEO and SEM are different

Otherwise, this tells me this you don’t understand the Google search results page (SERP), and because you think all results are either the result of money or meta keywords, you don’t think things through very well. Yes, I could clarify in two seconds, but I shouldn’t have to.

  • How to use Excel (my go-to requirements: comfortable with pivot tables and vlookup)

Can you import messy data, clean it up, rearrange it, and analyze it? Can you create a model that lets you repeat this later with minimal effort?

  • How to articulate what you are hearing and thinking

What are our assumptions? What are we testing? What does success look like in a particular situation?

  • Good writing: grammar, spelling, minimal fluff. Strunk & White.

Marketing is about communication. Be good at the most basic form.

  • A sincere interest in getting people to want what you have

Too often people apply for marketing positions and talk about working on “strategy”. That sounds like lazy thinking to me. I need to trust that you will be excited in the weeds, where we spend a lot of time. Strategy is cool, and we’ll talk about it, but that’s not really what being a junior marketer is about.

  • A comfort with learning new tools

I get a little nervous when a resume lists out every analytics and social media tool the person has used. Learning new tools comes with the territory—it’s not an accomplishment and rarely worth listing.

What you’ll learn (after you’re hired)

Anyone can learn how to market. I (or any competent marketing lead) will mentor on things like:

  • How to work backward from company goals to marketing goals
  • How to think broadly about acquisition/engagement/retention
  • How to find traffic
  • How to attract traffic, both paid and organic
  • How to determine whether a click/ad/campaign/service is a good investment
  • How to write and design using best practices
  • How to build a funnel
  • How to write simple copy designed to move through a funnel
  • How to convert
  • How to A/B test
  • How to email
  • How to track everything you’re doing
  • How to report on what you’re doing
  • How to make decisions on what you’re seeing in reports

Assessing an individual’s progress

We measure progress down the generalist marketing path by anchoring discussions on eight functional areas:

  • Understands, articulates, and advocates for the company brand
  • Understands the market/space in which they are marketing and uses good judgment in delivering optimal materials
  • Thinks rigorously through all steps of a marketing funnel or campaign and connects the dots between components
  • Correctly collects, analyzes, and synthesizes data to provide insight and direction for the company’s marketing
  • Works independently and effectively in a fast-paced, agile marketing environment
  • Effectively balances creativity and constraints in driving projects to completion
  • Leverages the right tools, services, and people to be as effective as possible
  • Helps the company to achieve its goals faster by identifying opportunities for change and process improvements, generating solution options, and executing when appropriate

I’m curious how others think about hiring and mentoring junior marketers. What do you look for? How do you coach and mentor?

The online marketing tools starter kit

If I were building a marketing operation from scratch today, here’s what I’d use to run mission control. This technology setup is not free and assumes the business is ready to invest in marketing in order to generate revenue.

  • WordPress for website and blogging
  • WP Engine for hosting WordPress
  • HubSpot for all-around marketing toolkit and automation, including email, landing pages, and analytics
  • Wistia for video hosting, embeds, and analytics
  • Optimizely for A/B testing on WordPress pages
  • Google Analyics because duh
  • 3Q Digital for online ad operations (SEM/display)
  • Formstack for misc. forms outside HubSpot
  • Zapier for stitching services together
  • Leftronic for building dashboards for big screens in the office
  • Printfection for all merch (e.g., t-shirts)

What am I missing?

So you want to contact a startup?

At a startup—or any small company, really—dealing with the outside world is hard.

If you are not a customer (current or prospective) or a PR opportunity, startups often have no use for your email or phone call, and in that chronically understaff world, there’s likely no one assigned to “the public”. If you’re lucky, they have assigned an office manager or their customer support group to field incoming traffic. If not, you might be reaching a managerie of PR/BD/sales/marketing folks.

At some one point or another I’ve been privy to almost all our incoming traffic, including email, phone, chat, and social media. Due to my role, my personality, and my tenure with the company, I have a good sense for how to reply directly, where to forward various audiences, which are OK to ignore, and which deserve a snarky response.

Here’s my advice for specific groups trying to reach a startup.


  • First, email the company through the provided address or form
  • If necessary and possible, call the company
  • Tweet at them

Note: Twitter can be good for getting attention, but it also could also mean relying on the social media folks to get your info over to support, and also means you won’t actually have a ticket, which can actually drag out resolution. (Yes, some companies use something like and choose to monitor tweets as tickets, but it’s an exception to the norm.)

Prospective Customers

  • Take five minutes and read the actual text on the website. You’d be surprised how much time has gone into answering your questions.
  • B2B: Submit whatever marketing/sales form is provided. This will route you to someone whose purpose in life is to contact you.
  • B2C: Email your questions to support. They have better ticketing than a general inbox and are already equipped to answer product questions, even though it’s not really their job to sell you.


  • Send an actual, well-formed question which you will use to make a purchase decision, not something like “Tell me about your product, thanks.”
  • If you submit info and a B2B company does not get back to you, it might be because you’re not a good fit for the product (yet). There are many reasons this might be the case.


In order:

  • Email a company executive directly with an interview request
  • Email a press inbox
  • Call a press inbox
  • Email a general inbox

Job Applicants

If possible, and in order:

  • Contact someone you know and have them refer you directly to the hiring manager and (if applicable) recruiting lead for the position
  • Apply for the job

We’re organized enough to handle applications as is. But if you’re feeling antsy and need to follow up, I suggest you:

  • Follow up directly with the recruiting lead or team
  • Follow up directly with the hiring manager
  • Follow up directly with the department head


  • Email the company’s general inbox asking for a response
  • Email the company’s general inbox asking to have coffee with someone to learn more about the company/position
  • Ain’t nobody got time for that.

Salespeople / Cold Calls

In general, you’re wasting your time. But if you must hit your rolodex, email someone directly, particularly the person likely to make a purchase decision.

I’m amazed how many salespeople skip their own research and email our general inbox expecting us to forward their pitch email to the right person.


  • Email the press inbox (immediate blacklist)
  • Email multiple general inboxes (ditto)
  • Email the same thing to 10 people (it’s a startup: we sit next to each other, we talk, we roll our eyes at you)
  • Try to connect with someone on LinkedIn out of the blue
  • Call the company

Do you know why you don’t call a startup to sell something? Because most people at startups don’t use company phones—they email, chat, and tap each other on the shoulder, or use their own cell phones. I only use my VoIP phone to dial out; the only people who call me at work are salespeople, so I literally never answer the phone.

"Buy my company or technology" Pitches

Unless you know someone at the company and contact him/her directly, it’s a total waste of time. Even if you do have something interesting, the company can’t risk the chance that you’re a patent troll lining up a lawsuit.

Recruiters Pitching Services or Applicants

  • Contact our recruiters directly (if you’re good at your job, you’ll figure out how)
  • Anything sent to a general inbox is deleted

If I’ve forgotten something, tweet me @superstrong

WordPress local development using WP Stack

I’ve been working with a local development extension of WP Stack for a couple months at Knewton, and this now my workflow. I can usually develop in local master, but when needed I’ll work in a local development branch first.

My point is, it’s much simpler to do this than it used to be—so easy a marketing guy can do it. I don’t know of many places where the marketing team has developed this level of self-sufficiency.


  • Open iTerm2

    The dev guys told me this is better than Terminal. I use these three panes to manage my stuff. They use like 12.

  • cd projects/marketing-deploy/vagrant/
    • "marketing-deploy" is a private repo (hosted on Github) that handles all our deployment configuration
    • "vagrant" is Vagrant, which handles virtualized development. I’m basically running a second computer on my computer.
    • "" is a copy of our WordPress-based site, including database and server configs
  • git pull

    Fetch and merge from the repo’s origin (Github)

  • vagrant up

    Boot up the Vagrant virtualization

  • vagrant knewton:sync

    Sync the database from production to local

  • vagrant knewton:localdev on

    Change my hosts file to point to my local version

  • Do some work
  • vagrant knewton:localdev off

    Revert hosts file

  • vagrant suspend

    Shut down the Vagrant virtualization


  • ssh to the admin box

    The admin box is a separate instance hosted on AWS that handles deployment, rollback, restarting nginx/memcached/etc., and more with single-line commands

  • switch to the deploy user
  • cap deploy

Parse’s Cloud Code is the Hotness

A few months ago, my gf (a product manager) was excited about a mobile feature she wanted to build into her company’s iPhone app: a new sorting feature that used a ton of data from different tables in the db. She couldn’t do it, unfortunately, because her mobile team operated independently from the API team, each of which had their own roadmaps, timelines, and managers.

The API team would not create a new call to provide the calculated data, and the app couldn’t do it because the client would have to download a ton of data from the db just to crunch it and display the result. (The API team there operated oddly, creating excruciatingly client- and feature-specific calls rather than exposing data more generally and enabling clients to combine calls.)

My suggestion was that they instead have the API team expose some data generally, then build an interim API layer that could make the call to the existing API and cache the results, then provide an endpoint to the mobile clients.

Turns out Parse is doing just that. Parse just released “Cloud Code”:

Cloud Code makes Parse a one-stop shop for mobile app development by pushing the boundaries of server code. You can now add custom validations and endpoints that are instantly and easily accessible by any client, whether it’s iOS, Android, HTML5, or via the REST API. You get all of the power of the Javascript SDK running on the Parse cloud.

For example, if you were building a restaurant review app, you’d probably want to display the average star rating for a venue. Instead of grabbing all the reviews and averaging them on the client, you could specify a custom endpoint.

[sample code]

All your clients would immediately have this functionality available to them. Furthermore, if you wanted to use a more sophisticated averaging algorithm, you would be able to alter it without having to update any code in the client.

There are analogous services in the marketing world, where marketers need the ability to create landing pages, add tracking code, A/B test images, send emails, etc. without dragging developers through their manic experiments. Tools like HubSpot, Marketo, Test & Target, and more charge thousands per month to provide this independence.

Similarly, Cloud Code seems like a great way for front-end teams to operate more independently, developing experiments and features for their mobile clients without bothering the API team, which sometimes (usually?) operates on an independent roadmap, or at least its own timeline.

This sounds big.