My morning routine usually start with, "Hey Siri, how is the weather today?". Now with Shortcuts, it's possible to teach Siri new tricks. How about, "Hey Siri, how is my MailChimp doing?".

This is going to be a 3 part effort:

  1. Gather MailChimp status via API and summarize it into human readable text
  2. Wrap the code from step 1 into a mimi server
  3. Construct Siri Shortcut to read out the status
If this is your first time working with MailChimp API, please consider reading the introductory post: Getting Started with MailChimp API

Getting the API Key

Before we start, let's get the access token, also known as API key, of your MailChimp account.

Authorize with MailChimp

Summarize MailChimp Status

MailChimp API provides a running total of your daily stats under list/activity. See documentation here. Let's write a quick script to see it in action.


const MailChimp = require('mailchimp-api-v3')
const api = new MailChimp(process.env.MAILCHIMP_API_KEY)

const listResult = await mailchimp.get("/lists")
for (let list of listResult.lists) {
    // Fetch list activity
    const activityResult = await mailchimp.get(`/lists/${list.id}/activity`)
    console.log(activityResult)
}

It helps to run the script above, expand the data returned. Next we will construct function summarizeListStats to transform the stats into more human friendly forms.


const isYesterday = require('date-fns/is_yesterday')
const Mailchimp = require("mailchimp-api-v3")
const mailchimp = new Mailchimp(process.env.MAILCHIMP_API_KEY);

const listResult = await mailchimp.get("/lists")
let report = ""
for (let list of listResult.lists) {
    // Fetch list activity
    const activityResult = await mailchimp.get(`/lists/${list.id}/activity`)
    report += summarizeListStats(list, activityResult)
}

function summarizeListStats({ name }, { activity }) {
    // Only use yesterday's stats
    const [yesterday] = activity.filter(stat => isYesterday(stat.day))
    if (!yesterday) return ""

    const summary = [`Yesterday, list ${name}:`]

    // Summarize sent data
    if (yesterday.emails_sent) {
        const openRate = Math.round(yesterday.unique_opens / yesterday.emails_sent * 100)
        const clickRate = Math.round(yesterday.recipient_clicks / yesterday.emails_sent * 100)
        const bounceRate = Math.round((yesterday.hard_bounce + yesterday.soft_bounce) / yesterday.emails_sent * 100)
        summary.push(`sent ${yesterday.emails_sent} emails with ${openRate}% open, ${clickRate}% click through, and ${bounceRate}% bounced.`)
    }

    // Summarize sub/unsub data
    if (yesterday.subs) {
        summary.push(`added ${yesterday.subs} new subscribers.`)
    }
    if (yesterday.unsubs) {
        summary.push(`${yesterday.unsubs} unsubcribed.`)
    }
    
    // Concatenate report strings. Return empty if there's nothing eventful.
    return summary.length > 1 ? summary.join(" ") : ""
}

report = report || "Nothing to report."

The activity API returns an array of up to 10 days of activity data. In this example we are only interested in yesterday's stats. So the first thing is to filter out stats that's not from yesterday (Line 15). In addition we want to do a few calculations to turn absolute stat numbers into percentage. e.g. recipient_clicks / emails_sent to get click through rate (Line 22 - 24).

Summary in Mini Server

We have the summary, but to make it useful for Siri Shortcuts, it needs to be wrapped in a mini web server.


const isYesterday = require('date-fns/is_yesterday')
const Mailchimp = require("mailchimp-api-v3")
const mailchimp = new Mailchimp(process.env.MAILCHIMP_API_KEY);

const listResult = await mailchimp.get("/lists")
let report = ""
for (let list of listResult.lists) {
    // Fetch list activity
    const activityResult = await mailchimp.get(`/lists/${list.id}/activity`)
    report += summarizeListStats(list, activityResult)
}

function summarizeListStats({ name }, { activity }) {
    // Only use yesterday's stats
    const [yesterday] = activity.filter(stat => isYesterday(stat.day))
    if (!yesterday) return ""

    const summary = [`Yesterday, list ${name}:`]

    // Summarize sent data
    if (yesterday.emails_sent) {
        const openRate = Math.round(yesterday.unique_opens / yesterday.emails_sent * 100)
        const clickRate = Math.round(yesterday.recipient_clicks / yesterday.emails_sent * 100)
        const bounceRate = Math.round((yesterday.hard_bounce + yesterday.soft_bounce) / yesterday.emails_sent * 100)
        summary.push(`sent ${yesterday.emails_sent} emails with ${openRate}% open, ${clickRate}% click through, and ${bounceRate}% bounced.`)
    }

    // Summarize sub/unsub data
    if (yesterday.subs) {
        summary.push(`added ${yesterday.subs} new subscribers.`)
    }
    if (yesterday.unsubs) {
        summary.push(`${yesterday.unsubs} unsubcribed.`)
    }
    
    // Concatenate report strings. Return empty if there's nothing eventful.
    return summary.length > 1 ? summary.join(" ") : ""
}

report = report || "Nothing to report."

const http = require("http")
http.createServer((req, res) => {
    res.end(report)
}).listen(3000)

The only new addtion here is line 42-45, where we wrapped the report string to repond to web requests. You can test it by opening the URL below.

Hey Siri, meet MailChimp!

With our mini server up and running, let's wire up the Shortcut. We will need following nodes: URLGet Contents of URLSpeak. Simply copy and paste URL generated from previous step.

Next open your Shortcut setting and wire up Siri.