Show Notes: Deep Work, Digital Minimalism, and the Key to a Happy Retirement

I have been a longtime subscriber of The Mad FIentist and he recently did an interview with Cal Newport of Deep Work fame. Cal just released his latest book Digital Minimalism and this interview was a mix of many things I’m interested in: meaningful work, productivity, and financial independence. I enjoyed the podcast so much that I went back and listened to it again while taking notes.

My notes are below along with the timestamp of where that topic starts in the podcast. This is not a transcript just my interpretation of the interview. When a block of text is italicized, that’s me putting in my own two cents about how it relates to my life.

Listen to the full episode here:

0:00 Why Cal Newport on this podcast? His work has been incredibly influential to Brandon (The Mad FIentist) who has FIRE’d and helps ask and guide you on those questions of what to do with your time and what will bring you happiness. So not a ton of direct FIRE relation but tangential.

There are a lot of people in the FIRE community who believe all they need to do is retire and then they’ll be happy. So while Cal’s advice is not about living frugally or early retirement — it is about the other side of the coin: how to be happy by finding meaning in the things you do.

2:48 On pursuing your “passion.” The pursuit of passion is overrated and the advice of “follow your passion” is trite and overdone. This was basically the premise of Cal’s 2012 book So Good They Can’t Ignore You — where he delved into the dynamics of really loving your work.

So how do people end up loving what they do? As kids you’re sold this bill of goods. “Oh if you just follow your passion you’ll be fine” but research doesn’t support that people have preexisting passions. You career satisfaction is not a matching game and there is very little evidence that people who find fulfillment in their jobs already were interested in the topics

I’m an operations professional who has fallen deep into Salesforce — I can vouch for this being true. “This” being I wasn’t born with an inherent interest for this stuff.

5:48 If passion is bogus, then what? Happiness comes from getting good at something not doing something you think you like (it’s the craftsman mindset vs. the passion mindset). The more you work the better you get and then the more you like it. It’s a virtuous cycle.

People who report high satisfaction at work experience autonomy, competence, and relatedness.

7:24 Don’t ask people for advice, ask them for their story. You’ll quickly learn that they didn’t have some preexisting thing they loved. More often to not they fell into one thing or another and they got really good at it and that is what unlocked freedom, flexibility, etc. All the things that the FIRE community wants.

8:09 So FIRE enthusiasts might be misguided in “rushing to the finish line?” Most definitely, yes because they are probably giving up career capital and the work that actually might make them happy.

What are you trying to get to? That you have these passions and if you just had more time to do them you’d be happy? Well that isn’t what the research says. It is not a major source of satisfaction. You need sense of autonomy, impact and competence and that comes from meaningful work not from scrolling on Instagram all day.

There isn’t a term for it (maybe I’ll try to invent it, how about Flex FIRE) but instead of focusing on stopping work, try to get so good that you have flexibility and focus on work you want. Then you’ll have a high sense of satisfaction and be well compensated.

Autonomy + Impact + Competence = Happiness

11:03 Okay, so we need to get good at something to find our passion and be so good we can’t be ignored. How do I do that? This question sprung out of So Good They Can’t Ignore You and is what inspired the book Deep Work. Deep work is just concentrating without distraction and in today’s age of open offices, Slack, etc. this is becoming increasingly rare. Rare things are often valuable and the ability to put your head down and focus on something that matters is becoming high point of leverage. If you are one of the few people who can cultivate the ability to concentrate without distraction, you’ll have a huge competitive advantage.

Shutting down email, putting away Twitter, etc. It’s incredible how much you can get done when you shut off the distractions.

High Quality Work = Time Spent + Intensity of Focus

I personally am amazed with how much I can get done in just an hour when I put my head down listen to Lo-Fi Beats and have my phone physically away (in my backpack or a drawer) and Slack turned off. It’s scary.

A formula that works is batching deep work. So work undistracted for 2–3 hours and you’ll really get a lot done. What doesn’t work is the sprinkling your day with appointments. It’s really hard to ramp back up from even a quick little context switch and the way a lot of knowledge workers have set up their day makes them basically work with a self-imposed cognitive handicap. It’s like we’re taking a reverse nootropic that is making us dumber.

15:22 Less work & more relaxation doesn’t actually make us happier — which is sort of a troubling concept for the FIRE movement.

Choice quotes from Deep Work: “Relaxation does not result in happiness.” “People are happier at work.” “More flow experiences = more life satisfaction.” “Flow happens when your mind is stretched when you’re trying to accomplish something worthwhile and difficult.”

So all of the above could be at odds with the FIRE movement which basically wants to work as hard as possible so they can relax forever. But is that necessarily good?

