The hard part of email design is cross-client compatibility. Enhanced effects work in some web and mobile clients, but you need graceful degradation to HTML 3.2-era stuff, gotta have VML for Outlook desktop, etc.
Identifying email clients is easy-ish after a person opens an email, but what about before?
Wouldn’t it be nice to have some idea of how many people will be reading your emails in at least one Gmail client — in addition to those literally @gmail.com
? A Smart List like this’d do it:
A similar list of people whose companies use Outlook 365, but who aren’t using personal @outlook.com
addresses:
And a fun one, people whose domains don’t have MX records at all, so can’t receive mail[1] (i.e. partial/poor man’s email validation):
Let’s find out how to populate that Email Domain MX Records field.
Create Marketo fields
I assume you already have a field Email Domain that holds a person’s email domain. If not, add it as an SFDC Formula:
if( find( '@',YourEmailField) == 0, '', right( YourEmailField, len(YourEmailField) - find( '@', YourEmailField ) ) )
Now add a String field Email Domain MX Records:
We’ll fill that field using Google’s DNS-over-HTTPS JSON gateway, part of their infinitely scalable public DNS infrastructure.
Set up the webhook
Thanks to DNS-over-HTTPS (DoH), the idea of fetching DNS results over HTTP is mainstream.[2] You still need a DoH-to-text gateway[3] for the results to be read as a webhook response, but Google and CloudFlare both offer free, unlimited-use gateways.
So set up a simple webhook:
Here’s that URL value for copying and pasting:
https://dns.google/resolve?name={{lead.Email Domain}}&type=mx
In Response Mappings we’re taking advantage of a Marketo quirk. The Answer
property is a JSON array like so:
[
{
"name" : "cornell.edu.",
"type" : 15,
"TTL" : 427,
"data" : "0 cornell-edu.mail.protection.outlook.com."
}
]
When we map the entire Answer
to a string field, Marketo converts the array to a List of Java Maps and then serializes that list to a reasonable (if imperfect) string format:
For readability, that New Value is:
List(Map(name -> cornell.edu., type -> 15, TTL -> 427, data -> 0 cornell-edu.mail.protection.outlook.com.))
The format wouldn’t be suitable for deserialization, but for simple text matching it’s fine.
One more thing: Consolidate lookup exceptions into a single ERROR
value
A few different DNS responses amount to “no MX record.” For example, if a domain has no nameservers at all, they implicitly have no MX records, though the response details are different. I use this Smart Campaign to normalize any response that doesn’t contain Type 15 records to the value ERROR: Domain not found in DNS or no MX record
:
If you ever need the raw response you can consult the Activity Log for Call Webhook.
Notes
[1] Yes, you can also receive email with only a DNS A record, and SMTP-senders still respect that fallback. But in the modern era, if someone doesn’t publish an MX record it’s 99.99999% likely (and that’s generous) they don’t have a functioning mailserver on example.com
’s IP, either.
[2] Commercial DNS-to-HTTP services have been around for a long time. They’re just DNS clients that parse the response into JSON, about as simple as it gets. But they’re comically expensive — just look at the prices below. Ridiculous!
[3] DoH uses the binary DNS wire protocol, not JSON (i.e. the response is a binary stream, like when you download an image). So technically, you’re not sending a DoH request from Marketo; rather, Google is using DoH and transforming the response to be webhook-compatible.