Run-time Resolution of Data Using Attribute Values
Recently I had cause to do some work in Marketing Cloud, which is pretty rare for me to say the least. Something that's been both surprising and powerful, is the fact that you can put AMPscript in far more places than you might suspect, it's not just for email content and the like, but can also in various configuration fields, for example in the From Name and From Email fields of a Sender Profile. This surprised me as in the majority of systems out there, such input fields would only be expected to accept text, and there's nothing in the UI to suggest otherwise. All of the fields indicated below can accept AMPscript rather than just plain text:
Thankfully, being able to use AMPscript in these fields was of particular use to me as we needed to do populate these fields using data from the extension created by a Salesforce Data Entry Source in Journey Builder. Not only did we need to use information from this DE, but needed to do some simple text substitution on the domain part of the email address. I configured it using the syntax I expected to work, but consistently had silent failures when a Salesforce record would trigger the journey. I could see the journey being invoked, and it'd complete all the steps, but the emails would always fail to be sent, with no indication as to why. A quick consultation with someone who knew what they were doing (Eliot Harper), highlighted the fact that the syntax I'd used was completely invalid - I'd hacked around with what I knew until I could save the sender profile, but it meant that at run time the From Email field had a garbage value, so it's not surprising that it wouldn't send.
What I wasn't realising, is that when saving a sender profile, the content of the fields is validated, and as the sender profile configuration is done in the setup screens it doesn't have the context of any given data extion. Trying to reference data extension fields directly fails as they're not known at compile time; my botched syntax actually meant I wasn't referencing the fields, so it'd save, but as stated, produced garbage at run time.
What is needed is a method to avoid a hard coded reference to the fields, basically the equivalent of doing this in Apex:
// hard coded reference to a record type, meaning they must be turned on at compile time
String rtid = account.RecordTypeId;
// run time evaluation means this code will compile in an org with or without record types enabled
String rtid ((SObject)account).get('RecordTypeId');
The way to achieve this in AMPscript is via a function called
AttributeValue, that takes a String parameter providing name of the data extension field to evaluate at run time, and returns the value from that field or
null if it doesn't exist:
%%=IIF(NOT EMPTY(AttributeValue('MyObject__c:Owner:User:SenderName')), AttributeValue('MyObject__c:Owner:User:SenderName'), AttributeValue('MyObject__c:Owner:User:FirstName'))=%%
This simple expression can be used in a Sender Profile no problem, because there are no field references to resolve when saving the profile, then at run time will set the Sender Name to be
SenderName from the
User object in Salesforce if it's not blank, otherwise falls back to the user's
FirstName value. This won't be news to anybody well versed in Marketing Cloud, but for those who dip their toes in very occasionally, it may save you from suffering the frustrations that I had to endure.