People actually like doing hard, meaningful things and it’s just not true that we need to veg. Meaningful work is engaging and rewarding. Cal spoke with Mr. Money Mustache and The Frugalwoods — these people don’t sit around and watch TV. They fill it with difficult, engaging work (building stuff, pouring concrete, chopping wood, etc.) They actually didn’t crave more relaxation.

High quality leisure is key for satisfaction. So Cal recently picked back up guitar playing — which is a quintessential quality leisure activity: high-skill, requires concentration, not easy to do, yet done purely for the pleasure of it.

So as a knowledge worker, it’s not really helpful to think that if you could chill on the couch and scroll through IG all day that you would have a better life. You need to strive to get engaged in something and seek progress in it — that will make you happy. Even my hobby — pottery — is something that I wouldn’t say is particularly relaxing. It’s actually really hard but I derive a lot of joy and satisfaction on working on something difficult and seeing results.

19:35 Skillful management of attention and choosing what you pay attention to

There is so much stuff flying around out there and so your world is really constructed based on what you are concentrating on. If you are focusing most of your attention on things that are difficult to accomplish and meaningful to you, you’ll have a life that is higher in satisfaction. What you pay attention to really influences your attitude and outlook on the world.

Take the above and compare it against scattering your attention across email, lots of apps, content that is frustrating or alarming, etc. and it can be easy to feel like your life doesn’t have a lot of meaning or focus. So that is a hidden benefit of deep work — you’re only focusing on stuff that matters to you and focusing on what matters results in happiness. Which rolls in nicely into Cal’s most recent book Digital Minimalism.

21:50 Maybe I buy these claims about technology in our professional life but what about technology in my personal life? Thus Digital Minimalism was born.

A lot of Cal’s writing is focused on work, but people are addicted to their screens in their personal life as well. Minimalism says that it’s almost always better to focus on fewer things that are the most important (which ties in perfectly with the FIRE movement).

So Marie Kondo is helping you declutter your physical life and Cal’s book is helping you declutter your digital life. Essentially taking all the apps, etc. and rebuilding but only keeping the things that matter. Step away from all the technology in your personal life for 30 days (this helps reduce the compulsive urge to check apps, etc). But what you need to do during these 30 days is get back in touch with what you are really about: what you value, what you want to spend time outside of work doing. Because you’re not just mindlessly scrolling during any second of downtime you can now sit with your thoughts and think critically and answer these hard questions.

And once the 30 days are over, you evaluate each app and thing you want to bring back into your digital life and ask if it is going to help you works towards the goals that you have outlined during these 30 days. And if the answer is no? Be cool with missing out on it, because it is probably not making your life better.

Similar with the FIRE community where people give up lots of little luxuries (i.e. a panini press) because it is not at the core of what makes them happy and moving them towards their goal of FIRE. There might be some value there, but the little bit of value you get isn’t worth the tradeoff of being distracted, anxious, etc so you should just do without it.

This is a small example but I deleted my Snapchat account a couple years ago. I only sometimes used it but I still felt a pull to check it, post with it, etc. I deleted it and sure I might be missing out on some funny Snaps from friends — but overall I’m happier because it’s one less thing to deal with.

20:42 Connection between digital minimalism and the health and fitness industry

Cal has never suggested a “plan” for his readers prior to this 30 day digital detox and he realized that it was necessary because we’re just so inundated with apps, news, alerts, etc. Basically, it’s a fresh start. There are some parallels between our technological consumption and the hyper-palatable food that was invented at the second half of the 20th century. It’s no longer enough to say “just watch your portions” because this stuff (both technology and food) has been designed to be really engaging and addictive.

The people who are most successful with the health usually have a strong guiding philosophy (keto, vegan, paleo, etc) that helps them make consistent decisions. Cal’s aha moment was that technology forces are strong enough that people need a guiding philosophy around it as well. You have to have a strong change in behavior. You have to have the dramatic break to create a reset and create clarity in your choices.

32:00 Downsides of social media

I’m only interjecting in here to say that I think social media and the internet is a huge boon for humankind. The ability to connect with like-minded people that are thousands of miles away on esoteric topics has been greatly facilitated by social media. I personally have made lots of connections with really cool people because of it. With that said, I think it is important to balance your online and offline relationships but I want to go on record to state that I think on the whole social media brings a lot of good with it.

People are constantly looking at their phone and we are making the mistake that it is the phone that has us addicted but that’s not actually true. It’s the applications on the phone that have created this behavior, mostly Facebook, Instagram, and Twitter.

