11 Replies Latest reply on May 28, 2018 11:33 AM by Sanford Whiteman

    Custom de-duplication: Create new cookie on form submit

    Markus Bianchi

      A customer is using a custom de-duplication logic (email address and an additional field). When a person is submitting a form, Marketo is only using this custom de-duplication check if the person is unknown. For known people, the cookie will "trump" the field values, when it comes to the dedupe logic. In most cases that's desirable and therefore the expected result.

       

      However, in this specific case, we always want to use the custom de-duplication logic rather than the cookie. So, I tried to delete the existing cookie when a person submits the form and create a new cookie before the form is submitted (in the hope that Marketo would "connect" that newly created cookie with the person that was updated in the database (for tracking/pre-fill reasons)):

       

      function deleteCookie(key, path, domain) {
        document.cookie =
          encodeURIComponent(key) +
          '=; expires=Thu, 01 Jan 1970 00:00:00 GMT' +
          (domain ? '; domain=' + domain : '') +
          (path ? '; path=' + path : '');
      }
      
      MktoForms2.whenReady(function(form) {
        form.onValidate(function(isValid) {
          if (!isValid) {
            return false;
          }
      
          deleteCookie('_mkto_trk', '/', 'DOMAIN');
      
          setTimeout(function() {
            Munchkin.createTrackingCookie(true); 
          }, 10);
        });
      });
      

       

      The above code is quite simple, still has a couple of flaws but was just a proof of concept. It deletes the cookie but although I'm using createTrackingCookie() it's not creating a new cookie before the form is submitted (even if I prevent submitting the form with e.g. form.submittable(false);). While this code now forces Marketo to always use the custom dedupe logic (rather than the cookie) it prevents the tracking and pre-filling functionality (assumably because I'm unable to create a new cookie before the form is submitted)!?

       

      Does anyone know how to create or force create a new tracking cookie before the form us submitted or why createTrackingCookie() is not working in this case? Maybe Sanford Whiteman?

       

      Any help is greatly appreciated.

       

      — Markus

        • Re: Custom de-duplication: Create new cookie on form submit
          Sanford Whiteman

          pre-filling functionality

          First of all, you will break pre-fill if a page loads without an associated cookie.  The only way pre-fill works is if the page is requested with an already-associated cookie sent in the HTTP headers (or with mkt_tok in the query string). 

           

          If you delete the cookie using JS in the page itself, that's by definition after the page loads. It doesn't disable pre-fill because the pre-fill JS object (mktoPreFillFields) is already in the page. You can manually clear the form values, of course. But if you don't do that, you'd get the pre-fill data from the initial page load (including hidden fields) re-posted with the form, regardless of whether there's an old cookie, new cookie, or no cookie at all.

           

           setTimeout(function() {  Munchkin.createTrackingCookie(true);   }, 10);  });

          While this code wouldn't work anyway, using setTimeout here is undermining your goals. setTimeout means the function won't run until another turn of the event loop. That's the opposite of what you want, assuming you're trying to create a new cookie immediately. Setting a cookie is a blocking, synchronous process (the cookie is guaranteed to exist on the next line). Using setTimeout makes it asynchronous, which is only going to add confusion and unpredictable behavior.

           

          Even without setTimeout, createTrackingCookie isn't going to work, because it's aware that Munchkin has already been initialized with a cookie and exits immediately (like other Marketo libraries, the Munchkin library has guards against functions being called reentrantly, which can be surprising at times).  Doesn't matter if you delete the cookie from the cookie store directly, it's looking at the Munchkin JS object.

           

          What you can do is add _mkt_trk as an empty hidden field whenReady:

           

          form.addHiddenFields({"_mkt_trk":""});
          

           

          Then onSubmit, create a cookie directly in the cookie store. Make sure it conforms to the Marketo cookie format, which is pretty self-evident. Then set the hidden field to that value:

           

          var newCookie = ...;
          document.cookie = "_mkto_trk=" + newCookie ...
          form.setValues({"_mkt_trk" : newCookie });
          

           

          1 of 1 people found this helpful
            • Re: Custom de-duplication: Create new cookie on form submit
              Markus Bianchi

              First of all, you will break pre-fill if a page loads without an associated cookie.  The only way pre-fill works is if the page is requested with an already-associated cookie sent in the HTTP headers (or with mkt_tok in the query string).

              I described it badly in my original question but meant to say that the pre-fill broke (after a page reload) due to the new cookie not being associated with the person.

               

              While this code wouldn't work anyway, using setTimeout here is undermining your goals. setTimeout means the function won't run until another turn of the event loop. That's the opposite of what you want, assuming you're trying to create a new cookie immediately. Setting a cookie is a blocking, synchronous process (the cookie is guaranteed to exist on the next line). Using setTimeout makes it asynchronous, which is only going to add confusion and unpredictable behavior.

              Sorry, that shouldn't have been in there originally but I forgot to remove it before posting this question. I used it in my last try after all my previous attempts to set the cookie and associate it failed .

               

              Even without setTimeout, createTrackingCookie isn't going to work, because it's aware that Munchkin has already been initialized with a cookie and exits immediately (like other Marketo libraries, the Munchkin library has guards against functions being called reentrantly, which can be surprising at times).  Doesn't matter if you delete the cookie from the cookie store directly, it's looking at the Munchkin JS object.

              What you can do is add _mkt_trk as an empty hidden field whenReady:

              I probably should have looked in the Munchkin code to figure out why createTrackingCookie wasn't working. Thanks a lot for pointing that out and mentioning that _mkt_trk needs to be set as a hidden field.

               

              Anyway it seems to be working now. I used the following function to create a Marketo cookie myself:

               

              function getRootHostname(domainLevel) {
                var hostnameSplit = window.location.hostname.split('.');
                return hostnameSplit
                  .slice(hostnameSplit.length - domainLevel)
                  .join('.');
              }
              
              function getMarketoCookieValue(munchkinId, domainLevel) {
                var rootHostname = getRootHostname(domainLevel);
                var timestamp = (new Date).getTime();
                var randomInt = Math.floor(9E4 * Math.random()) + 1E4;
              
                return 'id:' + munchkinId +
                  '&token:_mch-' + rootHostname + '-' + timestamp + '-' + randomInt;
              }
              

               

              (Just a word of caution for everyone reading this: I'm aware that the getRootHostname has a very limited use case and will not work for all hostnames. I might need to use some library to get that right. There's also a hidden field "munchkinId" in the form which I could use instead of using a function parameter.)

              • Re: Custom de-duplication: Create new cookie on form submit
                Markus Bianchi

                One more question actually. Would setting the new cookie in onValidate also work (just to not reset the cookie too early in case the validation fails)? In my tests it still worked the same but I'm wondering why you suggested onSubmit?