About Adam Erstelle

Adam Erstelle is a Solution Engineer & Product Development Lead with Sercante. He loves learning about and solving really interesting challenges with Pardot and Salesforce often by building some cool tools.

Twilio SMS Messages and Pardot: A Complete Guide

We’ve previously talked about External Actions and External Activities, with some general ideas of how each can be applied separately. Where the real power comes in, is tying them together. In this blog post, let’s explore using a Marketing Cloud Account Engagement (Pardot) Engagement Studio Program to send an SMS message and act on the Prospect replying to it.

Installation and Configuration for Twilio SMS Messages and Pardot

Say your company is going to attend a big conference, and you want to see if there is interest for nearby Prospects (far enough in their journey with you) to meet with your team. A quick text asking if they are interested, followed up with sales outreach and/or a “book a meeting” page is a great example of sending the right message at the right time.

There’s a lot of installing and configuration needed to pull this off: 

  1. Set up Twilio for Salesforce
  2. Set up Twilio for Pardot
  3. Create a Flow to be called by External Action
  4. Configure the Marketing App Extensions
  5. Create the Engagement Studio Program
  6. Handle SMS Responses with a Flow

Set Up Twilio for Salesforce

The first thing we are going to do is to integrate Twilio with our Salesforce org. Twilio has a really good instruction video for setting things up, we highly recommend watching it and following along.

https://www.youtube.com/watch?v=-AS4EMCv_cU

Install instructions written out can be found here:

https://www.twilio.com/docs/salesforce/install

Setup Twilio for Pardot

Once Twilio is set up for Salesforce, there are a couple of steps to enable it to work with Pardot.

  1. Add the B2BMA Integration User as a “Twilio for Salesforce” Licensed User (enables Pardot to send the SMS)
    • In Salesforce Setup, use the Quick Find window to search “Installed Packages.”
    • Click Manage Licenses beside the Twilio package, add the B2BMA Integration User
  2. Add the “Twilio User” Permission Set to B2BMA Integration User
  3. Create a “Latest SMS Campaign” field on both the Lead & Contact (Lookup to Campaign). You do not need to sync this field with Pardot, though the B2BMA Integration User should have access to edit the field values.

4. Create a Pardot custom field named “MobilePhone.” Sync this field to the Salesforce field of the same name. The Twilio Lightning Components you added when setting up Twilio for Salesforce relies on the MobilePhone field.

For the purpose of this blog post, we are not taking into consideration whether the prospect has opted in or out of SMS messages. Though, you should consider this when putting together a solution in your environment.

Create a Flow to be called by External Action

External Actions can be powered by APEX, External Services (which make APEX behind the scenes), and Flows. Whenever possible, we recommend using a Flow, as it makes it a bit easier to test and troubleshoot later on.

  1. From Salesforce Setup, use the Quick Find window to search for “Flows.”
  2. Select Create New Flow, then choose Autolaunched Flow.
  3. We need to create a few resources (variables) that will be exposed to Pardot and provide the information we need. These should all be set to:
    • Resource Type: Variable
    • API Name: varPhoneNumber (The phone number we are sending the SMS to)
    • Data Type: Text
    • Available for input: checked
  4. Repeat step 3 for the following variables:
    • varCampaignId – The Salesforce Campaign ID we want to use for tracking
    • varCrmLeadContactId – The Salesforce ID of the Lead or Contact record
    • varMessage – The text we want to include in the SMS message
    • varCampaignStatus – the CampaignMember status you want to use when sending the SMS. This is optional, you could just hard-code the flow to use “Sent”
  5. Create a couple more variables to help simplify the flow. These will be Text, and we will not be selecting the “Available for input” checkbox (they are only used within the flow)
    • varLeadId – set only if the varCrmLeadContactId is a Lead (Decision-based on prefix starting with 00Q)
    • varContactId – set only if the varCrmLeadContactId is a Contact (Decision, prefix starting with 003)
  6. The Flow itself will be composed of a few sections
    • Send SMS via Twilio
    • Update the “Latest SMS Campaign” field on Contact/Lead records with the Campaign ID if the Prospect is synced to CRM
    • Create/Update CampaignMember record for the Contact/Lead and Campaign
    • When done, your Flow might look something like this:
  7. Save and Activate your Flow

Configure the Marketing App Extensions