Facebook was coming to their IPO and couldn’t figure out how to make money, even with the amount of users they have. And this is because social media was a static experience prior to them re-engineering the social media experience. It used to be “Oh, I’ll post something and maybe check to see if my friend has posted an update about their life.” The experience now is not about posting and reading other people’s posts but about creating a constant steam of social approval indicators. It has become an incredibly addictive formula to see if people are liking things that you do and because it is about you of course you are interested and it’s random. Sometimes you log into the app and there is stuff to see and sometimes there isn’t and that also creates desire for you to constantly check. The whole social media experience is a slot machine and there is nothing fundamental about the iPhone that makes you want to do that, it’s all because of social media apps.

We don’t need the constant companion model of social media. We are doing this for no real good reason and that is why people are getting frustrated with it.

37:50 Impact of social media on young people and our mental health

Cal spoke to a woman who worked in mental health services for college kids and she said that she has tons more kids coming in related to anxiety and anxiety related orders. She believes this is because these kids grew up with smartphones.

Jean Twenge wrote a book on this called iGen where she measured how the rise of mental health issues between Gen Z and Millennials and the key factor between the two was that Gen Z had widespread smartphone usage starting as kids. And Cal sees this as the digital canary in the coal mine — Gen Z does this behavior that we all do, but to an extreme. So if we start looking at what happens when this behavior is maxed out, when basically all discretionary time is spent looking at a screen, we see massive issues with mental health.

So the message we get out of this experiment is that our brain is not meant for this kind of consistent behavior and that constant low level sense of anxiety that we have is our brain crying out for help, “I’m not supposed to be doing this kind of high-octane, low bit-rate level of digital interaction.” This isn’t what the brain is supposed to be doing and it’s not natural.

But one thing worth mentioning: It’s hard to fill your time when you don’t have digital distraction. A lot of people use social media as a crutch so they don’t have to face the void, face themselves, answer the hard questions of “What do I want to do with my life?” So you need to get disciplined about high quality leisure activities and how you want to spend your time (like Mr. Money Mustache and The Frugalwoods and they got that straight before they added all of this free time to their lives).

Figuring out what you want to do with your life is harder than you think, especially if you don’t have the crutch of the screen.

For the FIRE crowd: You don’t want to work this hard to be “free” just to be scrolling and refreshing a screen. You better start thinking because otherwise you won’t be happy. It’s hard work to figure out what you want to do instead, but it is work that is really worth doing. These screens have been filling in for answer to this question.

Even without social media, humans have a drive to be social. Cal doesn’t have social media but still has a desire to talk to and interact with people. And that is one of the big costs of social media, you think you’re talking to people all day but your brain doesn’t recognize that as socializing and that is why we have these research studies of people saying the more they use social media the lonelier they feel. It’s because it displaces the real world socializing and seems just real enough that you think you’ll be satisfied with just internet relationships but that’s not true.

Another FIRE crowd shoutout: FIRE people are weird and willing to do drastic stuff to achieve their financial goals. Cal is sort of like that with his digital life (see: Why you should quit social media) Taking drastic steps digitally can also have massive positive impact on your life.

46:30 What’s one piece of advice you’d give to someone who is pursuing financial independence?

Skill is your greatest weapon. If you relentlessly hone a skill that is very valuable you will generate more financial options. You’ll get flexibility and freedom. A magic elixir for career satisfaction is being really really good at something. Even if that requires an in the desert apprenticeship mindset. The better you are at something the market values the more control you have over almost every other variable.

Today’s the day: Write your first Visualforce email template!

I shied away from Visualforce email templates for much longer than I should have. Mostly because there was never a burning need for me to create anything. Then, two situations arose that called for some snazzier email templates than plain text could provide. Time to write some Visualforce!

Visualforce templates are good for when you want to render information conditionally and/or you want to show a list of related records. You can’t render information conditionally in a plain text email or HTML email. And you certainly can’t show a list of records.

Read on for two examples and code samples that you can copy + paste!

The Conditional Render

I do best with real world examples, so here’s an example of a plain text email that needs a serious refresh:

V.1: Lots of superfluous information.

This email gets the job done but is missing a few things:

  1. Clear formatting that explains what the user should be looking at. There is no bolding or anything so it’s easy for the eyes to glaze over.
  2. Usage of “1” instead of “Yes.” It’s not fair to assume that your users will understand a boolean value (notice how I wrote the little explainer at the bottom to be on the safe side).
  3. There are no notes about the lead’s marketing…yet that label is there. 😕

Okay, so all the important information is there just not presented in the best light. Don’t let the perfect be the enemy of the good. Notifying your users certainly beats the alternative! But, if you’re interested in cleaning up the template slightly — read on.

V.2: Cleaner, strategic bolding, and only rendering information that matters to the user.

