1:1 Coupon Assignment
Leverage Simon's Journeys product to allocate coupons 1:1 to users within different variants of a campaign.
This feature leverages our Journeys Node Unique ID functionality. Read through our documentation to understand how it works!
Use Case
The solution outlined below allocates unique coupon codes 1:1 each contact in a segment or variant of a campaign. This is particularly valuable when you have the list of coupon codes that you want to assign out, but the set of contacts to whom you want to distribute them is defined by logic in Simon, making it impossible to allocate them via SQL in our Datasets product.
Note this solution does NOT cover coupon generation -- the assumption is that you have a table of pre-populated coupon codes available in your CDW.
How it works
We allocate coupon codes 1:1 by leveraging our Journeys Node Unique ID feature with Lookup tables. The Journeys Node Unique ID functionality ensures that each contact at each node in a Journey is assigned a unique number, starting at 1 for the first contact entering that node and increasing by 1 for each subsequent contact. At the same time, we can build a Lookup table that takes our table of coupon codes, and uses the ROW_NUMBER function in SQL to assign a unique number to each coupon code, starting with 1 for the first coupon code and increasing by 1 for each subsequent coupon code. By matching those numbers up (i.e. by using the Journey Node Unique ID as the key for your Lookup) you can achieve 1:1 coupon code assignment.
This feature is only available for Journeys.
Example
Lookup table
If we have our coupon codes in a table called coupons
, we can build a Lookup table named coupon_codes
like so:
select
coupon_code, row_number() over (order by random()) as lookup_key
from coupons
This will create a table with 1...N as the values for lookup_key
(with N
being the number of coupons available).
Journey
You can build a journey with as much internal complexity as you'd like. You can leverage branching and experimentation. If you want multiple nodes of your Journey to leverage couponing (say, if you want to experiment with different discount amounts) you can do that -- each node's contact_journey_node_unique_id
is independent from one another. You'll also need to build a different Lookup like the above for each node leveraging coupons that contain the coupon codes you want to assign to the contacts at that node.
Custom Context
In order to use the couponing at any node in your Journey, you can leverage the Lookup you built in custom context by indexing into it using the contact_journey_node_unique_id
:
{{ lookups.coupon_codes[simon.contact_journey_node_unique_id] }}
This will assign a unique row from the coupons
table to each contact.
Edge Cases
Too many coupon codes
In the case where you have more coupon codes than contacts, you don't need to do anything. The extra coupon codes will simply go unused!
Too many contacts
In the case where you have more contacts than coupon codes, you'll need to catch Lookup errors. This case will manifest itself by a contact's simon.contact_journey_node_unique_id
value being higher than any of the keys in your coupon lookup table. You can catch this error in Jinja and handle it however you'd like -- perhaps with skip_action()
to prevent the send from occurring.
Skip Actions
Note that the contact_journey_node_unique_id
increments from one contact to the next regardless of whether or not a message was sent. That means that if the content you're sending contains skip_action()
statements that are frequently called, you will end up skipping coupon codes in your corresponding lookup table.
Updated about 6 hours ago