How we use Google Sheets to manage email production

Generated with Speechify Studio


Hello Reforge team. A quick note: I’m playing around with an AI voice generator to make narrating this video faster!

This is how Calm uses Google Sheets to build and track emails.

I’ve created a simplified version of our sheet specifically for Reforge. In practice, Calm’s sheets have 70 or 80 rows instead of the 28 rows in this example.

At right you can see a basic newsletter. We break up each piece of the newsletter into chunks that we map to blocks of rows on the Google Sheet.

We replicate this google sheet column multiple times to represent different versions. In this example I’ve layed out six email newsletters. It could be 6 months or 6 weeks. whatever your newsletter cadence.

We also use the spreadsheets to manage newsletter translations for different languages.

Each section of the spreadsheet maps to a section of the email. Starting with the hero section on the email mockup, we have a header, a paragraph body,  and a call to action link. Each of those elements has a corresponding line on the spreadsheet.

We also have three sections that look the same. Therefore we have  three corresponding sections on the spreadsheet.

Finally, we finish with the email section on the bottom.

Now that the copy has a defined structure and pattern, we can interpret the email easily programmatically.

I connected the spreadsheet to a Google Apps Script that shows a basic preview of the newsletter to make the email easier to review and check for errors.

Notes on updating User Profile via Iterable webhooks

Iterable journeys have two webhook nodes to choose from so I was trying to figure out which node will make an outbound call to an API, receive data, and then write data back into the User Profile.

The “Journey webhook” node will not write data to the user profile.

  • This is an outbound-only HTTP request.
  • We can use the webhook to tell external certain things about the user that Iterable knows. But the webhook itself is fire-and-forget.

We are forced to use the “User Profile update” node

  • Iterable automatically stuffs a ?email=<email address> parameter on every request (security prob?)
  • This node allows for an Authorization header.
    • Screenshot shows Authorization: abcdefg
    • We can do Authorization: Bearer <token> to do basic auth instead of authorization token?

Example request header from User Profile update via webhook