Let’s dig into the nuts and bolts of the code that fuels this email.

Lines 1–7: Setting up our email with a series of opening tags (if you scroll down to lines 41–44 you’ll see the closing tags). The body of your email need to be in between these tags.

You can declare who the recipient will be and what object you’re referencing — in this instance a lead.

Lines 10–17: This is the main body of the email that provides all of the lead’s contact information. Something that is frustrating with Visualforce templates is the UI doesn’t provide the merge fields for you. I recommend opening up your field list for the object in question so that you can quickly reference what their API names are.

The <apex:XX> tags are specific standard components to Visualforce and each have individual behaviors. Salesforce lists all the components available in their documentation.

<apex:outputLink> is giving me my record link. Note that my instance is not hardcoded — this is a best practice. You can feel free to copy that exactly, since it’s what I did. 😇

Lines 21–24: I used the Visualforce component <apex:outputPanel> because I wanted to render all the information below depending on whether it was visible or not.

Another way to do this would be to make each line render conditionally, but it was creating a lot of weird whitespace so I went with this solution.

The rendered aspect has me checking 6 boolean fields and 1 text field to see if they are true/populated. If so, then continue to render the information below.

Lines 27–33: This is where I conditionally render the field labels and values of my boolean and text fields. I have the following fields: Restaurants, Food & bev manufacturers, Grocery, Higher-ed Admins, K-12 Admins, Agency, and Media Kit Comment.

If any of these fields are true, I want to render the label I’ve created and bold it. For example: Media Kit Comment: I’d like to purchase $100K of advertising ASAP!

I have to conditionally render this because just because Agency is true doesn’t mean I want to the field label for Media Kit Comment to show!

Lines 35–44: This is the rest of the email, and I’m closing out the tags. Notice I put a little more text after </apex:outputPanel>. If I had put it inside the tags, it would have also rendered conditionally.

The List of Related Items

Another good Visualforce email use case — what if you wanted to show a list of records related to an object, such as opportunity line items? Completely doable with the <apex:repeat> component.

Here’s an example of an email that we send internally to another department. The parent object is called a Project and the child records are Project Tasks:

This Project had 2 related Project Tasks that needed to appear in the email.

Lines 9–15: Some styling that I just left in there because I borrowed this template heavily from another template. You could remove it if you don’t care about the table headers/rows are rendered.

Lines 19–25: I am creating the labels for the columns my table will have.

Lines 27–36: This is where the magic happens. ✨ Using <apex: repeat> I’m able to set a variable name (pt) for my related object Project Tasks and iterate over them. I also utilized <apex:outputPanel> because I only wanted to render specific records. If you want to show everything, you wouldn’t need this part.

Note the pluralization! I initially wrote {!relatedto.AcctSeed_Project_Task__r} when it should have been plural. This absolutely killed me when I first started. Read this for more details on object relationships. I’m still not great with this.

Lines 37–50: This is closing out the email with all the tags, very similar to the first email.

Lines 55–71: This is actually the same email — just in plain text format! Given that this is going to an internal user and I know their email can handle it, I probably don’t need it. But leaving it in case you have a use case for it!

Line 73: Everything needs to stay inside the final </messaging:emailTemplate> component.

If you try to build a template, let me know in the comments!

Further reading:

Creating a Visualforce email template (Salesforce docs)

Not so scary VF templates for admins (Jan Vandevelde’s blog — and what inspired me to write this post)

apex:outputPanel render logic (StackExchange post)

Thanks to Jan Vandevelde and Peter Churchill for their help while I tackled these two email templates. ☁️

Lead Source quirks in Salesforce

The lead conversion process always is a bit stressful. Fields from one object are mapping to another and you want to make sure everything is working correctly and nothing is getting overwritten. Additionally, one of the most valuable fields for sales and marketers starts with the conversion process.

That field? Lead Source.

Understanding where your leads are coming from allows your team to focus their time (and marketing dollars!) on those areas. If you go to a lot of Trade Shows and *think* they’re valuable how would you know without marking the Lead Source as such?

With all that said, here are some brief notes regarding the Lead Source field and the conversion process:

  • Leads, Contacts, and Opportunities all have a field called Lead Source. This field maps automatically upon lead conversion and is default Salesforce behavior.
  • Accounts have a field called Account Source and that populates with the Lead Source during conversion.
  • Opportunities will inherit a Lead Source one of two ways: If a user creates an opportunity during the conversion process OR if a user later creates an opportunity from that contact’s record. The contact will also be added as a Contact Role to that opportunity.
  • Account Source will not map to a new opportunity if a user creates an opportunity from the account record.
  • Upon merge of duplicates, make sure to preserve the Lead Source data from the oldest record. This is the closest thing you to truth.

