Using Formula Fields to Group Data in Salesforce

A common ask I get in Salesforce is how to group data based on it’s characteristics – for example grouping random Industries into tighter categorizations or grouping people’s Job Titles into defined ‘Personas’. This makes it simpler to analyze and target your data – instead of dealing with disparate Industry or Job Title values users can now focus on cleanly grouped data. The solution to this problem is a formula field in Salesforce – I’ll walk through how to set up a formula field to return a ‘persona’ for a Contact based on it’s Job Title:

Let’s say you have a few predefined Job Titles that you want to group into ‘Personas’ for your outbound marketing efforts:

  • ‘Marketing Persona’ – anyone with the word ‘Marketing’ in their Job Title
  • ‘Sales Persona’ – anyone with the word ‘Sales’, ‘Support’, or Account’ in their Job Title
  • ‘Executive Persona’ – anyone with the word ‘Chief’ or ‘President’ in their Job Title

Create a Formula Field in Salesforce that returns Text:

Use the ‘If’ and ‘Contains’ functions on the Job Title field to return your personas if the record’s Job Title contains a relevant value:

The value of using a formula field here is as the Personas change it’s just an update to the formula field – for example if you want to add ‘VP’ the Executive Persona, just add in that line item. Here’s the compiled formula:

IF(CONTAINS(Title,’Marketing’), ‘Marketing Persona’,
IF(CONTAINS(Title, ‘Sales’), ‘Sales Persona’,
IF(CONTAINS(Title, ‘Support’), ‘Sales Persona’,
IF(CONTAINS(Title, ‘Account’), ‘Sales Persona’,
IF(CONTAINS(Title, ‘Chief’), ‘Executive Persona’,
IF(CONTAINS(Title, ‘President’), ‘Executive Persona’,
NULL))))))

How to automatically attach new Notes & Attachments to related records in Salesforce:

Here’s the requirement: when a new Note & Attachment is added to a child record automatically associate it with a related record, too. In this case we’re using PandaDoc on the Order object – when the PandaDoc is completed the Order is automatically ‘Released’ and when the Order is released the completed PandaDoc should attach to the Order AND the related Opportunity. PandaDoc automatically attaches the completed document to it’s related order – this is out of the box functionality. The challenge was relating the completing document to it’s Opportunity, too.

This was easy to accomplish with a flow using the ContentDocumentLink object. Here are the steps:

  • Create a Flow that triggers on, in this case, the Order Object. When Order Status is changed to ‘Released’ trigger the flow.
  • The first Get Records Query in the Flow should check if there’s a ContentDocumentLink where the LinkedEntityID matches the triggering record. This is how we determine if there’s actually a Note & Attachment on this object:
  • Add a Decision element to confirm if there is a ContentDocumentLink. If there is a ContentDocumentLink that means we have a Note & Attachment that should also be shared with the Opportunity so continue the flow. If there is not, just end the flow:
  • If there is a ContentDocumentLink to this parent record, then we just need to create a new ContentDocumentLink where the ContentDocumentID is the record found in the Get Records Query and the new LinkedEntityID is the ID of the related record from the triggering record. In this case the Opportunity ID is already written on the triggering record, but you could add another Get Records query to get related record IDs as needed:

The full flow looks like this – pretty simple:

Daisy Chain to SalesLoft and Outreach

A super common ask I get is how to move a person from marketing automation (Hubspot, Marketo, Apollo) over to a SalesLoft Cadence or Outreach Sequence. Typically the goal is: the person takes some action based on marketing automation emails so this action should result in the person moving to a Cadence or Sequence – basically, a higher level of engagement. If the marketing automation is connected to Salesforce, and if the SalesLoft or Outreach is connected to Salesforce this is easy. As long as the data is running through Salesforce the necessary fields get set on the record in Salesforce these fields sync to the engagement platform, then a trigger rule is used to add the person to a Cadence/Sequence on field update. Here’s the Cadence in SalesLoft:

