SOLVED

Re: How can I send 1 email with dynamic content blocks for products they have and products they don't have?

Go to solution
Ronn_Burner
Level 4

Here is what I'm being told from above that I need to solve for. I can't figure this out.

Think of our product model as DirecTV. A customer can go online and select (subscribe) to any channel or combination of channels they choose. - - So I have 10 ala carte products and a new subscriber signs up to any 1 single product or any number combination up to all 10 products. I only want ONE email to be sent per new subscriber regardless of how many products they subscribed to at one time. Then I will send a 2nd email later. Is it possible - and practical - to acknowledge each product they subscribed to uniquely with a text block and/or image for each AND a different text block promoting the products they did not subscribe to? And if not, what is the best way to handle this type of situation?

So many questions: 1. Segmentation logic? 2. Snippets, dynamic emails or unique streams or programs? 3. Engagement or Default Programs? 4. How to ensure ONLY 1 email regardless of new subscriptions deploys? 5. Smart campaign total and goal?

Any thoughts and or advice on how to handle this initial entry via new subscribers would be a life saver. Thank you!

1 ACCEPTED SOLUTION
SanfordWhiteman
Level 10 - Community Moderator
- I should only use $lead.DMSSubscribed or $lead.DMSSubscribedDate and not both, right?

Only the DateTime field.

- Do I simply just replace all $lead.DMSSubscribed with $lead.DMSSubscribedDate in the code?

Yes, that is, if you're going to convert a stringified DateTime (i.e., ISO8601 format) field into a Date, that's where you use the DateTime.

However I don't think these are ISO8601 "yyyy-MM-dd'T'HH:mm:ss".  They're actually ISO8601 "yyyy-MM-dd HH:mm:ss". That is, they have a space instead of the letter "T". So you can add this line to the code at the top:

#set( $ISO8601WithSpace = "yyyy-MM-dd HH:mm:ss" )

Then use $ISO8601WithSpace where you're using $ISO8601 now.

Parsing a String to a Date requires that you tell Velocity (actually Java) all the parts of the format.

- Do I uncheck the $lead.DMSSubscribed box in the Script Token?

For clarity, yes, but it's harmless to leave it checked as you won't be using it. Leaving it unchecked means it will always have the value null. That may be more or less confusing if you accidentally use it, I don't know.

View solution in original post

96 REPLIES 96
Joke_Van_Essche
Level 3

Ronn Burner Thanks for this topic!   

Sanford Whiteman‌ Is it possible to do the same with program membership instead of a boolean field? So: If Member Status = Registered in Program 1, then "welcome to session 1". If Member Status = Registered in Program 2, then "welcome to session 2". 

SanfordWhiteman
Level 10 - Community Moderator

Unfortunately no. Program membership is not a direct property of the lead.

If you used program membership to manage a segmentation, then the segment is a property of the lead (so could be used in personalization) but it's not updated in absolutely real-time.

Or have a field on the lead that's used as a mirror for their program status.

SanfordWhiteman
Level 10 - Community Moderator

What is a product subscription stored as? An individual Boolean? An individual DateTime? An entry in a semicolon-delimited list?

Ronn_Burner
Level 4

Individual boolean custom field per product. I have a custom CRM so was previously required to make those fields to utilize in other Up-sell program and get away from "Added to" and "Has updated" custom object world.

SanfordWhiteman
Level 10 - Community Moderator

This isn't a case for segmentations, then. Too many permutations. (Even if you could precompute them, you don't have enough segments.)

The answer: Velocity. VTL can easily check the value of a Boolean. (Many of my blog posts are about working with Boolean/Boolean-like/once-Boolean values, since it's the most important datatype to understand when using #if!)

Ronn_Burner
Level 4

This is so disheartening. I read the blog posts you linked to and it's far too complex for me. I have no experience with velocity. It's so confusing and I'm afraid I'm just not intelligent enough to do this on my own. I need hand holding to do this level of work within Marketo. As you say, I'm sure this is easy and certainly easy for you but it's a foreign language to me. Is there a way to get me through this - here step by step or offline if that's less annoying?

Jay_Jiang
Level 10

Trust me, the looping nurture program you set up is far more complex than creating an email script.  Don't fear what is unfamiliar. And I apologise for seeming to trivialise it.

Maybe Sanford Whiteman‌ can give you a helping hand with the code!

SanfordWhiteman
Level 10 - Community Moderator

Agreed, Jay!

Admittedly, it can feel good when your area of expertise is intimidating to others -- then you know it's a real skill. On the other hand, nothing is impossible... it may have taken many hours to get to an advanced level, but surely someone else can do it given enough time + enthusiasm. (I have one official student now, we'll see how that goes!)

