Search Content

12 Days of Scriptmas - 2022 Winners!

HowToSFMC

Published on 12/09/2021

12 Days of Scriptmas Title

Scritpmas Winners

But wait there's more!

The HowTo Crew must have been extra good this year because Santa left few extra presents under the tree so, we've decided to give them to a few of the folks who submitted scripts for Scriptmas! To add a little sparkle we decided to make a cloud page to randomize the winners. :sparkle emoji: Details on that a little later on.

Without further ado, the winners of Scriptmas 2022 are...

Grand prize

Tim Felch

Tim has won a physical copy of [Automating Salesforce Marketing Cloud] (https://www.amazon.com/Automating-Salesforce-Marketing-Cloud-productivity/dp/1803237198), as well as a Trailblazer Hoodie, an Astro plushy, and a Salesforce Certification voucher!

Additional winners

Cenk Irman
Akash Israni
Jake Wiesenthal
Elliott Davidson

All addtional winners will recieve a digital copy of [Automating Salesforce Marketing Cloud] (https://www.amazon.com/Automating-Salesforce-Marketing-Cloud-productivity/dp/1803237198), a Trailblazer Hoodie, and a Salesforce Certification voucher!

Thank you again to all who submitted scripts for Scriptmas '22 and we'll see you next year!

Scriptmas Randomizer Selector

Scriptmas Randomizer Selector

Now that we know who the winners are and what they won, let's take a look at how we selected these winners.

To make things fair, we randomly selected between the 12 chosen script creators who would be taking the grand prize as well as the other prizes. This was done via a CloudPage on SFMC using SSJS. We thought this would be fitting with the theme of helpful scripts and advocacy of Marketing Cloud.

Now, how do we make SSJS do a random selection? Lets dive in and take a look!

SSJS Randomizer

When broken down, the randomizer is a do/while() statement combined with a simple function. See below script for example:

  do {
    //entriesRS is an array of objects (taken from a DE holding all the entries)
    var winnerIndex = getRandomWinner(entriesRS.length);

    //winnerRS is an object
    var winnerRS = entriesRS[winnerIndex];

    var winnerID = winnerRS.ID;
    var winnerName = winnerRS.Name;

    var upsert = Platform.Function.UpsertData("Winners_2022",["ID"],[winnerID],["Name","Prize"],[winnerName,prize]);
    //Prize is set above do/while loop for grand prize

    //remove winner from eligible array
    entriesRS.sort(function(x,y){ return x == winnerRS  ? -1 : y == winnerRS ? 1 : 0; });
    entriesRS.shift();

    var prize = "Winner"
    cnt++;
  } while (cnt < 5)

  function getRandomWinner(max) {
    return Math.floor(Math.random() * max);
  }

The main crux of the randomization is the combination of Math.random() and multiplying it by the max number. random() will generate a completley number between 0 and 1, this then multiplied times the maximum number you want displayed will give you a random number between 0 and the maximum number. Now, this number will not be a whole number, so to make sure we only return a whole number, we add on Math.floor() to reduce the number down to the whole number displayed, removing all decimals. From there we then get a random number between 0 and the maximum number, which we can then use as an index for our array of objects, to select the winning row.

To better explain that, here are the breakdown steps to how it was selected:

  1. An array of objects was retrieved using Rows.Retrieve() on a Data Extension holding all the entries information
  2. Using the randomizer function, getRandomWinner(), we were returned with a whole number between 0 and the number of entrants
  3. This whole number was then used as the index for selecting an object out of the array of objects we previously retrieved
  4. This chosen object now contained all the information on that selected winner that we then upserted into a new data extension
  5. Utilizing a do/while() look, we did this for a total of 5 times to collect each of the winners for our event

Now that we understand the script, let's look at how we decided to run it.

Running the 'Thing'

Of course we could have just made this a script activity and run it and called it a day, but that seemed a bit...anti-climactic, so we decided to instead create a form on a CloudPage, that upon submit ran this script then displayed the winners on the page. Below are the requirements of this CloudPage and the script contained within:

  • Data Extension: Selected_Entries
  • Data Extension: Winners_2022
  • CloudPage (self-submit)

Now that we know what assets are needed, let's dive into what these assets are and what they need to contain.

Selected_Entries

This one is fairly simple, it will hold all the current entries along with the necessary information. For example in this case, we had the following columns:

  • ID | Number | Primary Key
  • Name | Text (50) | Nullable

Now to be fair, ID was not necessary, but I tend to like making my primary keys numbers or otherwise simple and unique values. The next data extension has a bit more to it though...

Winners_2022

Although this has a bit more to it then the previous, it really is just one field....Prize.

This field is a text field, with max character length of 50 and is nullable. This will show whether the person won the Grand Prize or not.

The CloudPage

The CloudPage is the most intricate part. But honestly, outside the script and a couple elegant functions and conditionals, it really is still fairly simple.

It is a few Rows.Retrieve() to get the entries and validate if the winners have already been chosen or not. From there it is a group of conditionals checking:

  • if winners are chosen then display the winners html code, hide form.
  • if winners are not chosen, but not submitted, then show form, hide winner html
  • if winners are not chosen, but is submitted, then run randomizer script, show winner html, hide form.

We then have a form that just has a simple submit button that will POST to itself passing along the simple input of 'submit = 1' to let the page know that the form button was pushed and to run the randomizer script. Outside that, it is a simple display of AMPscript variables showing the winners pulled from the winner data extension.

That is really it! It has some complicated parts and some twisty/turney type coding to it, but in general it is not too complex.

Click here to see the full code for the CloudPage:
<script runat="server">
  Platform.Load("Core","1.1.1");
  try {
    var debug = 0;
    var debugForm = 0;

    var submit = Request.GetFormField("submit");
    var winDE = DataExtension.Init("Winners_2022");
    var winRS = winDE.Rows.Retrieve();

    if ((winRS.length < 1) && (submit)) {

      var entriesDE = DataExtension.Init("Selected_Entries");
      var entriesRS = entriesDE.Rows.Retrieve();

      var prize = "Grand Prize"
      var cnt = 0;

      do {
        var winnerIndex = getRandomWinner(entriesRS.length);

        var winnerRS = entriesRS[winnerIndex];

        var winnerID = winnerRS.ID;
        var winnerName = winnerRS.Name;

        if (prize == 'Grand Prize') { 
          TreatAsContent('%' + '%[ SET @GrandPrize = "' + winnerName + '" ]%' + '%') 
        } else { 
          TreatAsContent('%' + '%[ SET @Prize' + cnt + ' = "' + winnerName + '" ]%' + '%') 
        }

        var upsert = Platform.Function.UpsertData("Winners_2022",["ID"],[winnerID],["Name","Prize"],[winnerName,prize]);

        //remove winner from eligible array
        entriesRS.sort(function(x,y){ return x == winnerRS  ? -1 : y == winnerRS ? 1 : 0; });
        entriesRS.shift();

        var prize = "Winner"
        cnt++;
      } while (cnt < 5)

    } else if (submit) {
      
      winRS.sort(function(x,y){ return x.Prize == "Grand Prize"  ? -1 : y.Prize == "Grand Prize" ? 1 : 0; });

      Variable.SetValue("@GrandPrize",winRS[0].Name);
      Variable.SetValue("@Prize1",winRS[1].Name);
      Variable.SetValue("@Prize2",winRS[2].Name);
      Variable.SetValue("Prize3",winRS[3].Name);
      Variable.SetValue("Prize4",winRS[4].Name);
      debugWrite('winRS',Stringify(winRS))

    } else if (winRS.length < 1) {
      Variable.SetValue("@form", "1")
    } else {
      
      Variable.SetValue("@GrandPrize",winRS[0].Name);
      Variable.SetValue("@Prize1",winRS[1].Name);
      Variable.SetValue("@Prize2",winRS[2].Name);
      Variable.SetValue("Prize3",winRS[3].Name);
      Variable.SetValue("Prize4",winRS[4].Name);

      if (submit != 1) {  (debugForm) ? Variable.SetValue("@form", "1") : ''; }
    }

  function debugWrite(name,val,overwrite) {
      if (debug && !overwrite) {
        Write('<b>' + name + ': </b>' + val + '<hr>')
      }
    }

  function getRandomWinner(max) {
    return Math.floor(Math.random() * max);
  }

</script>
<!DOCTYPE>
<html>
  <head>
    <style>
      body {
        background-color: aqua;
        margin: 0;
        font-family: ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Sego UI, Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,ui-monospace, SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monopsace;
      }
      .container {
        max-width:1000px;
        margin: 0 auto;
        background-color: #fff;
      }
      .logo {
        width:100%;
        padding: 30px;
        background-color: #000000;
        text-align: center;
      }
      .h2Logo {
        max-width: 200px;
      }

      .display {
        background-color: #fff;
        width: 100%;
        padding: 30px;
      }

      h1 {
        text-transform:capitalize;
      }

      .subheading {
        font-size: 1.4em;
        margin: -22px 0 20px;
        font-style: italic;
        color: #444
      }

      .copy {
        margin: 0 0 30px;
      }
      .divTable{
        display: table;
        width: auto;
        min-width: 600px;
      }
      .divTableRow {
        display: table-row;
      }
      .divTableHeading {
        background-color: #EEE;
        display: table-header-group;
      }
      .divTableCell, .divTableHead {
        border: 1px solid #999999;
        display: table-cell;
        padding: 7px 14px;
      }
      .divTableHeading {
        background-color: #EEE;
        display: table-header-group;
        font-weight: bold;
      }
      .divTableFoot {
        background-color: #EEE;
        display: table-footer-group;
        font-weight: bold;
      }
      .divTableBody {
        display: table-row-group;
      }
      .GrandPrize {
        background-color: rgb(247, 90, 90);
      }
      .Prize {
        background-color: rgb(105, 190, 105);
      }   
      form {
        margin: 0 auto;
        text-align: center;
      }
      input[type=submit] {
        font-family: inherit;
        font-size: 1.2em;
        color: #fff;
        width: 250px;
        padding:20px 50px; 
        background:rgb(17, 187, 94); 
        border:0 none;
        cursor:pointer;
        -webkit-border-radius: 10px;
        border-radius: 10px; 
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="logo"><img class="h2Logo" src="https://res.cloudinary.com/howtosfmc/image/upload/v1614651577/HowtoSFMCPlaceholder_White_vlsjf0.png" /></div>
      <div class="display">
      %%[if @form == 1 then]%%

        <div class="heading"><h1>Scriptmas 2022</h1></div>
        <div class="subheading">It is time for us to randomly select the winners for Scriptmas 2022!</div>
        <div class="copy">Using randomization scripting in SSJS on a SFMC CloudPage, we will select 1 Grand Prize winner and 4 other prize winners for this year's Scriptmas event. By Clicking the button below, we will have each of these selected and then displayed</div>

        <form method="POST">
          <input type="hidden" name="submit" value="1" />
          <input type="submit" value="Select the winners!">
        </form>
      %%[else]%%
        <div class="heading"><h1>Scriptmas 2022</h1></div>
        <div class="subheading">The winners have been selected for our grand and other prizes!</div>
        <div class="copy">A big thank you to all that have entered, and a hearty congratulations to those selected. Without further ado, displayed below are the randomly selected prize winners for the 2022 Scriptmas event by HowToSFMC!</div>
        <div class="divTable">
          <div class="divTableBody">
            <div class="divTableRow GrandPrize">
            <div class="divTableCell"><b>Grand Prize</b></div>
            <div class="divTableCell"><b>%%=v(@GrandPrize)=%%</b></div>
            </div>
            <div class="divTableRow Prize">
            <div class="divTableCell">Prize 1</div>
            <div class="divTableCell">%%=v(@Prize1)=%%</div>
            </div>
            <div class="divTableRow Prize">
            <div class="divTableCell">Prize 2</div>
            <div class="divTableCell">%%=v(@Prize2)=%%</div>
            </div>
            <div class="divTableRow Prize">
            <div class="divTableCell">Prize 3</div>
            <div class="divTableCell">%%=v(@Prize3)=%%</div>
            </div>
            <div class="divTableRow Prize">
            <div class="divTableCell">Prize 4</div>
            <div class="divTableCell">%%=v(@Prize4)=%%</div>
            </div>
          </div>
        </div>
      %%[endif]%%
      </div>
    </div>
  </body>
</html>

<script runat="server">
  
  } catch(e) {
    Write(Stringify(e))
  }
  
</script>

Well, that is pretty much it! I hope you enjoyed it and can use this in some way to help assist in your future needs. So long and thanks for all the fish!

Recent Articles

Search Content
All Rights Reserved
Made with by your fellow SFMC users.