You can add exclusions so they’re not in any other Cadences and the same logic works with both SalesLoft and Outreach. It’s a good concept: you use marketing automation as your ‘air cover’ – marketing automation is what’s daily or weekly emailing tens of thousands of records. If, during the course of these tens of thousands of emails there’s some interaction – a link click, a website visit – then change their status in marketing automation, this syncs to Salesforce which syncs over to your sales engagement tool and moves the record to a sales rep’s Cadence or Sequence. This is how records can move further down the funnel from marketing to sales. With this in place, focus on keeping the top of the funnel marketing going and as records take action they’ll automatically move to sales engagement.

Purging Records in Marketo with Salesforce

Anyone who manages a Marketo knows they bill based on volume of records in the system so there’s a constant battle to keep the number of records under the billing cap while still keeping any potential leads available for marketing. Way back in the day I used to just export the inactive records to csv every 3 months or so, then when we needed new records mine that data for anything of value, add back in and attempt to warm up. If your Marketo is integrated with Salesforce, though, there’s a more sophistacated approach that manages the ‘remove from Marketo’ automatically while mainting the data in Salesforce in case any records enliven later on. Here are the steps:

  • First, make sure you have the ‘Marketo – Do Not Sync’ field available between your Salesforce and Marketo. You can ask Marketo support to enable this field for you.
  • Next, if you don’t already have one add a TRUE/FALSE field to indicate if the record has been ‘Deleted from Marketo’. Sync this field with Salesforce with a default value of false.
  • Create a Smart List in Marketo of all records you’d like to delete on a rolling basis. Records with no Activity in the Last 90 Days, for example.
  • Now, create a Smart Campaign in Marketo that keys on this Smart List. In the Flow Step, first set the field ‘Deleted from Marketo’ to TRUE and set the field ‘Marketo – Do Not Sync’ to TRUE. In the next step, sync the record to Salesforce. Add a wait step (maybe five minutes) then set to ‘Delete from Marketo’ but not from the CRM.
  • This Smart Campaign, then, keys on your Smart LIst to regularly find the records for deletion, sets the proper fields on these records, syncs them to Salesforce, marks they so they don’t come back to Marketo, and deletes them from Marketo.
  • You can track the records in Salesforce that have been deleted from Marketo by using the ‘Deleted from Marketo’ field.
  • If you have duplicate rules on in your Salesforce and the record happens to come back in to Marketo – the duplicate rule will catch the record as it attempts to come in to Salesforce from Marketo. You can create a Smart List in Marketo to review records that have failed to transfer to Salesforce.
  • The Smart Campaign in Marketo looks like this:

Custom Object Report Chart Components

Here’s something I just took an inordinate amount of time researching, then quickly cobbled together the solution. The request is to add a Report Chart Component to an Account Page layout to show data on a custom related object. Most of the information I saw online for adding a report chart component to a record was predicated on there being a natural relationship between the standard objects – i.e. how to show Number of Opportunities on an Account. In my case, I needed to show Number of Custom Records on Account. There was an easy report of the Custom Object with Account Name in it – that should work! It didn’t. There was already a relationship between the Custom Object and the Account – but the standard Custom Object report didn’t work. What does? You have to create a new Custom Report Type with Account as parent and your Custom Object as the child:

Create the new custom report type, now using this report type create your report (in my case the same report I’d created earlier on the custom object – but this time with the new custom report type):

Then on the Account Page you want to add this Report Chart Component, add it over and set the filter to be on Account ID (or whatever your parent object is):

The trick here is creating the Custom Report Type. You might have two related objects and want to show data from one object on the other. You might have standard reports for those objects – but if you want the parent object to have a Report Chart Component that automatically filters the report to just that parent record you have to first build a Custom Report Type between this Parent and Child, then create your report and add the Component. Fun!

Implementing a Sales Process in Salesforce