Having at least a passing knowledge of VTL -- that's "Velocity Template Language" by the way, the full name of the language but interchangeable w/"Velocity" -- is critical to getting (seemingly) run-of-the-mill tasks done in Marketo.  And, to be frank, it's great for your career (bringing Velocity into a place that never used it makes you a hero)

In this case, you're talking about a bunch of special Strings in Velocity (corresponding to Booleans in Field Management) that each have one of two values: "1" (true-like) or "" (false-like). And you want to choose output based on the value.

Let's say 2 of the fields, checked off in the fields tree in Script Editor, are $lead.product1 and $lead.product2.

A basic Velocity snippet to do content switching looks like this:

#if( $lead.product1.equals("1") )
You subscribed to Product 1.
#else
You did not subscribe to Product 1.
#end
#if( $lead.product2.equals("1") )
You subscribed to Product 2.
#else
You did not subscribe to Product 2.
#end

The output lines are text-only for readability, but can just as easily be HTML.

(Granted I would probably do this in a slightly slicker way myself, but this way is easiest to understand.)

Ronn_Burner
Level 4

Jay, that is good to hear. And you nailed it - I panicked in terror due to the unfamiliarity. Just when I think my Marketo game is solid something like this presents itself and I feel like it's my first day in the instance.

Sanford, I look forward to being a hero. Trust me! This stuff is exhilarating to learn once the "Aha!" moment clicks - and the terror subsides. I've been reading your content for years - Your student is lucky to have you!

I have created this 'Email Script' token implementing the boolean field 'Product X Subscribed' for our 7 products (there will be more to come later but at this point we have only these 7.)

pastedImage_2.png

Am I headed down the right path thus far? I don't want to get to far ahead but just to see if I'm even remotely close to comprehension here 1.) In the end, will this be a token in the email HTML? 2.) Is this only the dynamic content block to pull in information for those products that were, in fact, subscribed to which means I would need to duplicate this script using .equals("") ) for the content block of the products they did not subscribe to?

I'm probably overthinking it because if it does not equal ("1") then obviously it equals ("")

And we're off! I CAN DO THIS! I think I can... I think I can... I think I can...

SanfordWhiteman
Level 10 - Community Moderator
Am I headed down the right path thus far?

Yep!

1.) In the end, will this be a token in the email HTML?

Yes, you will include the name of the {{my.token}} in the email.

2. Is this only the dynamic content block to pull in information for those products that were, in fact, subscribed to

No, you're including content for both the true and false fields here.

If you want to break it up with all trues first, then all falses second, then have

#if( $lead.field1.equals("1") )
Your field1 is true.
#end
#if( $lead.field2.equals("1") )
Your field2 is true.
#end
#if( $lead.field1.equals("") )
Your field1 is true.
#end
#if( $lead.field2.equals("") )
Your field2 is true.
#end‍‍‍‍‍‍‍‍‍‍‍‍
Ronn_Burner
Level 4

If you want to break it up with all trues first, then all falses second, then have

I'm open to suggestions on how to best do this but in my mind (because I wasn't sure how else to make it work) I saw this as 10 individual content blocks and if you sign up for 1 product it only populates that 1 block "Welcoming" them. The other 9 blocks are then the remaining products they did not subscribe to Or if you subscribe to 7 you get "welcomed" from each of them and still pitching the 3 products they did not subscribe to.

So for every product subscription that = TRUE the block will have "Welcome/Confirmation" text and/or image populate it and those that = FALSE will have "You still need this product blah blah" text.

I think perfect world I would love to acknowledge each product they subscribed to (1 to 10) at once AND only 3 of the products they still need to subscribe to - rather than all 9 if they only subscribed to a single product.

I'm sure you can see a clear best way to do this with how Velocity within Marketo works - and i am 100% open to it. In the end I just need to acknowledge/confirm what they DID subscribe to AND mention at least a couple products they have NOT subscribed to.

I'm all ears and eager as can be to learn! And I cannot thank you enough for your help, time and patience! it is beyond appreciated.

SanfordWhiteman
Level 10 - Community Moderator
In the end I just need to acknowledge/confirm what they DID subscribe to AND mention at least a couple products they have NOT subscribed to.

As far as I can see, you have exactly that already.For each product, you have the choice to output certain content if their value is "1" (they are subscribed to that product) or if their value is "" (they are not subscribed to that one).

You can do all the "welcomes" first. Only output the welcome for a product if it is subscribed ("1").

Then do all the "pitches". Only print the pitch for a product if it is not subscribed ("").

Ronn_Burner
Level 4

You will be shocked at the stupidity of this question so I apologize in advance BUT where is the content being pulled from to populate the "1" and "" within the body of the email?

If Product X Subscribed = "1" that area will populate with the paragraph and/or image specific to that product but where is that built and stored to be pulled from? I know the answer is right in front of my face yet I don't know it.

