Nicholas Saunders
Nicholas Saunders

Reputation: 764

How to query for a list of all Mailchimp campaigns using Python?

There are campaigns; however, none of them are being returned from this sample script:

nicholas@mordor:~/python$ 
nicholas@mordor:~/python$ python3 chimp.py 
key          jfkdljfkl_key
user         fdjkslafjs_user
password     dkljfdkl_pword
server       fjkdls_server
nicholas@mordor:~/python$ 
nicholas@mordor:~/python$ cat chimp.py 
import os
from mailchimp3 import MailChimp

key=(os.environ['chimp_key'])
user=(os.environ['chimp_user'])
password=(os.environ['chimp_password'])
server=(os.environ['chimp_server'])

print ("key\t\t", key)
print ("user\t\t", user)
print ("password\t", password)
print ("server\t\t", server)


client = MailChimp(mc_api=key, mc_user=user)
client.lists.all(get_all=True, fields="lists.name,lists.id")
client.campaigns.all(get_all=True)


nicholas@mordor:~/python$ 

do I need to send additional information to get back a list of campaigns? Just looking to log some basic responses from Mailchimp.

(obviously, I've not posted my API key, nor other other sensitive info.)

Upvotes: 0

Views: 573

Answers (1)

Nikhil Gupta
Nikhil Gupta

Reputation: 1486

This is what I use and works for me. Just call the get_all_campaigns function with the MailChimp client. I added n_days for my specific needs, but you can choose to delete that part of the code if you do not need it. You can also customize the renames and drop columns as per your needs.

from typing import Optional, Union, List, Tuple
from datetime import timedelta, date
import pandas as pd  # type: ignore
from mailchimp3 import MailChimp # type: ignore


default_campaign_fields = [
    'id',
    'send_time',
    'emails_sent',
    'recipients.recipient_count',
    'settings.title',
    'settings.from_name',
    'settings.reply_to',
    'report_summary'
]

def get_campaigns(client: MailChimp, n_days: int = 7, fields: Optional[Union[str, List[str]]] = None) -> pd.DataFrame:
    """
    Gets the statistics for all sent campaigns in the last 'n_days' 
    
    client: (Required) MailChimp client object

    n_days: (int) Get campaigns for the last n_days

    fields: Specific fields to return. Default is None which gets some predefined columns.
    """
    keyword = 'campaigns'

    if fields is None:
        fields = default_campaign_fields  
    
    # If it is a string (single field), convert to List so that join operation works properly
    if isinstance(fields, str):
        fields = [fields]

    fields = [keyword + '.' + field for field in fields]
    fields = ",".join(fields)

    now = date.today()
    last_ndays = now - timedelta(days=n_days)
    
    rvDataFrame = pd.json_normalize(
        client.campaigns.all(
            get_all=True,
            since_send_time=last_ndays,
            fields=fields).get(keyword))
    if 'send_time' in rvDataFrame.columns:
        rvDataFrame.sort_values('send_time', ascending=False, inplace=True)
    
    mapper = {
        "id": "ID",
        "emails_sent": "Emails Sent",
        "settings.title": "Campaign Name",
        "settings.from_name": "From",
        "settings.reply_to": "Email",
        "report_summary.unique_opens": "Opens",
        "report_summary.open_rate": "Open Rate (%)",
        "report_summary.subscriber_clicks": "Unique Clicks",
        "report_summary.click_rate": "Click Rate (%)"
    }
    
    drops = [
        "recipients.recipient_count",
        "report_summary.opens", 
        "report_summary.clicks",
        "report_summary.ecommerce.total_orders",
        "report_summary.ecommerce.total_spent",
        "report_summary.ecommerce.total_revenue"]

    rvDataFrame.drop(columns=drops, inplace=True)
    rvDataFrame.rename(columns=mapper, inplace=True)

    rvDataFrame.loc[:,"Open Rate (%)"] = round(rvDataFrame.loc[:,"Open Rate (%)"]*100,2)
    rvDataFrame.loc[:,"Click Rate (%)"] = round(rvDataFrame.loc[:,"Click Rate (%)"]*100,2)

    return rvDataFrame

Upvotes: 1

Related Questions