Script 141: New Campaigns Pause Low ROAS

Purpose

The script pauses new Google ad campaigns with low Return on Advertising Spend (ROAS) based on predefined criteria.

To Elaborate

The Python script is designed to manage Google ad campaigns by pausing those that are new and have a low Return on Advertising Spend (ROAS). It evaluates campaigns over the previous 30 days, considering their maturity level and specific ROAS thresholds. The script uses a set of criteria to determine which campaigns should be paused, ensuring that only those with ROAS below certain levels are affected. This helps in optimizing advertising budgets by halting underperforming campaigns, thereby allowing for better allocation of resources to more successful campaigns. The script is particularly useful for advertisers who want to automate the process of managing campaign performance based on ROAS metrics.

Walking Through the Code

  1. Define Pause Criteria
    • The script begins by defining criteria for pausing campaigns. Each criterion includes a campaign maturity level and a range for ROAS. Campaigns that fall within these ranges are candidates for being paused.
  2. Initialize Temporary Status Column
    • A temporary column is created in the input DataFrame to store the new status of campaigns. This column is initially set to empty.
  3. Apply Pause Criteria
    • The script iterates over each set of pause criteria. For each criterion, it checks campaigns that match the maturity level and have a ROAS within the specified range. If these conditions are met, the campaign’s status is updated to ‘Paused’.
  4. Identify and Process Changed Campaigns
    • After applying the criteria, the script identifies campaigns whose status has changed. If there are any changes, it creates an output DataFrame containing only the campaigns with updated statuses. This DataFrame is prepared for further processing or reporting.
  5. Output Results
    • If no campaigns meet the criteria for status change, an empty DataFrame is created. Otherwise, the output DataFrame is populated with the relevant campaign details, ready for further action.

Vitals

  • Script ID : 141
  • Client ID / Customer ID: 1306925431 / 60269477
  • Action Type: Bulk Upload (Preview)
  • Item Changed: Campaign
  • Output Columns: Account, Campaign, Status, Script Paused
  • Linked Datasource: M1 Report
  • Reference Datasource: None
  • Owner: Michael Huang (mhuang@marinsoftware.com)
  • Created by Michael Huang on 2023-05-25 20:20
  • Last Updated by alejandro@rainmakeradventures.com on 2024-01-26 18:55
> See it in Action

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#
# Pause Low ROAS New Campaigns
#
#
# Author: Michael S. Huang
# Date: 2023-05-26
#


# define campaign LOW ROAS PAUSE criteria
# note: MIN values are inclusive; MAX values are non-inclusive
campaign_pause_criteria = [
    # format:
    #  (min spend, max spend, min roas, max roas),
    ('New - Launch', 0, .4),
    ('New - Round 2', 0, .2999),
    ('New - Round 3', 0, .5),
    ('New - Round 4', 0, .5),
    ('New - Round 5', 0, .5)
]

# define column parameters
RPT_COL_CAMPAIGN = 'Campaign'
RPT_COL_ACCOUNT = 'Account'
RPT_COL_STRATEGY = 'Strategy'
RPT_COL_CAMPAIGN_STATUS = 'Campaign Status'
RPT_COL_CAMP_MATURITY = 'Campaign Maturity'
RPT_COL_ROAS = 'CLICKS ROAS'
RPT_COL_PUBLISHER_TARGETCPA = 'Publisher Target CPA'
RPT_COL_DAILY_BUDGET = 'Daily Budget'
BULK_COL_ACCOUNT = 'Account'
BULK_COL_CAMPAIGN = 'Campaign'
BULK_COL_STATUS = 'Status'
BULK_COL_SCRIPT_PAUSED = 'Script Paused'

VAL_STATUS_PAUSED = 'Paused'


# create temp column to store new status and default to empty
TMP_STATUS = RPT_COL_CAMPAIGN_STATUS + '_'
inputDf[TMP_STATUS] = np.nan


# loop through each PAUSE criteria and apply
for (new_round, min_roas, max_roas) in campaign_pause_criteria:
	print(f"Applying pause criteria: new round={new_round}, min roas={min_roas}, max roas={max_roas}")

	inputDf.loc[ (inputDf[RPT_COL_CAMP_MATURITY] == new_round) & \
				 (inputDf[RPT_COL_ROAS] >= min_roas) & \
				 (inputDf[RPT_COL_ROAS] < max_roas) & \
                 (inputDf[RPT_COL_ACCOUNT] == 'ExplorAds Google'), \
				 TMP_STATUS \
			   ] = VAL_STATUS_PAUSED

# find changed campaigns
changed = inputDf[TMP_STATUS].notnull() & (inputDf[RPT_COL_CAMPAIGN_STATUS] != inputDf[TMP_STATUS])

if sum(changed) > 0:

    print("== Campaigns with Changed Status ==", tableize(inputDf.loc[changed]))

    # only select changed rows
    cols = [RPT_COL_ACCOUNT, RPT_COL_CAMPAIGN, TMP_STATUS]
    outputDf = inputDf.loc[ changed, cols ].copy() \
                    .rename(columns = { \
                        TMP_STATUS: BULK_COL_STATUS \
                    })

    outputDf[BULK_COL_SCRIPT_PAUSED] = datetime.datetime.now(CLIENT_TIMEZONE).date()
    
    print("outputDf", tableize(outputDf))
    
else:
    
  print("Empty outputDf")
  outputDf = pd.DataFrame(columns=[BULK_COL_ACCOUNT, BULK_COL_CAMPAIGN, BULK_COL_STATUS, BULK_COL_SCRIPT_PAUSED])

Post generated on 2024-11-27 06:58:46 GMT

comments powered by Disqus