After I figure that part out. Then am I to simply have a single content block with the Email Script Token {{my.VelocityAllTrueThenAllFalse}} or do I put that token in 8 (1 for each product) different blocks (there are 8 actually, I misspoke and said 7 previously) or since there is a "1" and a "" do I need a total of 16 block with the token in each?

I believe I have this correct in the below image?

Screen Shot 2019-11-11 at 4.32.05 PM.png

SanfordWhiteman
Level 10 - Community Moderator
If Product X Subscribed = "1" that area will populate with the paragraph and/or image specific to that product but where is that built and stored to be pulled from?

It's built right where you currently have "Your Max Digital Subscribed is true" and so on. Replace that with your actual content, including HTML <div>/<img>/<whatever> tags.

Then am I to simply have a single content block with the Email Script Token {{my.VelocityAllTrueThenAllFalse}}

You'd embed the {{my.token}} only once. It does all the output, covering all the permutations.

Ronn_Burner
Level 4

Got it. I figured it would have to be but I made it way more difficult than I needed to. After seeing this and having that "click" moment really makes re-reading your blog posts actually seem like English. This is very, very cool and skill and knowledge I will continue to to explore and sharpen. Now I want to do this for ALL my automation emails!

I can see this is simple and very flexible to simply add, subtract or edit any product in the token - which will be tremendously helpful as our products are software and are constantly changing.

After reviewing how this process will work I realized I have an additional question. All new subscriptions for any product triggers this email.

As it is now, a lead signs up for new Subscription for 1 to 8 products that triggers this email scanning all the "1" and  "" and populating each products content as it should. However, it's very common that a client will, in fact, subscribe to one of the remaining products they do not yet have on any later date, in which case would once again trigger this same email - which would scan and once again "Welcome" them to a product they already have. You see what I mean.

How should I - or how would you handle that?

SanfordWhiteman
Level 10 - Community Moderator

Here's where people realize that Booleans are (usually) an inferior substitute for DateTimes.

A non-empty DateTime is effectively a superset of a Boolean, because it indicates both (a) that something is true and (b) when it became true. In contrast, as you're finding out, a Boolean can only record whether something is currently true or false.

If you had these as DateTimes you could find out the ones that became true during the past day and only "welcome" those. Of course that means more advanced Velocity code.

P.S. In the the grander scheme of database design, people know Booleans are resource-efficient, so they don't reach out to DateTimes as fast as they should IMO. It's true that a Boolean can take up only a byte, or even less, while a DateTime takes 6-8 bytes to store -- but still not worth worrying about unless you're talking hundreds of fields and have proven that storage is a real-world concern.)

Ronn_Burner
Level 4

Right. I see. Well, we may be okay then - Thanks to Jay back when I created my dynamic programs - he advised the DateTime approach so I did, in fact, add a custom field "Product X Subscribed Date" to go along with the boolean T/F. I used {{system.date}} simply because our CRM to Marketo sync is a one way street daily batch so Time becomes irrelevant. Understanding this better I now see that is information I should have provided to you at the top. My apologies.

Now, that being said, if that works, can you help me get there or does "more advanced Velocity code" translate to "forget about it!?"

All this information is invaluable and I'm eagerly absorbing it.

SanfordWhiteman
Level 10 - Community Moderator
... add a custom field "Product X Subscribed Date" to go along with the boolean T/F.

But if you're not also updating the DateTime when someone flips to false, then there's no need for the Boolean. I'm talking about having only a DateTime, not both.

On the other hand, if the DateTime also is updated on the Unsubscribed Date -- functioning as the Last Product X Subscription Change Date as opposed to only the Last Product X Subscribed Date -- then you do need the 2 fields, since that can't be reflected with just the DateTime.

Ronn_Burner
Level 4

Thanks for following up because I read your blog post several times and realized I don't know near enough yet to proceed. So thank you for not abandoning me. This is an invaluable lesson and experience to add to my skill set.

But if you're not also updating the DateTime when someone flips to false, then there's no need for the Boolean.

I am actually. If Product X gets 'Canceled', it is System.Date stamped and 'Product X Subscribed' changes to False. The custom fields I created (again per Jay Jiang many months ago - I keep giving him credit because he went above and beyond to help me and he deserves it to be acknowledged for it) are:

Product X Subscribed (Boolean)

Product X Subscribed Date (System.Date)

Product X Canceled Date (System.Date)

Product X Nurture Completed (Boolean) - which is used to complete loop program and reset to re-enter later

I'm talking about having only a DateTime, not both.

Right. I see. It's not necessary as the system.date stamp (value) - if there is one - for Subscribed/Canceled lets you know the TorF status of each.

I feel like all of what I have is good news and we're still in business since we have this data in place already, right?

Ronn_Burner
Level 4

Based on the fields I have am I able to create more advanced Velocity code required to "welcome" those that became true during the past day? If so, how?