I’m regularly asked about implementing a sales process in Salesforce so I’ll add my notes and a fairly standard sales process in Salesforce below. First – Leads or Contactcs? In my opinion, it doesn’t really matter. You can map Leads to Accounts (using Email Domain/Domain) so both Leads and Contacts are always linked to Accounts. Just call them ‘People’. I’ve worked in orgs that ‘don’t use Leads’ (only Contacts) and that causes confusion in itself as people regularly find themselves looking at Leads, or looking for Contacts that are Leads that never converted. Link Leads to Accounts and use them both as ‘People’. Next – when to create an Opportunity? Create an Opportunity when a demo is set – this way Opportunities track your demos. If you’re creating an Opportunity and the person you’re demoing with is a Lead – you’ll need to convert the Lead and add as an Opportunity Contact Role on the Opportunity. Opportunities should require Opportunity Contact Roles. An Opportunity created when a Demo is Set is ‘pre-pipeline’ – outside of demo tracking numbers no reason to include demos set in your pipeline forecasting. If the person doesn’t show up for the demo or the demo is a bad fit, the Opportunity is closed/lost (with reason ‘no show’ or ‘bad fit’). If the demo shows some promise then the Opportunity is advanced and goes in to pipeline.

Sales reps are assigned Accounts. They should be logging activity against those Accounts regularly. If reps own Accounts but aren’t logging activity they should lose those Accounts. Reps shouldn’t be assigned more than 100-200 Accounts at any time and they should be logging activity. When an Opportunity is created on an Account, it’s even more important to track Activity on that Account – there should be more Activity or if no Activity over a certain period of time the Opportunity should be Closed/Lost. All people should have a Status – starting with ‘Open Not Contacted’ and moving up to ‘Converted’ (if a demo is scheduled) or ‘Unqualified’ if they’re purely a bad fit. As Opportunities advance through Stages, new fields can be required – fields like ‘Next Steps’ and ‘Success Criteria’ so the case to purchase is clearly made as the Opportunity advances.

This entire process easily translates to Salesforce by agreeing on People Statuses, Opportunity Stages and the gates by which People and Opportunities can advance. Here are high-level Stages and Statuses that I’ve used:

Opportunity Stages:

  • Demo Set (pre-pipeline, first stage) – Opp created when Demo Set
  • Sales Qualified Opportunity (pipeline – 10%) – demo was successful, there are next steps, sales sees potential here.
  • Evaluation / Validation (30%) – Company has a defined need for this solution and is evaluating this and similar solutions
  • Reviewing Proposals (50%) – company has confirmed budget for the solution.
  • Verbal Approval / Vendor of Choice (80%) – we have verbal notice that we’re the selected company at the pricing discussed.
  • Closed Won – require notes for CS for hand-off
  • Closed Lost – require Closed/Lost reason (i.e. ‘Budget’, ‘Competitor’)

People Statuses:

  • Open – Not Contacted – The default stage for any newly added, or untouched person.  This can change to the next stage automatically when an Activity is logged.  Expectation is if a rep has 20 Accounts and 100 People they have almost 0 people in ‘Open – Not Contacted’.  If people come in through form fills they should be in ‘Open – Not Contacted’ for as little time as possible.
  • Working – Contacted – The status a person moves to when it has Activity logged against it.  Reps should only contact people at Accounts they own or are assigned to avoid overlapping work.  The majority of people assigned to reps should be in this status.  We can add automation to lower the status on a person if no Activity is logged to the record in 30 days.
  • Nurture – person is not being actively worked by a rep but rep reviewed and there’s potential.  These records should go to marketing campaigns (monthly newsletters).  This status is for people who have shown some interest but are not likely to buy in the next 6-12 months.
  • Unqualified / End of Cadence – people that were in ‘Working’ but never responded after 30 days move to this status.  These records showed no response to any outreach or were unqualified by the rep.  We can require ‘Unqualified Reason’ for records moving to this status.
  • Opt Out – people that responded to an email to specifically opt out.
  • Qualified / Converted – status for the record when a demo is set and Opportunity is created.