GET /?email=exampleemail@foobar.com HTTP/1.1
Host: <HOST>
User-Agent: AHC/2.1
Accept: */*
Authorization: <STRING>
X-Forwarded-For: <IP ADDRESS>
X-Forwarded-Host: <HOST>
X-Forwarded-Proto: https
Accept-Encoding: gzip

A thoughtful UX Teardown on my work

Calm was the subject of a email UX teardown recently which was well-written and had several interesting insights. The obvious first reaction to this post was “oh no, we’re horrible” but the reality is she articulates several weaknesses that the team has been aware of.


We missed an opportunity for personalization

Complaint – She was a happy user churning out of the product. When she churned we hit her with a generic urgent messaging that others recognized not to be soothing. Why are we talking to her like a beginner?

What is the root of the complaint? We don’t distinguish “happy churn” from other types of churn. (Note to self: what are the other types of churn?) Our churned-user experience is certainly under-appreciated.

This user has multiple email addresses: a paid subscription email and a trial churned email. Presumably she used the trial churn email to conduct her research.

The paid subscription email address was unsubscribed from marketing emails. She received transactional emails only. This underlines that we should sneak in some more light marketing into our transactional emails.

What technology do we need to solve this? Lots of people have multiple email addresses. It’s not a technical issue. However we could benefit from having consistent time-based email cadence (use as a default) augmented by an event-based cadence when users are well engaged.

Is there a barrier to fixing it? No barriers. We have the capability to look at the user’s engagement within the last several months or weeks to separate out an engaged user from unengaged users — at all times!


Inconsistent email cadence

Complaint – she experienced an email dead zone where she didn’t see anything messaging from us for weeks (months?)

What is the root of the complaint? There was a dead zone for several weeks after churn from trial. She eventually got enrolled into a monthly email but monthly may not be enough frequency to maintain engagement.

What technology do we need to solve this? Increase production

Is there a barrier to fixing it? Emails are too difficult to specify right now.


Off-brand copywriting

Complaint – The author and several LinkedIn commenters perceived the emails to be aggressive and ironically not “calming”

What is the root of the complaint? She received several sale-oriented headlines during a large revenue-producing campaign.

What technology do we need to solve this? No new technology necessary to write copy. Slow down and work cross-functionally to capture critique from marketing & content teams to get on the same page for user-facing communication.

Is there a barrier to fixing it? We are not trained copywriters. However, we can learn to write in an on-brand voice. That is a marketable skill that can be augmented with AI.

Referring back to the personalization problem, we could come up with alternate subject lines for well-engaged users who do not need urgency-oriented messaging.

Big-time copy-writing failure!

I had to add a disclaimer block to some messaging so that users don’t mistakenly look for coupons on Apple or Android.

I suspect this line of text caused some of the drop.

“This discount is valid only for subscriptions purchased through [domain name]. Offer not valid for subscriptions purchased in the Apple Store or Google Play Store.”

Notes from Iterable Activate 2022 in San Francisco

I attended Activate in San Francisco held at the Marriott Marquis. It was a fine time. I gravitated toward high-level strategic talks in-person. I take a look

Most insightful talk: Women Language + Power and Standard Communication by Susannah Baldwin

When I walked into the room vaguely labeled “professional development” session I was late so I hurriedly took a seat at the side of the room. After I got settled and composed I realized I was one of two men in a room of one hundred women. Ooops! I felt way out of place but I stayed in the room and happy I’m happy I did.

The speaker’s point was that women are taught at an early age to speak in a soft or indirect manner. To reach the upper echelons of But that’s not

Many Useful takeaways : Find Your Target: Reaching Different Personality Types Without Flooding Your Marketing Channels by Tim Hemingway, Havas Media

Broadening my horizons: Presenting with Impact by Susannah Baldwin

Reforge notes: Retention & Engagement

Rough notes while I go through the Reforge Summer 2022 program on Retention & Engagement.

4 Strategies to increase ENGAGEMENT

  1. Add Use Cases
    1. Uber
      1. start with going to airport
      2. add going out with friends
      3. add commuting to work
    2. JIRA
      1. start with bug tracking
      2. add product releases
      3. add project management
    3. Calm
      1. listen to sleep stories
      2. add journaling
      3. add coaching
  2. Increase usage frequency
    1. Metric is weekly active user (all are weekly actives)
      1. 1x/week
      2. 4x/week
      3. multiple times/day?
  3. Increase feature usage
    1. Expand breadth of features does individual use.
      1. User 1: Sleep stories & music
      2. User 2: music & Daily Calm & Journal
  4. Increase intensity of usage
    1. amount of time per use? (listen to Calm music 5hrs/session)
    2. $ spent
    3. # actions per use (?)

Add Use Cases

In what ways can we expand the number of uses for subscription apps that I am trying to improve?

Calm use cases

  1. Bed time
  2. Focus during work/study
  3. Leisure during commute
  4. Consistent daily mindful practice (advanced)
  5. (expand to) measuring personal growth?
  6. (expand to) handling anxiety in-the-moment

TTS Inc. use cases

  1. Leisure reading fiction
  2. Reading textbooks
  3. Reading work documents
  4. Proof-reading, editing, review
  5. (expand to) studying, taking notes on subjects.
  6. (expand to)

Black Friday 2021 notes

I identified a profitable segment combining app usage and sales data from the previous year

I found a particularly profitable segment of users by looking cross-referencing app usage and purchase behavior. For the Black Friday 2020 campaign we sold far more high ticket items to people who had used the app for 12 consecutive months (the size of the circles represent # plans purchased). It helped us send our most active users our best deal. (High price but high discount)

Bigger circle = more sales. X-axis is consecutive months of activity.

Spreadsheet command center

To keep track of the 60 campaigns I built out a spreadsheet to track the different offers and email template modules to include in the campaign. Different segments received personalized offers (pictured) based on analysis from our Data Science team that found the optimal offer according revenue per email sent.

Each cohort, the day of the campaign, and the sales modules to be offered to the recipients

Landing page switch led to 40% conversion improvement

Toward the end of the campaign I created an A-B test for the email click’s landing page.

You should notice that the original page is a very simple credit card page. Because we were advertising a Black Friday time-limited sale our logic was to collect payment as quickly as possible.

You will notice that Treatment version has a lot more information. It has a big hero image, some science facts, a product comparison checklist in the middle, and testimonials on the bottom. Our product & engineering team had refined and tested this landing page for peak performance earlier in the year but we had never tested these two variants against each other within the context of a holiday sale.

The A-B test showed 50%+ sales conversion improvement over the 3-day observation period for the campaign. I wished I had tested these two landing pages earlier in the campaign!

I believe that part of the reason the page performed so much better is that we only sent this page to users who never subscribed before. These people barely know what Calm is so I believe that having the extra information on the page properly educated the returning inactive users and clearly did a better job at explaining the value of the Black Friday deal that we were offering them.

Next year I’ll be sure to compare the two variants across broader audience (churned, current paid, etc.)

Original
Treatment

Treatment landing page (green line) outperformed for duration of the sale
52% improvement & statistically significant

Iterable recipe: inject data from a custom event into userProfile for email template

An email I’ve been working on needs to refer back to information from a previous event.

... TEMPLATE ...

Hi {{firstName}}, 

Thank you for watching {{title of movie I watched}}!

... RENDERED ...

Hi Jeff, 

Thank you for watching STRANGER THINGS!

The problem here is that the I wanted to reference the title of a video that was watched in the past within a blast email. This is not possible without saving the information somewhere in Iterable. In my case I decided to store the data on the user’s profile.

To save data from an event onto the user profile I use a workflow and the Change Contact Field node.

The event data might look like this:

{
    "eventName": "Video : Watched",
    "eventType": "customEvent",
    "email": "<EMAIL_ADDRESS>",
    "dataFields": {
        "video_title": "Stranger Things",
    }
}
  1. Create workflow
  2. Add node “change contact field”
  3. In the CHANGE CONTACT FIELD node define the data I want to save in JSON format.
{"video_title":"{{video_title}}"}
## (You should use better field names than this) ##

Now when the event comes through Iterable will replace the template variable with the new value on the user profile and thus making it accessible on any email template.

Here I can put the saved_program_title into the subject line or email template body using the Handlebars.