⚠️ If your Account Source field is blank and you convert a lead to that account, the account will inherit that lead’s source. This is bad for data attribution. I have created a default Account Source field called “Unknown” which will prevent the lead conversion process from overwriting the source.

This goes against what the Salesforce docs say but I tested it and so did Amnon Kruvi and we had the same experience. Check out this thread for more:

Anything I missed or that you wish you knew when you starting managing the lead conversion process in Salesforce? Let me know!

Intro to Java: Classes & Objects☕️

“Why Java?” is the question everyone asks me when I tell them I’m taking Treehouse’s Beginning Java class.

My response is always the same, “Because Salesforce’s programming language (Apex) is very similar to Java, but Intro to Apex courses are few and far between.”

For context, I do not have a background in computer science or engineering. But I love Salesforce and technology and developing solutions on the Salesforce platform. When I got stuck on Salesforce’s Get Started with Apex Trailhead module, I knew that I needed to start with the basics in order to succeed with Apex in the long run.

I was familiar with an object thanks to Salesforce. At its base level, an object represents something in the world. A Pez dispenser, a go-kart, or a book. All of these things have unique attributes about them. In Java, these unique attributes are called a class.

Because I love ice cream I’m going to use that as the example for my post. 🍦

Makes sense, right? But you’re probably asking why you need a class for ice cream. It’s totally common sense that ice cream has a flavor and a color. Sure, but what if you were working with something you weren’t familiar with? An Opportunity for example?

Opportunities don’t have flavors, they have close dates and amounts. As a developer, you would have no way of knowing the potential attributes of an Opportunity without looking at its class. You’d be totally in the dark.

So a class is neat template (or blueprint) for whatever object you want to create.

Here’s my ice cream class in code:

class IceCream{
String flavor;
String texture;
String color;
String brand;

I’m declaring the class at the beginning and giving it a name (IceCream). Then inside the curly braces I’m declaring the attributes (or variables) that my IceCream class has. “String” means that I’m expecting a word as my value, i.e. mint-chocolate chip.

But what about objects? Objects are created from classes. This is called instantiation. You can create many objects from one class.

Note: If you are coming to Java from Salesforce, this concept is a bit confusing. Because in our world there are objects (like the Opportunity object) and then records created inside the object. Java doesn’t use the concept of records. They use classes (which is Salesforce’s version of an object) and then objects (which I knew as records).

Not so bad, right? In my next post, I’ll talk about modifiers (which give you a certain type of access to the variables).

Thanks to Craig Dennis & Doug Ayers for helping me with the concepts in this post.

Adventures in Salesforce formulas & validation rules with WEEKDAY(), IF(), & INCLUDES()

Formulas are one of those tricks up an admin’s sleeve that are extremely powerful and cool (or maybe that’s just how formulas make me feel.) 🤔

It almost feels like coding and you can accomplish a lot with just a few lines of formulas in a field or validation rule.

Until recently, my experience with formulas had been pretty elementary but recent projects at work and Trailhead got my gears turning and I realized the endless possibilities of formulas.

In this post, I’m going to walk through a formula I recently built and list some resources that have really helped me as I’ve expanded my formula skills.

All changes in Salesforce require clear requirements and this one was no different. I work for a company that sells online advertising. We send email blasts, newsletters, and other marketing content that advertisers can sponsor. While it’s not physical, our inventory still has restraints. For example, we only send certain email blasts on Tuesdays and Thursdays.

My Ad Operations team who is responsible for trafficking ads noticed that sometimes sales reps would put the wrong date in for a product on a contract and that would cause confusion. If the product date was Wednesday but email blasts only go out on Tuesday or Thursday some back and forth would be required to determine the correct date.

Wouldn’t it be nice if depending on the product a sales rep entered they’d only be allowed to enter specific days of the week?

Validation rules and a complex formula to the rescue! If you’re new to validation rules, check out the Salesforce docs and this Trailhead module.

I wanted the the solution to be modified by an end user and flexible. Some of our products don’t have a specific send date so I couldn’t make a solution that requires a send date or else that would be a problem.

Example of the picklist on a product record.

I created a new multi-select picklist called “Product Send Days” and put that on the Product object. Multi-selects have their downsides since they can be terrible for reporting but for this use case it was perfect. With just a couple clicks our Ad Ops team could update the days of the week our products send.

Now it’s time to flip to the validation rule and the formula. The Opportunity Product object has a relationship to the Product object, which means I’d be able to reference it in my formula. It’s import to remember that when you’re working on a formula. If there is no relationship between the objects it won’t work.

Accessing my Product Send Days field by drilling down from Opportunity Product.

IF(WEEKDAY(ServiceDate)==1 && INCLUDES(Product2.Send_Days__c,'Sunday'),false, true)

So what does the above say? Let’s break it down.

The biggest problem that I immediately saw was that I needed some way to translate the day of the week on my Product object to the actual day of the week that was being chosen on the Opportunity Product. This is where the WEEKDAY() function comes into play.

WEEKDAY checks the ServiceDate to see if it’s equal to 1, which is Sunday. ServiceDate is a field on the Opportunity Product. The INCLUDES() is a function unique to multi-select which checks to see if the multi-select has the value you want. So it’s taking my field Product2.Send_Days__c and checking to see if Sunday is selected.

We want something to happen when we ask the question “Does the ServiceDate equal Sunday and does Product2.Send_Days__c include Sunday?” So we are gonna wrap it in an IF() statement!

IF(logical_test, value_if_true, value_if_false)

We already know our logical test, that’s the WEEKDAY() and INCLUDES() where we’re checking to see if Sunday = Sunday. But here is where it gets tricky. For value_if_true we’re putting false because we don’t want the validation rule to fire. 😳

If the sales rep is entering the date correctly, we don’t want to stop them! So only if Sunday ≠ Sunday do we want it to fire. Note: If you put null instead of false in the 3rd position, the validation rule would not fire.

So now that we’ve broken down how to create it for Sunday, you just need to copy & paste to make it for the other 6 days of the week, like so:

IF(WEEKDAY(ServiceDate)==1 && INCLUDES(Product2.Send_Days__c,'Sunday'),false,
IF(WEEKDAY(ServiceDate)==2 &&
IF(WEEKDAY(ServiceDate)==3 && INCLUDES(Product2.Send_Days__c,'Tuesday'),false,
IF(WEEKDAY(ServiceDate)==4 && INCLUDES(Product2.Send_Days__c,'Wednesday'),false,
IF(WEEKDAY(ServiceDate)==5 && INCLUDES(Product2.Send_Days__c,'Thursday'),false,
IF(WEEKDAY(ServiceDate)==6 && INCLUDES(Product2.Send_Days__c,'Friday'),false,
IF(WEEKDAY(ServiceDate)==7 && INCLUDES(Product2.Send_Days__c,'Saturday'),false,

I didn’t talk about the double ampersands (&&) but that’s just a logical operator for AND. You could switch out && for AND and it would work just as well.

I thought this formula was looking pretty good…until I went to test it. Which is why you should always test before you release to your users. Remember when I said that some products didn’t have specific send days? Well in the formula above there is no place to allow for that. My validation rule is not going to let a user save an Opportunity Line without a correct send day.

So I added some extra logic at the very top.

NOT((ISBLANK(Product2.Send_Days__c)) || (ISBLANK(ServiceDate)))

Here I’m saying, “If the Send Days field is blank OR the ServiceDate field is blank, you can ignore and not fire.” I had to wrap it in a NOT() because I only want the validation rule to keep working if the fields aren’t blank.

Similar to the double ampersands (&&) the double pipe (||) means OR. You can use either!

So here is the final formula in all its glory. ✨

NOT((ISBLANK(Product2.Send_Days__c)) || (ISBLANK(ServiceDate)))
IF(WEEKDAY(ServiceDate)==1 && INCLUDES(Product2.Send_Days__c,'Sunday'),false,
IF(WEEKDAY(ServiceDate)==2 &&
IF(WEEKDAY(ServiceDate)==3 && INCLUDES(Product2.Send_Days__c,'Tuesday'),false,
IF(WEEKDAY(ServiceDate)==4 && INCLUDES(Product2.Send_Days__c,'Wednesday'),false,
IF(WEEKDAY(ServiceDate)==5 && INCLUDES(Product2.Send_Days__c,'Thursday'),false,
IF(WEEKDAY(ServiceDate)==6 && INCLUDES(Product2.Send_Days__c,'Friday'),false,
IF(WEEKDAY(ServiceDate)==7 && INCLUDES(Product2.Send_Days__c,'Saturday'),false,

As promised, here are some resources that have helped me a ton in my formula journey:

Shout out to Natalya Murphy who sat with me at WIT DC’s #SalesforceSaturday to work on this with me. ☁️

Let me know in the comments if you’ve tried a similar formula or if you would have done it differently!

How to use Salesforce Outbound Messages & Zapier to celebrate a closed won sale in HipChat 💸 🎉

I’ve always found Zapier to be a cool tool, but never thought of an application to use it at Industry Dive. My colleague had set up a few Zaps between Google Sheets & Salesforce and had showed me the gist of Zapier, which got my wheels turning.

Then, this happened in our sales chat:

I mean, #duh.

Spoiler Alert: This post is not about how I managed to get specific songs to play from Spotify to Sonos. We’re still using a human for that part of the equation — but if you have ideas, let me know in the comments! 🎵

We quickly polled the sales team to get everyone’s favorite song. Given that we didn’t want complete chaos on the Sonos we decided to limit playing a rep’s song to closed won deals over $15,000. This happens just infrequently enough that it would be special.

So here is where Zapier comes in: How could we notify the team in our HipChat room the second a deal was closed that met that criteria? A simple Workflow Rule in Salesforce would allow me to email the team, but a HipChat is exponentially more fun. 💬


Before following the below instructions, make sure you have the following or else you’ll just get frustrated.

  1. A paid subscription to Zapier. Salesforce is a “premium” application which means you can’t access it on Zapier’s free plan.
  2. A System Admin profile or Modify All Data permissions in Salesforce. Or, just send this to your friendly Salesforce admin, I’m sure she’d be happy to set this up for you. ☁️
  3. Ability to get the an Admin Auth Token from HipChat. This is what Zapier uses to “call” HipChat and access the HipChat room you want to message. This was the piece of the puzzle I didn’t have access to so I just hunted down one of our HipChat admins, asked them the generate the token and then send to me.

Step 1: Open up Salesforce & Zapier and set up the Outbound Message

If you have dual monitors, this will make it a lot easier so that you can flip between the two apps.

In Zapier create a new Zap and select Salesforce then type in “Outbound” into the Salesforce Trigger search. You’ll then be asked to connect your Salesforce instance to Zapier, so go ahead and do that if you haven’t already.

The next step will be to get this webhook, which is what allows Salesforce and Zapier to “talk.” Keep this page open and switch to a new tab to Salesforce.

In Salesforce, create an Outbound Message. The object you’ll want to create it on is Opportunity, because that where closed won sales happen! But you can see you can create an Outbound Message on almost any object.

Put the URL from the Zapier screen above into the Endpoint URL field in Salesforce.

The “Opportunity fields to send” section is important because that is the information you are sending back to Zapier, which will ultimately become part of the message you send to HipChat.

Side note: You’ll see that Account Name and Owner Name aren’t available options to pull over. This is why I’m bringing the IDs. We’ll convert them over to text in a later step.

Once you do this press Save on the Salesforce screen and save on Zapier. At this point, Zapier will want to pull in examples using the webhook you just added.

You’ll get something like this:

Allll the Salesforce IDs. 🔢

Step 2: Go back to Salesforce and set up a Workflow Rule

The Outbound Message is what sends all the relevant information to Zapier but something needs to kick off the Outbound Message. An Outbound Message on its own does nothing. Enter: Workflow Rule!

Create a new Workflow Rule that has the criteria you want to trigger to the Outbound Message. My criteria is fairly simple: Closed Won & over $15K.

Once you save your Workflow Rule, make sure to add an Immediate Workflow Action (choose: New Outbound Message) which is triggering your Outbound Message. Basically, you’re linking the two actions together. Otherwise, nothing will happen!

💡Admin Best Practice Side Note: I named both my Outbound Message and Workflow Rule “Over $15K for Zapier.” I also utilized the description field to explain what these actions do. When you’re stringing together different components within the system naming consistency is helpful because it shows you (and future admins!) that all these parts are related.

Before we delve into Step 3, let’s briefly cover what we did:

  1. Set up an Outbound Message from Salesforce to Zapier, which sends the relevant data from Salesforce to Zapier (which will eventually be passed to HipChat).
  2. Set up a Workflow Rule to push that information out of Salesforce based on specific criteria (since I don’t want to send a HipChat for every single sale!)

Next Steps: Use the IDs from the Outbound Message to get the text you want to include in your HipChat

This really puzzled me initially. In the screenshot above with all the Salesforce IDs you’ll note that that the only thing that is legible is the amount: 5000.00. Everything else is in Salesforce ID form. But when you go to set up your Outbound Message you don’t see an option to select “Account” just “Account ID.” Hmm. 🤔

So at first I just ignored this and plowed straight ahead into the HipChat portion of the Zap. This is what I got:


Okay, fine. I should probably figure out a more legible solution. At this point I hadn’t thought to read Zapier documentation, so I just turned to Twitter instead.

Initially I thought I’d create formula fields that would be hidden on the page layout in Salesforce so that I could pull the information over to Zapier. My heart secretly ached at the idea of creating extra fields for such a silly purpose. But then! A response!

Brilliant! Instead of creating these fields, I would just create steps in Zapier to search for the information I wanted in Salesforce and then bring it back to Zapier in the format that I wanted. I had to create a lot more steps in Zapier, but this way everything was self-contained in Zapier and I wasn’t spinning up random fields in Salesforce.

It does seem a little circular; you just called all this information from Salesforce to Zapier and now you’re sending it back to Salesforce just for the purpose of reformatting it. But since you only have IDs for these objects and nothing more, you need to query Salesforce so you can get all the fields so your HipChat message isn’t gibberish.

Step 3: Find Account

In Zapier, create a new step after your Outbound Message. Select Action, then Salesforce, and then “Find an Account.”

You’re searching by the Account ID you got in Step 1!

Select Account ID and then Notification S Object Account ID. Then follow the rest of the prompts.

Don’t worry about Account Name and other text yet! That will come later.

Step 4: Find User

This is pretty much the same as above, but instead of “Find an Account” you’ll choose “Find a Custom Object.” The User object is not a Custom Object, but that’s what Zapier calls anything that they don’t have in their system.

This is the User ID for the Opportunity Owner and how you’ll get their name.

This is what your steps in Zapier should look like so far:

Step 5: Format Currency

This is 100% optional but if you’re going to do a job you might as well do it well, right? In your Outbound Message Salesforce gives you the amount of the opportunity in this format: 50000.00. No dollar sign, no comma. Not ideal.💰

Luckily, Zapier has a solution for this called “Formatter” that will transform the number for you. Create a new Action and search for Formatter. Choose Numbers and on the next screen you’ll be presented with this:

The Currency Format part still confuses me a bit.

Your input is the amount that came over in the Outbound Message.

You’ll then get an option to test the results of the formatting. If it doesn’t look how you want it, go back to the previous screen and fiddle with the Currency Format options until you get what you want.

Step 6: String it all together to create your HipChat message! 💃

Okay, you’ve told Salesforce to send information to Zapier, you’ve searched Salesforce for the correct information you want to render in your chat and you reformatted the currency because you’re an overachiever. 💅 Let’s finally put it all together and send a HipChat message!

Back to Zapier: Create a new action, search for HipChat, and select “Send Message.”

You’ll need to connect HipChat and Zapier so this is where that Admin Auth Token will come in handy. Grab that and you’re ready to rock and roll.

Next comes the fun part: Setting up the template!

Room: The HipChat room you want to send the message to (when you are first setting this up and testing it, I recommend making a private room or sending the chats to a less populated room.)

From: This is just a free form text field and you can make it whatever you want. I thought Opportunity Bot was cute so that’s what I went with. 🤖 (Too bad I can’t add emojis in Zapier/HipChat because otherwise I totally would)

Message: Here is the what we all came for and the purpose of all those darn searches. You can now craft your message and pull information from each search step.

Basically an elaborate mail merge. 📩

I just wanted account name and user name but because you pulled in the entirety of the Account and User objects, you could pull in whatever you want — user title or maybe account phone? Really, the possibilities are endless.

Notify, Color, and Format: All pretty straight forward — make the choice that is right for you.

Before going live, I recommend sending a couple tests to a test HipChat room to make sure your chat is exactly how you want it.

Once you’re happy, change the HipChat room to real room you want to send the chats to and don’t forget to turn on your Zap!

Step 7: Wait for the sales to roll in

End of quarter sales has the Opportunity Bot working overtime. 😅

The best part of the Outbound Message is that it’s instantaneous! This is because Salesforce is pushing information to Zapier vs. asking Zapier to search your Salesforce instance. So the second a rep closes a deal, you’ll see it in HipChat.

Did you try this? Or have an idea on how it could be better? Leave a comment below or find me on Twitter. I’m always looking to meet other Salesforce enthusiasts. ☁️

In-Line Editing in List Views in Salesforce

I used to shy away from List Views because I thought of them as a less robust version of reports, so why bother with them? Recently I had a discovery that made List Views worth it: in-line editing.

Every week Industry Dive has a process where we confirm that the advertising placements we sold to a client actually ran. Our Ad Operations team confirms the placements ran and then communicates to our Accounting team that the placements can be invoiced.

In order to designate between a placement that we think ran vs. a placement that has definitely ran we have a checkbox on the record named “Reconciled?” Once this box is checked it means we’ve confirmed it has run and Accounting can invoice.

We usually run 80–100 placements a week, so checking that box for every placement would really suck. Enter: in-line editing! 🎊

Now a user can quickly reconcile placements without going into each individual record.

There are some important limitations and things to know about in-line editing and the permission to do so must be turned on by your Admin on your Profile.

If you have a situation where you are exporting a group of records to make a change on all of them that is the same, give in-line editing a try. It’s easier and less error prone than exporting and updating via Excel.