So the basic sales process looks like this:

  • Reps are assigned Accounts to work.  AE type reps are assigned few, larger Accounts; SDR type reps are assigned more, smaller Accounts.  We can mark these different Account types on the record in Salesforce.
  • AEs and SDRs can ‘DQ’ an Account to indicate it’s not a good fit – they’re required to add a ‘DQ Reason’ to explain why it’s not a good fit.
  • AEs should have 50-100 Accounts at any one time; SDRs 100-200 Accounts at any one time.
  • Activities are logged against the Accounts.  AEs can keep Accounts for longer than SDRs.  If no Activity is logged to an Account for 30-60 days the rep loses the Account so another rep can work it.
  • Reps have their assigned Accounts and a pool of Accounts (assigned to the Admin) that they can pull from.  Reps should never have more than 200 Accounts at any one time and should continuously be logging activity to their Accounts.
  • An Opportunity is created when a demo is set.  If the Opportunity is created by an SDR, they transfer the Opportunity to their AE.  The AE conducts the demo and either advances or closes the Opp.  The AE provides feedback to the SDR on the Opportunity so the SDR knows how the demo went.
  • If there are form fills there’s either a rep dedicated to inbound, or an alert goes to all SDRs when a form fill comes in.  The new person is either ‘first come first serve’ (the first rep to own it keeps it) or if the person is related to an assigned Account that rep gets the person.  This new person should go to ‘Working’ status as soon as possible.
  • Advanced Opportunities (in to pipeline) are what SDRs strive for.  AEs manage their pipeline and commit to the revenue at higher stages in the pipeline.

Custom integrations with Salesforce

I’ve been asked three times in the last six months for suggestions on integrating home-grown, thrid-party tools with Salesforce. These are systems completely separate from the Salesforce ecosystem where you’re going to be building something custom. A few years ago we used this architecture to integrate a third party payment system with Salesforce and it worked very well. To this day I’ll recommend this approach when integrating a third party with Salesforce and Unoffical SF has done us the favor of building out this integration pattern in a more configurable way. Unofficial SF’s Webhook to Flow package takes the same architecture but adds the flexibility of a Flow. At a high level the process looks like this:

  • Create a custom site in your Salesforce – this will be the endpoint your third party will send data to.
  • Create a ‘listener class’ invoked when anything is posted to that site to process the data.
  • Listener class translates the data from the json it arrives as to something workable by Salesforce.
  • Create a staging table (custom object) to store the data coming to this endpoint and processed by your listener class.
  • Use either apex or flows to translate the data from your staging table to other objects in use by your users.

This is a simple mechanism to expose an endpoint, trigger events when data is pushed to that endpoint, then move workable data into your Salesforce for users. I’ve used this mechanism multiple times for moving third party data in to Salesforce and processing into something the business can combine with other data.

Product Revenue Schedules for Renewals in Salesforce

In lots of the Salesforce orgs I’ve worked in over the years the renewal process is managed through Opportunties. When a new business Opportunity is Closed/Won a Renewal Opportunity is automatically generated and the Account Manager (or CSM) is responsible for managing the renewal. This is typically on an annual renewal basis – and you can automatically generate renewals for more or longer periods of time as needed. I was recently asked about monthly renewals, though, which led to some research comparing the Opportunity generation process versus Product Revenue Schedules in Salesforce. I’ll add my analysis here:

Opportunities vs. Revenue Schedules for Renewal Business:

  • Use ‘Renewal Opportunities’ if each month there’s an actual renewal – that renewal business must be won each month.
  • Use ‘Revenue Schedules’ if the monthly revenue is assumed and there’s no business to win each month.
  • If recognizing an agreed on monthly revenue then use ‘Revenue Schedules’, if each month there’s a negotiation and won business then use Opportunities.
  • If using Revenue Schedules you’ll need to define the timeline for the Revenue Schedule associated with each Product.

For either approach you can:

  • Automatically generate the renewal Opportunity (or Opportunities) or Revenue Schedule, or Renewal Opportunity with Revenue Schedule on New Business Opportunity Closed/Won.
  • Automatically set values on the Opportunities or Revenue Schedules to indicate likelihood the revenue comes in to allow for forecasting existing business.
  • Adjust future predicted revenue as needed.

Advantages of Revenue Schedules:

  • Out of the box MRR tracking for Closed Business in Salesforce.
  • Very configurable – can adjust pricing and configurations on Revenue Schedule records for forecasting purposes.

Disadvantages of Revenue Schedules:

  • Tied to Products so you’d need to introduce a Product or Products in order to use.  Products are probably a good thing to get started on anyway.
  • Introducing 2 new objects – Product and Revenue Schedules – adds complexity.