Next, we need to actually expose the Flow to Pardot. This is done with Marketing App Extensions in Salesforce Setup.

  1. In Salesforce Setup, use the Quick Find window to search for “Marketing App Extensions”
  2. Create a new extension named “Twilio” (don’t create a bunch of tests, currently these cannot be removed and you have a limit of 10)
  3. In the Related Tab, for Action Types click New.
    • Type Action Name: Send SMS w Campaign, type in a good API name
    • For Invocable Action, search for your newly created Flow
    • Once selected, the Action Schema will automatically fill in. We will want to edit it
      • adjust titles, set merge for varCrmLeadContactId, varPhoneNumber. This enables the system to automatically grab the values from the Prospect record.
      • remove view components for varCrmLeadContactId and phoneNumber. Since they are being auto-populated, no need to ask for the values.
      • Set varMessage, varCampaignId as required
    • Make sure “Active in Automations” is checked.
    • Once done, it will look like this (we adjusted the line spacing to make a decent screenshot:
    • Note: because you are directly editing JSON, if mistakes are made there isn’t great feedback in terms of errors upon saving. We’ve found it best to just click Cancel and try again, being a bit more careful.
  4. Next, we will create an Activity Type. This will enable us to send information back to Pardot when a Contact/Lead replies to one of our messages (we will walk you through handling this later in the post).
    • For Activity Name & API Name, simply use “FirstReply”
    • Make sure “Active in Automations” is checked.
  5. Lastly, we will enable these Actions and Activities for our Business Unit(s). Assign this Extension to your Business Unit(s) by clicking New, and choosing the Business Unit.

Create the Engagement Studio Program

Next, we will build an Engagement Studio Program that will begin to tie this all together.

  1. In Pardot, navigate to Automations > Engagement Studio
  2. Select + Add Engagement Program
  3. Add a new Action, choose “Send SMS w Campaign” (bottom of the list)
    • SF Campaign ID: provide an 18-character Campaign Id
    • Campaign Status: provide a valid CampaignMemberStatus for the Campaign
    • Message: let your creativity shine!
    • When done, it should look something like this:
  4. Next, we want to Listen for their First Reply to our Campaign. Add a new Trigger
    • Choose External Activity 
    • Extension Name: Twilio
    • Activity Type: FirstReply
    • Value: The Campaign Id you provided in the earlier step. We want these to match
    • Specify when the Trigger should be evaluated.
    • When done, it should look something like this:
  5. Next, you can decide what happens if the Prospect does reply. In our example, we add the Prospect to a Suppression List (as ideally, they are now engaging with Sales, we don’t want to keep bugging them right?

Ok, our Engagement Studio Program is done. How will it know when someone has replied to our message?

Handling SMS Responses

With the Twilio integration, we can create a Record Triggered Flow based on the “Twilio Message” object, looking for inbound SMS messages. When a message is received, we can check to see if we should take action (based on the “Latest SMS Campaign” field still having a value).

In our example, we will use the Pardot API to send an External Activity record (with some help from a free AppExchange package) to allow our Engagement Studio Program’s trigger to work, update the Campaign Member Status for the Lead/Contact and create a Task for Sales to follow up.

To begin, we will install & configure the Flow Actions for Pardot package, which makes it easy to make Pardot API calls (since you can’t natively do this within Salesforce).

Create the Flow

Next, we will create our Flow:

  1. From Salesforce Setup, use the Quick Find window to search for “Flows”, and create a new Flow
  2. Choose a Record Triggered Flow
    • Select “Twilio Message” as the Object
    • Trigger when a Record is created
    • Entry Conditions: TwilioSF__Direction__c Equals “inbound”
    • Optimize for Actions and Related Records, and Include a Run Asynchronously path.
  3. We will need a decision based on the Twilio Message being linked to a Lead or Contact. The logic we use for both Leads and Contacts will be similar, let’s start with Leads
  4. Use a Get Records element to retrieve the Lead based on the ID matching the Twilio Message’s Lead value
  5. Check to see if we need to take action on the Lead by checking if the “Last SMS Campaign” field has a value. If it does not, we can end the flow.
  6. If “Last SMS Campaign” does have a value, create a new Element: “Pardot – External Activity Add to Prospect”
    • Activity Type: FirstReply (this is what you provided when setting up the Extension earlier in the post)
    • Extension Name: Twilio (again, this was setup earlier)
    • Prospect Email: Grab the Email value from the Get Records element in Step 4 above
    • Value: Grab the “Latest SMS Campaign” value from the Get Records element
    • When done, it should look something like this:
  7. Update Lead’s CampaignMember record, create a new Update Records element
    • Specify conditions to identify records, and set fields individually
    • Update records of object: Campaign Member
    • Update records matching the CampaignId and Lead Id from the Get Records element in Step 4 above.
    • Set the Status to what you need it to be (we chose Responded). You will really want consistency across your Campaigns to reduce complexity.
    • When done, it should look something like this:
  8. Create a Task for Sales. You can do this with either a Quick Action, or with a Create Record element, it really depends on your setup and what level of detail you want to provide.
  9. After taking all of our actions, we will want to clear the “Latest SMS Campaign” field on the Lead, so that we don’t take the same actions the next time the person replies.
  10. Repeat steps 4-9 for a Contact, being sure to select the Contact’s Get Record variable in steps 5-9
  11. When done, your Flow should look something like this:

Phew, it’s all done. Give it all a try by sending your own Prospect record through the Engagement Studio Program. It will take a while once started, but you should get your Text message. Once received, check your Lead/Contact record to make sure it was stamped correctly and that you were added to the right Campaign.  

Send a reply from your phone and check your Lead/Contact record again to make sure that your Campaign Status changed, and check Pardot to see that your External Activity record was created.

Considerations

As with any “internet example,” there are a few things that we skirted around to avoid extra complexities, and there are a few things that might not be obvious.

  • This solution is best run when all Prospects (entering the ESP) are synced in Salesforce.
  • Prospects that are not synced to Salesforce, if they reply Twilio will create a Lead record and it might not be synced to Pardot fast enough to receive the External Activity resulting in a break in the process.
  • Our example handled ANY SMS response in the same way. While it is possible to add keywords and build branching logic into Flows and Engagement Studio Program, the solution will get exponentially more difficult to maintain.
  • In our example, we created the Task in the Flow instead of the Engagement Studio Program. We made this choice as it can give us more flexibility in what is provided in the Task and how it can be assigned. If you really want to keep that in the Engagement Studio Program, you certainly can!
  • Twilio does charge PER SMS, so be careful when selecting your audiences, especially during testing!
  • Working with External Activities in Pardot is still somewhat limiting, in that you can only look for “a record with a specific value.” You can’t look for External Activities created in the last X days or anything like that, so it really is a “First Response” mentality.
  • If you have multiple Twilio sending numbers, you could expose this as an input variable in your Flow and External Action, so that it can be specified when sending a message.

Happy Building! And Let Us Know If You Need Help

External Actions and External Activities are a great way to leverage other solutions with Pardot. But as you saw, there is still a lot that needs to be built to glue it all together. 

We hope this guide is helpful so you can take it on and build this solution yourself. And you can always reach out to Sercante to build this solution for you if you’re ready to hand it over to the experts. Visit our contact page here to raise your hand, and we’ll get back to you ASAP.

Original article: Twilio SMS Messages and Pardot: A Complete Guide

©2022 The Spot. All Rights Reserved.

The post Twilio SMS Messages and Pardot: A Complete Guide appeared first on The Spot.

By |2022-12-30T18:51:09+00:00December 30th, 2022|Categories: Pardot, Pro Tips|

Creating a Custom Pardot Campaign Influence Model: Lessons Learned

Sometimes the standard Campaign Influence models that come with Marketing Cloud Account Engagement (Pardot) just don’t quite fit what you are looking to measure. We recently went through the exercise of creating a Custom Model, and it wasn’t quite as straightforward as we would have liked it to be. 

To save you some ramp-up time we’ve decided to share some of the things we learned. Here they are!

Lessons Learned the Hard Way while Creating a Custom Pardot Campaign Influence Model

We went ahead and created a custom Pardot Campaign Influence model and took excellent notes so you can reap all the benefits. 

Here’s what you should know before you start your own custom Pardot Campaign Influence Model project.

Simplify your Custom Model, then nail it down

There’s a lot of calculations needed in Campaign Influence, and the last thing you want to do is build this a few times as you discover exactly what you are looking for. 

Spend some time with the business and really think about which touches you really want to measure and if having them measured will drive meaningful business value. Can you explain it in 20 seconds or less? No? Your model might be too complex.

You have 2 options for integrating your Model

The simple example Salesforce provides as part of its documentation is to have a Trigger on the CampaignInfluence object, which allows you to create your records when Salesforce creates theirs.  This example is okay for demonstrative purposes, and it avoids a lot of the complexities. 

The example also works okay if the Model that you are “watching out for” creates and deletes CampaignInfluence records at the same time you need to. Though for us, often we discovered that we wanted our Model to recalculate, but it never did. This is because the default model didn’t need recalculating so no new records were created/edited. As a result, ours never had the chance to run. 

One way around this is to watch out for the b2bmaEvenDistributionModel as it has the most chance of adding/removing records, and firing off your trigger.

Another thing to consider (if you are relying on another model’s calculation to trigger your custom one) is that Salesforce doesn’t properly batch influence calculation. We learned this when turning off the Even Distribution Model and turning it back on hoping it would trigger calculation on all Opportunities. We ended up having our own Batch APEX class run to initially populate data for our new model.

If you need a little more control, you would need to introduce triggers on various objects (such as CampaignMember, OpportunityContactRole, Opportunity) looking for the events that would have an impact on your Model and cause it to recalculate. You might find luck here using Platform Events to separate the triggering event from all the processing that the Model might need, especially important as Opportunities often already have a lot of custom automations hanging around them.

Campaign Influence code runs as a special User

Salesforce’s CampaignInfluence records are created by a Special Salesforce User “Salesforce Administrator” which you can’t pick when setting up debug logs. You can find this User’s ID by looking at the CreatedById field of any of the CampaignInfluence records in your org.

Setting up a Debug log for this user is a bit more involved than normal, and needs you to manually create a TraceFlag entry referencing the special User as well as the Id of DebugLevel. We used https://workbench.developerforce.com ‘s REST explorer to create the record, and we used the SFDC_DevConsole DebugLevel allowing us to use the DeveloperConsole to check out the logs as we were testing.  A bit of setup for each debugging session, but worth it.

Break your code into debuggable chunks

We ran into a few different challenges as we were putting this together, and we found having our code broken up really sped up our debugging process. Each chunk of code had debug statements giving us an idea of the overall state / progress, which made it easy to quickly diagnose where things might be going awry.

While we aren’t yet ready to share a precise recipe, we can at least give you the ingredients we used!

  1. Build a list of Opportunity IDs of the Opportunities that need to be calculated
  2. Get all Opportunity details (including Opportunity Contact Roles)
  3. Get all needed CampaignMember records
  4. Calculate the “winning” CampaignMember records for each Opportunity
  5. Calculate the CampaignInfluence records needed from the “winning” CampaignMember records
  6. Insert final results

Plan for custom Campaign Influence Model success

Creating a Custom Campaign Influence Model is not for the faint of heart. It takes quite a bit of planning and work to put together even the simplest of Models (which might be why there’s so little out there when we tried googling for examples). 

If you are looking to take this on, hopefully these tips save you a bit of frustration and colorful language. If it still looks daunting and you need some help, we would love to have a chat!

Further Reading

Original article: Creating a Custom Pardot Campaign Influence Model: Lessons Learned

©2022 The Spot. All Rights Reserved.

The post Creating a Custom Pardot Campaign Influence Model: Lessons Learned appeared first on The Spot.

By |2022-10-19T18:44:00+00:00October 19th, 2022|Categories: Analytics & Reporting, Pro Tips, revive, Strategy|

External Actions: The Long-Awaited Pardot Feature

Alas, Salesforce External Actions for Pardot is finally here.

Until now, our options to have Marketing Cloud Account Engagement (Pardot) trigger a third-party system have been limited to either: pre-existing connectors or syncing to Salesforce and relying on a Salesforce-side integration. 

With the Salesforce Winter ‘23 release, External Actions gives us the capability to integrate into any third-party system and do cool things. It’s a far cry from having true webhooks. Though, it is a step in the right direction. 

(We’ve built something to fill in the gap. Drop us a line — we’re happy to talk details with you).

Note: This feature is available to Plus, Advanced, and Premium editions of Pardot.

The Lowdown on External Actions for Pardot

External Action allows Pardot to do things like: 

  • Send an SMS message via Twilio or MogliSMS
  • Create a new Salesforce record (such as Lead, Opportunity, any Object!)
  • Send information to your favorite Star Wars API
  • Register a Prospect in another system
  • and whatever else you dream up! 

While there are some considerations (detailed later in this post), External Actions are a great way to plow through the barriers that have prevented you from automating your entire workflow. 

It’s important to note that there’s a similarly named feature called External Activities.  With Pardot External Activities, you can receive data from third-party systems to use in Pardot. With External Actions, you can send data to third-party systems so they can do cool things.

How does a Pardot External Action work?

Once an External Action is built, it will appear as an Action option in an Engagement Studio Program. Depending on the action, you may need to provide additional information through text inputs. You can use HML Merge Tags here, too!

When the Engagement Studio Program is running and hits your action, Pardot will call into Salesforce (via API behind the scenes), and call the functionality.  It does this in a “fire and forget” manner, so there’s no error handling inside your Engagement Studio Program. It is also not “bulkified,” meaning it will make an API call for EACH Prospect. So, you may need to take the API limits of Salesforce AND your external system into consideration.

For this blog post, we built an External Action that tracks Favorite Color. 

Once you pick “Track Favorite Color” you have the ability to provide a value. In the screenshot below, we are using HML to pull this value from a Prospect’s record, though you can also provide static text if you want to say everyone’s favorite color is Sercante Green.

How can I set up a Pardot External Action?

To set up an External Action, there are 2 key pieces:

  1. You need something in Salesforce that can “do the thing” you want. It can be any of the following:
    • Autolaunched Flow
    • External Service
    • APEX InvocableMethod
  2. Marketing App Extensions have been configured inside Salesforce Setup

No-code options to configure Pardot External Actions

If you are looking to integrate with a third-party system, you might luck out on #1 and be able to leverage something built by that third-party in their Salesforce package. This could be your quickest way to being able to use an External Action.

If this isn’t available for you, first look at seeing if you can make an Autolaunched Flow that can meet your needs. This option is also great for creating Salesforce Records of any object type (keeping in mind you are limited to text input types in Pardot).

When working with another API, and if that API supports the OpenAPI protocol, you can use Salesforce External Services to hook things up. That will give you everything you need.

 The Trailhead Module on External Services is a great way to learn how to get started.

Code option to get started with Pardot External Actions

If the above aren’t an option, it’s time to break out your development skills (or work with someone who has them). We’ve got a sample APEX class here that gives you all the structural ingredients you need to make this work, you just have to fill in what you want it to actually do.

public class MyNewExternalAction {

    // Classes to be used by the Flow Designer
    public class FlowRequest {
        @InvocableVariable(label='Prospect Email')
        public String email;
        @InvocableVariable(label='Favorite Color')
        public String favColor;
        // add any other String or number-based attributes you need
    }

    // If you are calling an External API, this would be a great
    // place to put Classes to represent the response
    public class ApiResponse {

    }
    
    @InvocableMethod(callout=true label='My New External Action')
    public static void performActions(List<FlowRequest> flowRequests) {
        System.debug('Start performActions');
        // at time of writing, Pardot DOES NOT BATCH these, it's always 1
        // per batch
        FlowRequest flowRequest = flowRequests.get(0);
        System.Http http = new System.Http();

        try {
            // This is where you put what you want to do!
            // you can call another API, call other APEX
            // read & write Salesforce Objects.. Whatever you want

        } catch (Exception e) {
            System.debug('There was an issue executing the request');
            System.debug(e.getMessage());
            throw e;
        }
        System.debug('Done performActions');
    }
}

Once you have the functionality ready, you need to tell Pardot about it. This is done by configuring Marketing App Extensions inside Salesforce Setup.

Configuring the Marketing App Extensions

This is the “glue” that ties everything together and makes External Actions usable by Pardot. There are a few easy things to configure to make this “glue” work.

First, we need the Top-Level Marketing App Extension. Be careful with these, as you cannot delete them once created (so don’t go making a bunch of test records!).

  1. In Salesforce Setup, search for Marketing App Extensions
  2. If you don’t have one, create New
    • Provide an Extension Name and an API Name, as well as check “Active in Automations”
    • Click Save

Next, we need to enable this for Business Unit(s).

  1. With the Extension still open, go to the Related tab
  2. Click New beside Business Unit Assignments
  3. Add an assignment for each Business Unit you want this extension to be available for

Now we can create the External Action.

  1. With the Extension still open, go to the Related tab
  2. Click New beside Actions
  3. Provide an Action Name (this will be the name visible when selecting it from Engagement Studio)
  4. Provide an API Name (this does not auto-fill like you may be used to)
  5. (Recommended) Provide a description of what this Action does, since you might not remember in three months
  6. Search for your functionality. Once selected, the Action Schema will auto fill with JSON that you need to review and likely modify
  7. Review & Modify the Action Schema
    • Properties – this contains details about the parameters/values that you want to provide to the Automation.
      • type:  currently can only be “string” and “number”
      • title: the Label of the input when viewing in Engagement Studio
      • value: Allows you to provide a default value. You can use HML merge tags here!
      • Note: Sometimes when working with Flows, you might have properties that are not relevant (like flow interview id). You should remove them from Properties (assuming they aren’t an input variable that your flow requires to function)
    • View Components – this allows you to specify which properties you want to provide inputs for in Engagement Studio. Currently, definition should always be “lightning/control” and “scope” should always point to one of the properties
    • Required – a list of properties that would be required from within Engagement Studio
  8. Action Params auto fills, no changes needed
  9. When you are ready to have this available in Pardot, check the Active in Automations box.

Here’s what it would look like for our sample APEX class above. Note that we’ve chosen to only display the favorite color field in the Engagement Studio, though we are passing the Prospect’s email behind the scenes.

Save the Action and, after a few moments, it will be available for testing!

Can I use an External Action to do things in Pardot?

Imagine being able to take action on another Prospect record from an Engagement Studio Program! While not natively available within the platform, you could build this when combining External Actions with our Free package Flow Actions for Pardot. After setting up the package, you would only need to configure the Marketing App Extension to have any of our Flow Actions available as an External Action.

Create Unified Experiences with Pardot External Activities

External Actions are available with the Winter ‘23 release. These Actions, as well as External Activities, allow Marketers to automate across platforms for a more unified experience. 

How do you plan on using these features to better automate your processes? Tell us in the comments!

Original article: External Actions: The Long-Awaited Pardot Feature

©2022 The Spot. All Rights Reserved.

The post External Actions: The Long-Awaited Pardot Feature appeared first on The Spot.

By |2022-10-13T14:36:51+00:00October 13th, 2022|Categories: API & Integration, Automations, New Features, Release Notes|

How to Update iFrames & References to the Default Pardot Domain Before the Deadline

In early March, Salesforce announced changes to how it serves content via go.pardot.com. In short, this impacts your Pardot content that might be placed on your website through iFrames. 

We’ll walk you through how to find where the go.pardot.com domain is in use. Then we’ll show you how to fix it across your website.

A bit of detail on the Pardot domain challenge

Pardot is making security enhancements that can affect users of the go.pardot.com domain who use this domain for iFrames. That means you’ll have to take action by April 22, 2022, to update your website forms that meet the criteria outlined in this blog post.

Website forms with iFrames + default Pardot domain + JavaScript = pay attention

Specifically, you should pay attention to the enhancements if your website forms:

  1. Embed Pardot forms or other content inside iFrames
  2. Include JavaScript in that content
  3. Serve this content over the default Pardot domain (go.pardot.com)

The main impact will be to any Pardot form served standalone or in an iFrame using the go.pardot.com domain.

Also included are forms that make use of included JavaScript to make external calls. This includes JavaScript that:

  • Communicates from within the iFrame to the pages that contain the iFrame
  • Makes an AJAX call to a server

Examples of these kinds of calls are:

  • JavaScript that resizes the iFrame on the page to better fit the form
  • Submission of forms using reCAPTCHA
  • Changing form behavior based on changes to the email address field, such as showing a message to a prospect if they previously unsubscribed

Other impacts with assets using iFrames are possible. For example, with these new changes you will no longer be able to embed a landing page within another webpage. This change also affects JavaScript callouts on form handlers and dynamic content when served directly via an iFrame.

Preparing for the fix

There are a few preparatory steps you can do before going and making (or requesting) changes to your website.

Step 1. Set up Pardot tracker domain

If you don’t already have a Pardot tracker domain, we will need to create one. If you aren’t sure, here are steps to follow:

  1. Log in to Salesforce & Pardot
  2. Go to your Pardot Settings > Domain Management page
  3. Look for a tracker domain that is custom. It should be one that’s similar to your website address (similar to the screenshot below)

If you don’t have a custom tracker domain set up yet, our friends at Nebula Consulting have a great set of instructions here.

If you have multiple tracker domains, you will need to know which one to use.

Step 2. Enable first-party cookie tracking

While not necessarily needed for this fix, it is best to set yourself up for success for the future of cookie tracking within Pardot.

To enable first-party web tracking cookies:

  1. Log in to Salesforce & Pardot
  2. Go to your Pardot Settings, Account Settings page and click Edit
  3. Scroll down to “First-Party Tracking” and make sure all 3 checkboxes are checked
  4. Save account

Step 3. Find website pages using the go.pardot.com domain in iFrames

I mean this is the whole reason you are here right? You have a challenge and want actionable steps on how to actually solve it instead of some blogger babbling.

We’ve created a tool that can leverage your website sitemap .xml file (the same sitemap Google crawls) to look for web pages that have embedded iFrames that also use go.pardot.com as the iFrame source.

Use the form below to find the forms on your website you’ll need to update. After submitting, we’ll gather some results and email them to you after a few minutes.

Name








Make changes to the website

With your list of pages in hand, you can begin the work of editing each page, swapping the go.pardot.com part of the iFrame “src” attribute with your new tracker domain. Try this out on one or two pages, testing out the forms to make sure nothing has broken. Then, roll it out across your site.

But… what if I can’t add a custom tracker domain?

You might ask yourself, “What if I can’t add a custom domain?” If this is you, you’re gonna be okay. 

Because of the change being made, you won’t be able to use iFrames with the default go.pardot.com domain to host standalone or embedded forms. If you plan on using a form, you’ll need to use the form on a landing page. If you have JavaScript needed for the form, it can be included in the landing page to keep the form functioning as it did before. 

If you have other assets you need in an iFrame, unfortunately you won’t be able to continue using the default domain to display them. You’ll need to get creative with these assets. Maybe convert the information into a downloadable PDF or display it as an image on a landing page.

It’s going to be okay

With new Pardot security enhancements comes a more stable marketing automation platform. But it also brings new complications — and we have your back. 

If you need further assistance with setting up a custom tracker domain, finding and fixing the use of go.pardot.com, or just a refresher on best practices, get in touch or tell us in the comments. We’re always happy to help.

The post How to Update iFrames & References to the Default Pardot Domain Before the Deadline appeared first on The Spot for Pardot.

By |2022-03-29T13:40:58+00:00March 29th, 2022|Categories: Data Management, Emails & Forms, Pro Tips, revive|

Implementing Pardot External Activities Natively in Salesforce

Pardot is delivering a whole new way to leverage your prospect data in the Salesforce Winter ‘22 release. Our earlier blog post covers this new feature and how to set up the Pardot External Activity in Salesforce so any third-party service can begin sending these activities to Pardot via API. This post explains what third-party services need to do to send these activities to Salesforce using Salesforce declarative solutions (Flow/Process builder). 

At a high level, we need to:

  • Configure Salesforce to allow our solution to call the Pardot API
  • Implement Salesforce APEX code to handle the Pardot API request
  • Add an action to a Flow to make use of our new code
  • Test

This solution is a little more technical than our post on Zapier. Once you are done, you will end up with a Flow like this:

Start Record-triggered flow

Configure Salesforce

Any time we want to work with the Pardot API, we need to “authenticate” with Salesforce in order to get an Access Token. 

First, follow the steps in our earlier blog post Connecting to Pardot API from APEX. By the end, you should have:

  • A brand new Connected App (to avoid issues, don’t re-use previously created Connected Apps unless they were created using the instructions above) 
  • Named Credential for connecting to the API 

Salesforce APEX code

To build this capability, we need to create an @InvocableMethod so that our Salesforce declarative automations can see it and call it to do our bidding.As with any code solution, there are a variety of ways that we can tackle this. The code sample below will work for readers with one Pardot Business Unit. The original code file (and APEX Tests) can be found in our GitHub repository: export-activities-sfdx

public with sharing class PardotExternalActivityPublisher {
    public static final Integer HTTP_REQUESTS_PER_BATCH = 50;
    public static final String ONLY_ONE_BUSINESS_UNIT_ID = '0UvB00000004000AAA';
    public static final String NAMED_CREDENTIAL = 'APEX_Pardot_Credential';

    public class ExternalActivity {
        // @InvocableVariable(label='Business Unit Id')
        // public String businessUnitId;
        @InvocableVariable(label='Extension' required=true)
        public String extension;
        @InvocableVariable(label='Type' required=true)
        public String type;
        @InvocableVariable(label='Value' required=true)
        public String value;
        @InvocableVariable(label='Prospect Email' required=true)
        public String email;
    }

    @InvocableMethod(label='Send Activity to Pardot')
    public static void sendActivityToPardot(List<ExternalActivity> activities) {
        //Very quickly pass this request into the ASYNC Queue, eliminating delays for Users
        System.enqueueJob(new QueueablePardotCall(activities));
    }

    /**
     * Handles Asynchronously firing each Activity to Pardot
     */
    public class QueueablePardotCall implements System.Queueable, Database.AllowsCallouts {
        private List<ExternalActivity> activities;

        public QueueablePardotCall(List<ExternalActivity> activities) {
            this.activities = activities;
        }

        public void execute(System.QueueableContext ctx) {
            //depending on how many Activities we are processing, 
            //we might hit the APEX limit of 100 Web Callouts
            List<ExternalActivity> remainingActivities = new List<ExternalActivity>();
            Integer processedCount = 0;

            for(ExternalActivity activity : activities) {
                if(processedCount < HTTP_REQUESTS_PER_BATCH ) {
                    HttpRequest req = new HttpRequest();
                    req.setHeader('Pardot-Business-Unit-Id', ONLY_ONE_BUSINESS_UNIT_ID);
                    req.setHeader('Content-Type', 'application/json');
                    // req.setHeader('Pardot-Business-Unit-Id', activity.businessUnitId);
                    // activity.businessUnitId=null;

                    req.setEndpoint('callout:'+NAMED_CREDENTIAL+'/v5/external-activities');
                    req.setMethod('POST');
                    String body = System.JSON.serialize(activity, true);
                    System.debug('Submitting: ' + body);
                    req.setBody(body);
                    Http http = new Http();
                    try {
                        http.send(req);
                    }
                    catch(Exception e) {
                        //we fire it off and don't do anything if there's an error
                        //probably not the best approach for Production, though it will
                        //be up to you how to handle it
                        System.debug('There was an error submitting the External activity');
                        System.debug('Message: ' + e.getMessage() + '\n' +
                                        'Cause: ' + e.getCause() + '\n' +
                                        'Stack trace: ' + e.getStackTraceString());
                    }
                    processedCount++;
                }
                else {
                    //we will process this in the next batch of Payloads
                    remainingActivities.add(activity);
                }
            }
            if(!remainingActivities.isEmpty()) {
                System.enqueueJob(new QueueablePardotCall (remainingActivities));
            }
        }
    }
}

To use this code, make sure you replace the Business Unit ID at the top of the code with your Business unit ID (to find this, navigate to Salesforce Setup > Pardot Account Setup).

For readers with multiple Pardot Business Units, remove the constant ONLY_ONE_BUSINESS_UNIT_ID and then uncomment the businessUnit lines throughout. You will need to either specify the Business Unit ID in your Flow, or you could write additional APEX to iterate through your Pardot Business Units by working with the PardotTenant object in Salesforce.

You might also want to specify how you want to handle any exceptions you get from making the Pardot API call. In our example, we simply write exceptions to the debug log.

Our APEX code does assume that the Contact has synced over to Pardot already. If you can’t make this assumption, you may consider calling a Pardot Form Handler to make sure that the prospect is in Pardot already. We have an APEX example for that too (which follows a very similar pattern, so it should be easy to merge them).

Adding an Action to a Flow

Once the APEX has been deployed, you will now be able to use it declaratively.

In our example, we have a Zoom Webinar Member (which is a Junction Object between a Zoom Webinar and a Contact).

To set this up in a Flow:

  1. Navigate to Setup > Flows
  2. Select “New Flow” or edit an existing Flow
  3. Select the + symbol to add a new Element, select “Action”
  4. In the “Search all actions” window, locate “Send Activity to Pardot”
  5. Provide a meaningful Label and Description
  6. Set your input values
    1. Extension: Enter the name of the Marketing App Extension you created in Salesforce
    2. Prospect Email: Source the email from one of the fields/variables in your flow
    3. Type: Enter one of the activities you set up and associated with your Marketing App Extension in Salesforce
    4. Value: Enter (or source from a field/variable) the unique value to identify this Activity, event IDs work great here
  7. Click “Done”
Send activity to pardot

Test

Once all elements of your Flow are ready, testing can begin. Activate your Flow and perform the action you are using to trigger the Flow. After a couple of moments, check the Pardot prospect you are testing with, and you should now see all the information you passed through.

prospect activities

Testing is a little bit tricky, for two reasons:

  1. We are executing this functionality asynchronously, meaning a problem won’t show up in Salesforce like you are used to seeing. Debug logs will be your friend here. But don’t worry, there isn’t too much to sort through.
  2. If the Named Credential or anything else isn’t quite set up right (from step 1), Salesforce and debug logs aren’t very helpful in troubleshooting. You will have to painstakingly go through the instructions again to make sure that nothing was missed / done incorrectly.

Considerations

  • The Export Activity API call only works for known prospects, and it will not work if the email address is not already associated with a prospect in your Pardot Business Unit (this is why we have the form handler in our example).
  • If you have multiple Pardot Business Units, there is no intelligence of “choosing the right one.” You need to target the right one with your APEX solution, which assumes all prospects going through this code are from the same Pardot Business Unit. As we mentioned in the APEX section, you have the flexibility to code whatever you need to handle your business case. 

 For assistance with this or other Pardot External Activities, reach out to Sercante!

The post Implementing Pardot External Activities Natively in Salesforce appeared first on The Spot For Pardot.

How to Implement Pardot External Activities with Zapier

Pardot is delivering a whole new way to leverage your prospect data in the Winter ‘22 release. Similar to webhooks, the new Pardot External Activities feature allows users to receive data from third-party systems and use the data in automations and Engagement Studio Programs. For instance, you could record when a prospect registers for a webinar, completes a survey, or watches a video.

In an earlier blog post, we describe how to set up the External Activity in Salesforce so a third party can begin sending activities to Pardot via API. This post will detail how to actually send the activities with Zapier. Similar approaches can be done with other meta-services. If you want hands-on help, we’d love to work with you.

Pardot External Activities Zapier Solution

Before we get started, it is important to note that Zapier doesn’t actually support this Pardot API request. Zapier only supports four of the many API requests possible, so we will be taking advantage of the Zapier Webhook capability to build our solution.

At a high level, we need to:

  • Configure Salesforce to allow our Zap to make API requests to Salesforce and Pardot
  • Create a new Zap which listens for a third-party event (such as registering for a Webinar)
  • Enhance the Zap to submit prospect information to a Pardot Form Handler
  • Enhance the Zap to get an OAuth token from Salesforce
  • Enhance the Zap to publish the External Activity (which works well as the Form Handler has ensured the Prospect exists already)
  • Test

Now I realize this is a lot, but don’t worry, we’ll walk through it all. Once you are done building this Zap, you’ll end up with something like this:

Configure the Salesforce Connected App

Anytime we want to work with the Pardot API, we first need to “authenticate” with Salesforce to receive an Access Token that can be used with the Pardot API. To do so, create a new Salesforce Connected App for Zapier. We highly recommend creating and testing this new Connected App by following the steps in our earlier blog post, Pardot API and Getting Ready with Salesforce SSO Users.

Once you have created your new Connected App, you should have a new Salesforce and Pardot User for the Zapier connection. Keep the user’s username, password, and security token handy for later.

In our example, we will be creating a Zap for a Zoom Webinar Registration. Due to the way Zoom Webinars are integrated with Zapier, you will need to create a Zap for each webinar, as well as creating automations in Pardot for each webinar. This may vary depending on which App you are using in Zapier.

Create a new Zap in Zapier

  1. Log in to your Zapier Account
  2. Create a new Zap and give it a name
  3. Find the third-party app that will trigger this Zap. For our example, we’ve chosen Zoom.
  4. Select your Trigger event. For our example, we have chosen “New Registrant”.
  5. Choose the Zoom account for your connection. If you haven’t already connected the app, now will be your chance!
  6. Next, (and this might differ based on your app), select the upcoming webinar you wish to integrate.
  7. Click “Test trigger”
    1. This often works best if you have a recent “event.” For Zoom webinars, it helps if you have at least 1 person who has already registered for the webinar via the Zoom registration page. In doing so, you will see sample fields and values, making the process a bit easier. 
  8. Finally, click “Continue” and you should have a nice clean “trigger.” Zapier will prompt you to make your first Action.

Enhance Zap to submit the Pardot Form Handler

Zapier now has a handle on prospects registering for the selected webinar, now we need to send this information to Pardot. 

In this first Action, we are going to send details about the person who registered for the Zoom webinar to a Pardot Form Handler. This allows us to create/update a Pardot prospect with the right field values.

Why are we using a Form Handler instead of API calls? 

  1. This approach greatly simplifies the integration by natively handling new prospect creation.
    1. Reduces sync errors for new prospects who have not interacted with a Pardot form yet
    2. More cost effective and efficient than using the Read API to create new prospects
    3. Ensures duplicates are not accidentally created
  2. The action that the person took will actually show up as Prospect Activity. This is good since they took real action and submitted a form.
  3. You can apply Completion Actions, which are not available in the API.

Make sure you have the Pardot Form Handler created and that you have the field names and the https URL handy.

  1. Continuing from the previous section, create a new Webhook Action by selecting “Webhooks by Zapier.”
    1. This step is important to establish who is registering and to make sure we associate the External Activity with a prospect. 
  1. For the Action Event, choose POST.
  2. Set up the action by filling in the following fields:
    1. URL: The https URL of your Pardot Form Handler
    2. Payload Type: form
    3. Data: Enter the Pardot Form Handler field name, and the values coming from the trigger setup earlier. Add new “rows” for each field you wish to populate in the Pardot Form Handler based on your trigger data available.
  3. Once you have finished setting up the Action, test the action, check that the Pardot Form Handler was called, and verify that the data is where it should be.
  4. Rename the Action to “Send Registration Info to Form Handler” so that it’s clear what this Action is accomplishing. 

Enhance Zap to get OAuth token from Salesforce

Now things start to get a bit tricky. Since we can’t leverage the Pardot app in Zapier, we need to do things manually. This is where we will use the Salesforce and Pardot User we set up with the Connected app in the first section.

  1. Create a new Webhook Action by selecting “Webhooks by Zapier”
  2. For the Action Event, choose POST
  3. Set up the action by filling in the fields:
    1. URL: https://login.salesforce.com/services/oauth2/token
    2. Payload Type: form
    3. Data -> grant_type: password
    4. Data -> client_id: Enter the Consumer Key from your Connected App
    5. Data -> client_secret: Enter the Consumer Secret from your Connected App
    6. Data -> username: Enter the Salesforce Username of the Pardot user we will use for API calls
    7. Data -> password:  Enter your Salesforce user’s password followed by the Security Token
  4. Once you’ve provided all the values above, Test and Review. A successful request should show values like access_token and instance_url for your Salesforce org.
  5. Rename this Action to “Get Salesforce OAuth Token” so that it’s clear what this Action is accomplishing. 

Enhance Zap to publish Pardot External Activity

Finally, we will send the External Activity to Pardot

  1. Create a new Webhook Action by selecting “Webhooks by Zapier”
  2. For the Action Event, choose POST
  3. Set up the action by filling in the fields:
    1. URL: https://pi.pardot.com/api/v5/external-activities
    2. Payload Type: json
    3. Data -> extension: Enter the name of the Marketing App Extension you created in Salesforce
    4. Data -> type: Enter one of the Activities you set up and associated with your Marketing App Extension in Salesforce
    5. Data -> value: Enter a unique value to identify this Activity, event IDs work great here
    6. Data -> email: Enter the email address that was used in step 3 of the “Enhance Zap to submit the Pardot Form Handler” section
    7. Headers -> Authorization: This one is a bit tricky to fill out. First, when you click in the text box, type “Bearer “ (with the space) and then select the Access Token.
    8. Headers -> Pardot-Business-Unit-Id: Enter the ID of the Pardot Business Unit that is associated with the Marketing App Extension. You can find the Pardot Business Unit ID by navigating to Salesforce Setup >Pardot Account Setup. (Detailed instructions here).
  4. Once you’ve provided all the values above, Test and Review. Check the Pardot Prospect for the new Activity record. This activity will appear between the Prospect Activities and Custom Fields section of the prospect page.
  1. Rename this Action to “Send External Activity” so that it’s clear what this Action is accomplishing. 

Test

Now it’s time to test our Zap end-to-end. 

Activate your Zap and perform the action that you are capturing in the Zap’s Trigger (i.e. register for the Zoom webinar). After a couple of moments, check the Pardot prospect that you are testing with. You should now see all the information you passed through the Zap!

Considerations

  • The Export Activity API call only works for known prospects, and it will not work if the email address is not already associated with a prospect in your Pardot Business Unit. This is why we have the form handler in our example.
  • If you have multiple Pardot Business Units, there is no intelligence of “choosing the right one.” You need to target the right one with your Zap, which assumes all prospects going through this trigger are from the same Business Unit. Proceed with caution and test rigorously when attempting more advanced solutions with business units.
  • Salesforce only allows five access tokens to be issued at a time. With high volumes of a triggering event, it is possible that Zaps may fail due to Salesforce Access tokens getting recycled before they can be used in the following actions (this is due to us manually getting an Access Token with the second Action).
  • Any time the user’s password and/or security token changes in Salesforce, each ZAP that uses it will also need to be updated.

These considerations are best addressed by writing your own code, which can properly address the edge cases, etc. For assistance with this or other Pardot External Activities, reach out to Sercante!

The post How to Implement Pardot External Activities with Zapier appeared first on The Spot For Pardot.

By |2021-10-15T18:27:46+00:00October 15th, 2021|Categories: Data Management, Integration, Pardot Business Units, Release Notes, Salesforce|

Using the Pardot Integration from Zoom App Marketplace

Integrating Pardot with Zoom webinars allows you to not only collect prospect activity in real time, but also track attendance, handle communications, and send sales new leads quickly and easily. Using the Zoom-native Pardot App simplifies sharing data between these two systems by allowing you to capture Zoom webinar registrants, attendees, and absentees within Pardot lists. 

In this post we’ll cover the pros and cons of this integration as well as walk you through the setup process for a webinar. 

At a high level, to integrate Zoom and Pardot you will need to:

  1. Install and set up the Pardot App from the Zoom App Marketplace.
  2. (Optional) Configure Custom Zoom Registration Fields to go to Pardot.
  3. Start creating Zoom webinars.
  4. Prepare your email notifications.

Considerations for Using the Pardot App from Zoom App Marketplace

Before we dig in, there are a few things to consider when using this native integration:

  • The integration works best when using the Zoom registration form. 
    • There is an option to use a Zoom Post URL (similar to how we think about Pardot Form Handlers). However, this option relies on the Thank You page of the Pardot Form having an additional hidden form that changes per webinar. This hidden form must be completed and requires JavaScript for a behind-the-scenes submission. That makes this option prone to human error and/or browser issues. 
  • Both email solutions leave something to be desired. You can choose between: 
    • Emails styled in Zoom with prospect-specific URLs to join the webinar. With this option you’ll lose out on Pardot tracking and personalization capabilities.
    • Your beautiful Pardot email templates with all the benefits of Pardot data, tracking, and personalization, but no Zoom webinar details or prospect-specific URLs to join the webinar. 
  • This process will not connect prospects with the associated Salesforce campaign. You’ll need additional automations if that’s part of your strategy. 
  • Each webinar requires its own setup and configuration. These take between 1-3 hours each, depending on how granular you get with automations. As a result, this integration is better suited for companies that have a low volume of webinars.
  • There is no mechanism to pull in questions and answers from webinar polls.

Install and Set Up the Zoom Integration App 

  1. Navigate to the Pardot App on the Zoom App Marketplace and sign into your Zoom account. 
  2. Select “Install” from the top right of the Pardot App listing page.
  3. Once installed, you’ll see a prompt to enter your Pardot credentials. If you are not redirected to this screen, click “Manage” from the left-side navigation, scroll down, and click “Configure”). Select “Use Salesforce SSO.”
    Use Salesforce SSO
  4. Next, install a very tiny managed package provided by Zoom. This package creates a connected app to allow Zoom to connect to your org. Click “Install Package” and install this for Admins only.
  1. While the package is installing, create a Salesforce and Pardot user for your Zoom integration. Having one user per integration helps in the event that you need to troubleshoot your Pardot org and/or integrations. Once the user is set up, log in as this user to authorize and approve the app.  
  2. Next, provide Zoom with the Pardot Business Unit ID. You can find the Pardot Business Unit ID by navigating to Salesforce Setup > Pardot Account Setup (you can access detailed instructions here).
    Enter credentials
  3. Select “Save”

Zoom and Pardot are now connected, and they are ready to work together!

(Optional) Configure Custom Zoom Registration Fields Sync to Pardot

Zoom automatically passes most of the common fields directly into Pardot. This includes: 

  • Email
  • First Name
  • Last Name
  • City
  • State/Province
  • Zip/Postal Code
  • Country
  • Phone
  • Job Title
  • Organization
  • Industry
  • Questions & Comments
  • Employees

You can also create new fields in Pardot to sync Purchasing Time Frame and Role in Purchase Process from Zoom. 

Depending on what information you are looking to capture in Pardot, you may decide you want to have Zoom pass more fields into the prospect record. A good example of a field you may wish to connect is “Join URL.” This field is a prospect-specific URL that will allow the prospect to join the webinar. 

To add this field, simply:

  1. Navigate to Pardot Settings > Object and Field Configuration > Prospect Fields. Select “+Add Custom Field.”
  2. Complete the required info and select “Create Custom Field.”
  3. Once created, go back to the Pardot App in the Zoom Marketplace and select the “Custom Field Mappings” tab.
  4. Map the Zoom Registration Field “webinar_join_link” to the Pardot Custom Field that you created. Click “Add.”

Your new custom field is now connected. Future registration captured by Zoom will pass the Zoom Webinar Join URL to your Pardot prospects. But please note, the prospect record will only have values from the latest registration.

Start Creating Zoom Webinars

You will need to configure the Pardot integration for every webinar you create in Zoom. 

  1. First, create three static lists in Pardot so Zoom knows where to send the data. You will need a:
    • Registration List
    • Attendee List
    • Absentee List

Make sure you use naming conventions so these lists are easy to find in Zoom and any Pardot automations. 

  1. Next, create or locate the webinar in Zoom. Select the webinar name to view details. 
  2. Select the “More” tab and then select “Configure” within the Integration section.
    create a zoom webinar
  3. Provide Zoom with the static lists you created in Pardot. All three lists are required.
    Provide zoom with pardot static lists
  4. Click Save

Now your lists will be kept current with the right prospects!

Prepare Your Zoom Webinar Email Notifications

Getting prospects to register for a webinar is only half the battle. Now we need to get them to attend! Registration and reminder emails are key here, and getting the right message delivered at the right time will make all the difference.

Both Zoom and Pardot can be used to send these emails, each having their own considerations.

Considerations for Using Zoom Email Notifications

Zoom email settings can be configured at a Zoom Account level (i.e. for your entire company) and at a webinar level. You can customize email templates only at the Account level, and you can’t have webinar-specific templates.

  • Registration emails can include the prospect-specific Join URL and are sent immediately after registration.
  • Reminder emails can include the prospect-specific Join URL and can be sent 1 hour, 1 day, and/or 1 week prior to the webinar.
  • Follow-up emails can be sent 1-7 days after the webinar ends.

Considerations for Using Pardot Email Notifications

With Pardot, create an Engagement Studio program or Automation Rules to automatically send out your registration, reminder, “thank you for attending” and “Sorry we missed you” emails. These automations should look for Prospect that join the webinar’s three static lists.

  • If you configured your integration to send the Zoom Webinar Join URL to Pardot, this value can be included in registration emails sent from Pardot. 
  • Reminder emails can also include the Zoom Webinar Join URL, however if the prospect registered for multiple webinars in close proximity, the Zoom Webinar Join URL on the Prospect’s record may not match the webinar you are reminding the prospect about!
  • Follow-up emails can be sent whenever you like. You can even choose to send a different email template to those who register and attend versus those who register and are absent.

Try the Sercante Connector for Zoom Webinars and Pardot

As mentioned above, if you have a low volume of webinars, this process may not be an issue, especially since the integration is the low-low price of free. However, if you’re hosting one webinar per week (or more), then this process is pretty daunting. 

If you need to scale up your Zoom-Pardot integration, check out the Sercante Connector for Zoom Webinars and Pardot

What other tools or webinar platforms are you looking to integrate with Pardot? Tell us in the comments!

Special thanks to Erin Duncan for contributing to this post.

The post Using the Pardot Integration from Zoom App Marketplace appeared first on The Spot For Pardot.

By |2021-09-23T16:49:58+00:00September 23rd, 2021|Categories: Email Marketing, Event Management, Events, Integration, Zoom|

Pardot Protected Campaign Member Statuses Solution

Get a solution for Protected Campaign Member Statuses in Pardot and step-by-step instructions for installation.

We go through all the effort of setting up beautiful Salesforce Campaigns, naming standards and maybe even a hierarchy. The next challenge in completing your beautiful work of campaign art is getting a hold on your Campaign Member Statuses for each campaign.

When a new Salesforce Campaign is created, many people aren’t just happy with the two default statuses of Sent and Responded. This prompts them to create what they think makes the most sense. Though as time goes on and as reporting starts to be needed, everyone making their own Campaign Member Statuses can be a nightmare that prevents you from getting meaningful and actionable intelligence. It would be really nice to take the guesswork out of status reporting and have a standard set of Campaign Member Statuses everyone uses consistently.

Jenna Molby posted a fantastic solution that enables you to automatically create the right Statuses on Campaign creation.

The automation here is good, though as you increase the number of Types the Flow could become a bit unwieldy.

Another thing that could be a problem comes later when other people might make changes to your carefully crafted structure. What happens if someone edits or even removes these statuses?

Install Protected Campaign Member Statuses

Protected Campaign Member Statuses is a free solution you can install and easily configure to solve this problem. It allows you to:

  1. Define the Campaign Member Statuses that should always be present on given Campaign Types.
  2. Restore the Protected Statuses on Active Campaigns should someone make changes.
  3. Create additional Statuses for specific reasons.
  4. Override by authorized users on a per-Campaign basis.

I don’t want the details, just let me install it

(Don’t worry. Keep reading to learn exactly what’s going on inside.)

We have an Unlocked Package you can install that sets up the application.

Get Started

Once installed, you need to define your Protected Statuses. This is done with Custom Metadata Types.

  1. Login to Salesforce Lightning, and go to Setup.
  2. Navigate to Custom Metadata Types, and click Manage Records for Protected Campaign Status.
    Pardot Protected Campaign Member Statuses
  3. To create your first ones, click New
    Pardot Protected Campaign Member Statuses
  4. Fill in the various fields.
    • Label: Used in the List of Campaign Statuses in the Setup view in step 3 above. Recommended convention:  TYPE-STATUS
    • Name: This is an API name that can be used by developers. Not required by this package. Recommended: let this autofill after you type in the Label.
    • Campaign Type: This is the actual value for the Campaign’s Type field.
    • Protected Status: This is the Status value that will become protected.
    • Is Default: Select this if this Status should be the default (please pick only 1 per Type).
    • Is Responded: Select this if this Status should be marked as Responded.
    • When complete, your screen may look something like this:
      Pardot Protected Campaign Member Statuses
  5. Click Save (or Save & New) and repeat a whole bunch.
  6. Lastly, time to set up a scheduled job to restore deleted protected statuses.
  7. Back in Setup, go to Apex Classes and click Schedule Apex.
    Pardot Protected Campaign Member Statuses
  8. Fill in the few fields.
    • Job Name: give this a nice descriptive name so you remember what it is in 3 months.
    • Apex Class: SL_ProtectedCampaignStatusJob
    • Frequency: set this to what works for you. We recommend running this daily during off-peak hours.
    • Start: today
    • End: some time in the distant future
    • Preferred Start Time: off peak hours
    • When complete, your screen may look something like this:
      Pardot Protected Campaign Member Statuses

You are good to go once you have provided your statuses. Give it a whirl by creating a new Campaign with the Type you have set up. Then take a look at the statuses already created.

Campaigns with Types not already set up will keep the default two statuses that Salesforce creates.

That’s cool. What’s behind the curtain?

To accomplish this, we leverage a few cool tools available to us:

  • Custom Metadata Types: Allows the Protected Statuses to be treated like normal Salesforce metadata and can be deployed around like any other metadata (changesets, insert devops tool here)
  • Campaign Custom Field: Has_Protected_Campaign_Member_Statuses__c is automatically checked by the solution if a Campaign is created and there are Custom Metadata Type records that specify this Campaign’s Type. It is also what allows the rest of the code to keep the statuses intact. You can clear the checkbox for this field to make changes to the statuses if you need to. However, you can’t enable protection afterwards.
  • Change Data Capture: We turn this on for CampaignMemberStatus so we can detect edits to statuses and then fix the records after-the-fact. Sadly we can’t (yet?) put any triggers on CampaignMemberStatus (which would have been ideal).
  • Triggers: yea these have been around for a while and are quite handy. We use them to kick off the automation that we’ve built when a Campaign is created. We also use them to watch for Campaign Member Status edits (through the ChangeEvents from Change Data Capture) so we can set things right afterwardsd.

If you want even more details, check out the Github project where you can see all the inner workings of what is going on.

Further Reading

Here are some resources you can use to learn more about Salesforce Campaigns and how they work in Pardot:

The post Pardot Protected Campaign Member Statuses Solution appeared first on The Spot For Pardot.

By |2021-07-16T18:27:52+00:00July 16th, 2021|Categories: Campaigns, Data Management|

Getting a List of Pardot Business Units For Your App – Programmatically

As our Pardot integrations are coping and adjusting to using the Pardot API with Salesforce SSO users, one of the new requirements is to provide the Pardot Business Unit ID in each API request. It is easy for Salesforce Administrators to get the ID, but what if we could do this with code? 

Right now, most Apps are directing Salesforce Administrators to grab the Pardot Business Unit ID  by going through these simple steps:

  1. In Salesforce Lightning, Navigate to Setup
  2. Navigate to Pardot Setup Home under Platform Tools > Pardot
  3. Next, click Assign Admin

4. On this page, you will see your Business Unit Id. Note: some people might have many Business Units!

Currently, this step can leave room for configuration errors. So now that we know how to ask for a Business Unit ID, let’s look at how  we can do this with code?  Well as you might have noticed, the Business Unit ID is a Salesforce record Id, and after a little discovery we learned that the Salesforce object name is PardotTenant.

Working with PardotTenant – REST API

Disclaimer: at the time of writing, PardotTenant is not documented and the Metadata Coverage Report shows basically nothing is supported.

That’s ok, as developers we are used to wanting documentation right! So let’s use Salesforce’s standard functionality to learn as much as we can.  For this exploring, we will be using the Workbench: REST Explorer.

Once you are logged in, we will use a GET request with the following path: /services/data/v50.0/sobjects/PardotTenant/describe

Here’s a breakdown of what we think the key fields are and what we can use:

  • Id: The Business Unit Id that is used for the API
  • PardotTenantName: The Business Unit Name that we see beside the ID in Setup.
  • PardotTenantAccountType: We’ve seen Production and Demo as values, could be used to determine which Pardot URL to use for the API
  • PardotTenantId: The Pardot Account ID that you see in Account Information in Pardot’s Settings page.

Now that we know what the fields are and what may be of use to us (for the application we are working on right?), we can use a new REST call to get the list of PardotTenants with the following path: /services/data/v50.0/query?q=SELECT+Id,+PardotTenantName,+PardotTenantAccountType,+PardotTenantId+FROM+PardotTenant

Great, we know what REST calls need to be made and the format of the response. The tricky part is getting our Connected App to be correctly configured to enable us to get the information we need.

There are 2 key things that you need to be able to use the Salesforce REST API and get a list of Pardot Business Units.

  1. A Connected App which includes the API scope.
  2. A Salesforce User with at least a Platform license.

Needing at least a platform license is where things can get tricky.  Normally for working with the Pardot API, a User with the Identity License (along with the Connected App) is good enough.  Identity Licenses don’t provide access to most of the Pardot objects, PardotTenant included.

Troubleshooting REST Errors

This is pretty tricky, and even just writing this post I came across a few errors.

Session is not valid

[{"message": "This session is not valid for use with the REST API", "errorCode": "INVALID_SESSION_ID"}]

You will get this error if your Connected App is missing the API scope, even if your Salesforce User can see the PardotTenant object.  Simply edit your Connected App, add the API scope, wait a few minutes and then try again.

Invalid Type or The Requested Resource Does Not Exist

There could be 2 causes for you getting one of these 2 errors.

The first is that the Salesforce Org you are connecting to just might not have Pardot setup. Pretty easy to check why.

The next (that I’m not 100% sure why yet) seems to be when I used an Access Token that I received from a Username/Password Oauth authentication request, but when I issued a JWT Bearer flow authentication request this worked fine.  For production-level code, it’s best to not use Username/Password flows anyways, but during experimentation this might cause a small issue.

Working with PardotTenant – APEX

This is pretty simple, we can use a plain old SOQL statement to retrieve the information we need.

List<PardotTenant> pardotTenants = [
        SELECT Id, PardotTenantName, PardotTenantAccountType, PardotTenantId
        FROM PardotTenant
        WHERE IsDeleted = false];

However, if you are working on a Managed Package, you might get a lot of packaging complaints about PardotTenant not being available to you. In that case, you can do something a little more dynamic:

public List<PardotTenantDto> getBusinessUnits() {
        List<sObject> pardotTenants = Database.query(
                'SELECT Id, PardotTenantName FROM PardotTenant WHERE IsDeleted = false');

        List<PardotTenantDto> businessUnits = new List<PardotTenantDto>();
        for(sObject pardotTenant : pardotTenants) {
            businessUnits.add(new PardotTenantDto(
                    (String)pardotTenant.get('Id'),
                    (String)pardotTenant.get('PardotTenantName')
            ));
        }
        return businessUnits;
    }

Conclusion

Depending on your app, it might provide a better user experience to allow users setting up their Pardot connection to select from a list of Pardot Business Units, in order to help reduce the chance of configuration errors. Exploring the PardotTenant object might be a great way to get you to being able to do this. Have questions or need help exploring if this is the right path for your app? We would love to help. Reach out or shoot a question in the comments.

The post Getting a List of Pardot Business Units For Your App – Programmatically appeared first on The Spot For Pardot.

By |2021-03-08T18:29:51+00:00March 8th, 2021|Categories: Integration, Pardot SSO Update|

Pardot API and Getting Ready with Salesforce SSO Users Part 3A: Connecting to Pardot API from APEX

The Pardot User-Migration deadline is fast approaching. There is a lot of guidance on setting up our human users for success, but what about our code? Currently, there is a lack of specifics available on how to make changes to custom code & scripts that talk to the Pardot API. So we wrote this guide specifically for connecting Pardot API from APEX

Also See Part 3B: Connecting to Pardot API from Custom Code.

We’ve come across our fair share of APEX code written in Salesforce that works with the Pardot API, and in the past it was fairly simple to set up. Just get the username, password and API key of the Pardot User, copy some APEX code examples and you were ready to go.  Now that we need to authenticate through Salesforce SSO, we’ve taken the time to detail out what you need to set up. Hang on, as there’s a lot to do. In summary we will:

  1. Create a new User for this integration
  2. Create a Salesforce Self-Signed Certificate
  3. Create a Connected App, allowing our User to be pre-authorized
  4. Create a Named Credential
  5. Write some Basic APEX that demonstrates this all working

Step 1: Create a new User

It is our recommended advice that each integration has its own user. For this Pardot integration, a Salesforce User (with an Identity License profile) linked to a Pardot SSO User should be sufficient.

In Salesforce, create a new user, commonly using the Identity Profile.

  1. In Salesforce Lightning, Navigate to Setup
  2. Navigate to Users under Administration > Users, click on New User
  3. Use the following values (or use whatever makes sense for you)
    1. First Name: Pardot
    2. Last Name: APEX
    3. Alias: pdotapex
    4. Email: use an email address you have access to
    5. Username: create a username that uniquely identifies this integration
    6. User License: Identity
  4. When complete, the section should look like this
  5. Using the Salesforce activation email, be sure to login, which will ask you to set a password and recovery options. Save this info somewhere.
  6. If you are using User Sync, complete one more step: in Salesforce Setup navigate to Pardot Setup > Account Setup > Manage Users. Edit User Assignments and make sure your new user is Selected (or is added as a member of a selected group or role).

In Pardot, create a new user (skip step 1 if you are not using User Sync): 

  1. If you are using User Sync, update the profile and role mapping to make sure the Salesforce profile (e.g. Identity User) is mapped to a Pardot Role that matches the abilities you want your API integration to have.
  2. Navigate to the Users page in Pardot by navigating to Admin (Pardot Settings in the Lightning app), and then User Management | Users.
  3. Click the +Add User button and complete the required information, using the same values (where possible) that you used when creating the Salesforce User
  4. In the CRM Username dropdown menu, select the new API integration User you created in Salesforce.
  5. When complete, the section should look like this
  6. After saving the new User record, click the “Enable Salesforce single sign-on” link. (If you have already enabled User Sync for this user/profile, this will be completed automatically.)

A Permission Set is what will enable our User to connect via the Connected App without needing to manually authorize it.

  1. In Salesforce Lightning, Navigate to Setup
  2. Navigate to Permission Sets under Administration > Users, click on New
  3. Use the following values (or use whatever makes sense for you)
    1. Label: Pardot API Access
    2. API Name: let it auto populate
    3. Description: Grants access to Pardot via API. No permissions specified
    4. Click Save
  4. Add the new Permission Set to the User created/chosen above
    1. When viewing the Permission Set, click Manage Assignments
    2. Click Add Assignments, and select the correct User

Step 2: Create a Salesforce Self-Signed Certificate

Certificates are actually composed of 2 pieces: a private key (often called just a key) and a public key (often called just a cert/certificate). For our purposes, the private key is used to “prove” that it is actually your code that is trying to login, and is the reason that passwords and security tokens are not required. For our purposes, the public key is used to verify that the correct (authorized) process is trying to access Salesforce.

  1. In Salesforce Lightning, Navigate to Setup
  2. Navigate to Certificate and Key Management under Security, click Create Self-Signed Certificate
  3. Use the following values (or use whatever makes sense for you)
    1. Label: Pardot Integration Certificate
    2. Unique Name: let it auto populate
    3. Key Size: Leave it as the default value
  4. When complete, the section should look like this:
  5. Save the Certificate
  6. Once saved, click the Download Certificate button, as  you will need it when setting up the Connected App later on.

It is important to note that this certificate is only going to be valid for 1 year. You can create a longer-lived certificate, but you will have to import it from a Keystore and we will leave that for another blog post.

Step 3: Create the Connected App

A Salesforce Connected App is how you enable external code / systems access to use the Salesforce API.  Now it may seem a little weird as your APEX is already inside Salesforce, however the Authentication methods work the same way.

  1. In Salesforce Lightning, Navigate to Setup
  2. Navigate to App Manager under Platform Tools > Apps, click on New Connected App
  3. Use the following values for Basic Information
    1. Connected App Name: APEX Access to Pardot
    2. API Name: (let it auto populate, or make up your own name)
    3. Contact Email: use a company email address
    4. Description: Grants access to Pardot from our APEX
    5. When complete, the section should look like this:
  4. Use the following values for API (Enable OAuth Settings)
    1. Enable OAuth Settings: Checked
    2. Callback URL: https://login.salesforce.com/services/oauth2/callback
    3. Use digital signatures: Checked
    4. Browse: Use the certificate you downloaded earlier
    5. Selected OAuth Scopes:
      1. pardot_api (allows you to actually call the Pardot API
      2. offline_access (allows your code to make API calls when it needs to)
    6. When complete, the section should look like this:
  5. Save the new Connected App, click Continue after observing the warning
  6. From the Saved Record screen, take special note of the Consumer Key, you will need to use it in your APEX

Pre Authorize User to use Pardot API

Regardless of how the Connected App was set up (above), we need to pre-authorize the correct user to use the Pardot API.

  1. In Salesforce Lightning, Navigate to Setup
  2. Navigate to App Manager under Platform Tools > Apps, find the APEX Access to Pardot app, click the drop down menu and then Manage
  3. Click Edit Policies
  4. Under OAuth Policies > Permitted Users, change to: Admin approved users are pre-authorized, Save
  5. Back at the Connected App, new sections have appeared. In Permission Sets, click Manage Permission Sets
  6. Assign the Pardot API Access permission set

Step 4: Create a Named Credential

The Named Credential is what allows your APEX code to login and be able to actually use the Pardot API.

  1. In Salesforce Lightning, Navigate to Setup
  2. Navigate to Named Credentials under Security, click New Named Credential
  3. Use the following values
    1. Label: APEX Pardot Credential
    2. Name: (let it auto populate, or make your own name)
    3. URL: https://pi.pardot.com/api (adjust if https://pi.demo.pardot.com/api)
    4. Certificate: leave this blank, this is used for 2-way SSL connections
    5. Identity Type: Named Principal
    6. Authentication Protocol: JWT Token Exchange
    7. Token Endpoint URL: https://login.salesforce.com/services/oauth2/token (adjust if test.salesforce.com)
    8. Issuer: OAuth Consumer Key that you created earlier
    9. Named Principal Subject: The username of the User you want to use (from the first steps of this post)
    10. Audiences: https://login.salesforce.com (adjust if required)
    11. Token Valid for: 30 Seconds
    12. JWT Signing Certificate: Pardot Integration Certificate
    13. Callout Options: leave all these at their default settings.
  4. When complete, this section should look like this
  5. Save

Sample Working APEX

The following APEX code can be called to demonstrate a working solution.

public class PardotTesting {
    public static void tryItOut() {
        HttpRequest req = new HttpRequest();
        req.setEndpoint(‘callout:APEX_Pardot_Credential/account/version/4/do/read?format=json’);
        req.setHeader(‘Pardot-Business-Unit-Id’, ‘0Uv4W0000000056SAA’);
        req.setMethod(‘GET’);
        Http http = new Http();
        HTTPResponse res = http.send(req);
        //Ideally you would parse the JSON response and work with it
        System.debug(res.getBody());
    }
}
Key things to note:  Setting the Request’s Endpoint, the Name of the Named Credential is used in the String. Following the Named Credential is the rest of the Pardot API endpoint you want to hit.

Conclusion 

Following the above steps will get your code ready for SSO in preparation for the February 15th deadline. Have some additional insights? We would love for you to  share your experiences and tips as you work through getting your code ready for SSO. Stuck and need help – let us know and we would be glad to help audit your unique instance needs

CONTINUE READING:
Pardot API and Getting Ready with Salesforce SSO Users Series: 

The post Pardot API and Getting Ready with Salesforce SSO Users Part 3A: Connecting to Pardot API from APEX appeared first on The Spot For Pardot.

By |2021-02-02T16:43:28+00:00February 2nd, 2021|Categories: Pardot SSO Update|