Creating time sensitive offers with Adobe Target
Adding urgency to your campaigns can really move-the-needle, if you need convincing - try reading up on the scarcity principle. In this article I'll show you how to test and report on time sensitive offers using Adobe Target. The below example will show you how to create URGENT offers that expire within 30-90 minutes (this can be adjusted). So without further ado lets get to it!
Creating the 1st Profile Attribute
I've named this Profile Attribute; getOfferExpiryHour and here's what the below code is doing:- Checking to see if the visitor has seen the offer before, if so are they in the allowed time-frame? If not they're set to expired and they've missed the promotion, otherwise we let them through.
- The else clause is doing most of the work - here we have a couple of functions that convert the time from 24hr format (probably nicer to use when outputting in our offer) and another that returns am or pm - again used for copy purposes in our offer.
- The rest is related to time - we're using the visitor's time which is based on their system settings. The visitor will have between 30-90 minutes to complete this offer depending on what time they arrive.
// only run this script with the below mbox if (mbox.name == 'YourMboxName') { // has visitor already seen this offer var offerExpiryHour = user.getLocal('offerExpiryHour'); // returning visitor that has seen this offer if(offerExpiryHour) { if (profile.browserTime.getHours() >= user.getLocal('offerExpiryHour24') || profile.browserTime.getDate() != user.getLocal('offerValidDate')) { return "expired"; } else { return offerExpiryHour; } } // vistor's first time seeing the offer else { var hour = null; var seconds = null; // is it AM or PM? - used when outputting copy function amPmDecider(hour) { if (hour == 0 || hour == 1 || hour == 2 || hour == 3 || hour == 4 || hour == 5 || hour == 6 || hour == 7 || hour == 8 || hour == 9 || hour == 10 || hour == 11) { return "am"; } else { return "pm"; } } // convert to non-24hr format function convert24Hr(hour) { switch(hour) { case 13: return 1; case 14: return 2; case 15: return 3; case 16: return 4; case 17: return 5; case 18: return 6; case 19: return 7; case 20: return 8; case 21: return 9; case 22: return 10; case 23: return 11; case 24: return 12; default: return hour; } } // tnt profile variables var currentHour = profile.browserTime.getHours (); var currentMinute = profile.browserTime.getMinutes(); var currentDate = profile.browserTime.getDate (); // round up time - if user visits at 11:59 we don't want offer to expire at 12:00 var d = new Date(1970, 0, 1, currentHour, currentMinute); d.setMinutes (d.getMinutes() + 30); d.setMinutes (0); // add 1 hour var offerExpiryHour = d.getHours() + 1; // store 24hr format for future comparison user.setLocal('offerExpiryHour24', offerExpiryHour); // store date of when user was exposed to offer user.setLocal('offerValidDate', currentDate); var timeSuffix = amPmDecider(offerExpiryHour); var offerExpiryHour = convert24Hr(offerExpiryHour); user.setLocal('offerExpiryHour', offerExpiryHour+timeSuffix); return offerExpiryHour+timeSuffix; } }
Creating the 2nd Profile Attribute
The below Profile Attribute has been named getNumBetween1and2 and is used for identifying whether the visitor has seen the time sensitive experience or the control version - we'll need this later for targeting. I've written about what's going on here in more detail in a previous post.// target script only for this mbox if (mbox.name == 'YourMboxName') { // has the visitor already been exposed to this script? var numBetween1and2 = user.getLocal('numBetween1and2'); // yes they have so no need to re-run if (numBetween1and2) { return numBetween1and2; } // no they haven't so return a number between 1 & 2 else { var x = Math.floor((Math.random()*2)+1); user.setLocal('numBetween1and2', x); return x; } }
Creating the offer
Now with the above Profile Attributes activated we can create our Offer with added urgency. The getOfferExpiryHour Attribute returns the expiry time, so in our offer we need to reference getOfferExpiryHour which looks something like this:<h1>Offer Ends ${user.getOfferExpiryHour} today: save 50% on all iPhones!</h1> <!-- This will look something like this: Offer Ends 5pm today: save 50% on all iPhones! -->
Creating the campaign
Our campaign type needs to be: Landing Page Campaign if it's not then when the visitor returns after the expired period s/he will see the limited time offer again which isn't good. Targeting rules for Landing Page Campaigns are reevaluated whereas the more common A/B aren't.In addition we need to create targeting for the returning Control and (expired) Variant visitors, so we can monitor/compare the performance of those that return once the offer has expired. The returning Control experience is just a copy of the default content while the returning Variant experience would be the full-priced / non-promotion offer.
So in total we have 4 experiences:
- The Control - your default content without the urgent offer.
- Variant - your urgent offer.
- Returning control - returning visitors that had previously seen the Control.
- Returning variant - the offer has expired and these are returning visitors that had previously seen the Variant, we would now show them the full price/ non-offer content.
The variant's targeting is the same other than the getNumBetween1and2 profile attribute is checking for 2 instead of 1.
Final reports
So with your targeting and campaign live you'll end up with reports that look like this:And that's it! I've seen some significant lifts when adding a sense of genuine urgency to offers and hopefully you will too.