Advantages of Opportunities:

  • No need to introduce new products.
  • If each month the revenue is not assumed based on the initial deal then Opportunities are a better fit.  We can still set forecasting values for the Opportunity to indicate likelihood to close.
  • We can use Opportunity Forecasting which is out-of-the-box Salesforce functionality.

Disadvantages of Opportunities:

  • Less structured than building out a Product Catalog with Revenue Schedules.
  • Potentially lots of extraneous Opportunities generated that are irrelevant.

My Suggestion:   Use Revenue Schedules if the monthly revenue is assumed and there’s no business to ‘win’ each month.  Use Opportunities if each renewal is ‘won’ each month.  If business is ‘won’ each month we’ll want to track the won and lost business to understand why we’re winning and losing.  If the business is assumed each month, then Revenue Schedules are much simpler. 

Last Activity Date in Salesforce

One of the most important fields to track in Salesforce is Last Activity Date. If you’re assigning Accounts to sales reps, you’ll likely want to track the last activity on those Accounts so Accounts that aren’t being actively worked can be re-assigned. Further, you may want to track currently open Opportunities based on their Last Activity Date to ensure that open Opportunities are actively being worked. Activity often correlates to setting Opportunities and moving Opportunities through the pipeline.

If you’re using Outreach, in Outreach under Settings >> Plugins >> Salesforce >> Contacts you can set which Activities from Outreach to track back to Contacts in Salesforce:

With this you can track in Salesforce who is opening your emails and clicking your links – both are indicators of potential interest in what you’re selling. The Last Activity Date on Accounts in Salesforce, though, is comprehensive of every activity on the Account. Therefore, you may find you want a custom Last Activity field in Salesforce to capture the date of certain outbound activities. This helps to differentiate any activity vs. pre-defined outbound activities. To do this, create a custom Date field (‘Last Activity Date’) on the Account object in Salesforce, then use a flow to set this field based on pre-defined activities coming from Outreach – for example ‘Outbound’ Emails from ‘Outreach’:

That’s a simple flow in Salesforce that fires on Activity create (after create), only fires if the activity meets the defined input criteria, then gets the parent Account and sets the current date. This way, you can track activities users take on Accounts based on your own defined criteria instead of what Salesforce offers out of the box. Finally, since this new Last Activity Date is on the Account, you can use a simple formula field to pull this field down to Opportunities for Opportunity Last Activity tracking,

Mailchimp on Contacts in Salesforce

Mailchimp has a nice connection with Salesforce to sync records back for ongoing marketing campaigns. Mailchimp captures good data on those campaigns (opens, clicks, unsubscribes) that is not natively added to the Contact record in Salesforce so that sales reps in Salesforce can prioritize those Contacts interacting with ongoing email campaigns. Mailchimp does have a little inline page we can add to Lead or Contact records:

but we wanted to get Mailchimp data directly on the Contact, instead of having to click through to inline pages just to get high level details.

Mailchimp has two related objects that can be used to move Mailchimp activity to their parent Lead or Contact: Mailchimp Subscriber and Mailchimp Activity. The Mailchimp Subscriber object offers the direct relationship from Lead or Contact to the record over in Mailchimp. The Mailchimp Activity object is a child object of the Mailchimp Subscriber and maintains all activities that subscriber has taken. Therefore, to get Mailchimp Activity up to the Lead or Contact we have to go through the Mailchimp Subscriber object. Once on the Mailchimp Subscriber object, we can just use a formula field from Lead or Contact to Mailchimp Subscriber to show the Last Activity. That’s done through a fairly simple process: create a text field on Mailchimp Subscriber called ‘Last Activity’ then create a Flow on Mailchimp Activity. When a Mailchimp Activity record is created, set a text variable to the name of the Last Activity – then, find the parent Subscriber record and set this custom field with the variable. Update the Mailchimp Subscriber record. With the Last Activity text field set on the Subscriber, then use a simple formula field on Lead or Contact to pull this value on to the Lead or Contact record:

Now, on Leads or Contacts in Salesforce we can report on Mailchimp Last Actions: