Search Results
68 items found for ""
- Platform Events — My New Favorite Tool
According to my Trailhead history, I completed the Platform Event Basics module on 12/9/17. So it's more than a little while since I first learned about them. But just in the last month or so I've kinda become obsessed. When I first read that module I barely understood it. And it's no wonder! The intro to the first section suggests understanding object oriented programming (I barely do.) and that "familiarity with the concepts of Streaming API(CometD) and Pub/Sub API is helpful for this module although not required." I have zero familiarity with those concepts. The hands-on challenge requires Apex triggers. I'm no coder. I know enough to be dangerous or to complete a Trailhead challenge, but I would never write code to go into a client org! All that is to say that the concept of platform events might seem a little intimidating to you. That's OK. It was intimidating to me as well. But I have realized that they can actually be pretty simple and incredibly useful. That's why I want to share with you! The Concepts Needed to Ferment Like I said, it's almost five years since I first learned about platform events from a Trailhead badge. At almost no time in the interim did I consider that I might have a use case for them. They sounded very developer-y. But the knowledge was tucked away, apparently. In January 2021 I completed Application Integration Patterns for Salesforce Lightning Platform. (There's an exciting sounding badge, right? I think I must have been bored. Or working toward some arbitrary number of new badges.) That was yet another badge that didn't seem to have a lot of relevance for me. And it was almost two years ago. But apparently concepts from that badge started rattling around my brain, eventually sticking themselves to platform events, which were also bouncing around in there. Pub/Sub (short for Publish/Subscribe) If you don't want to read that whole application integration patterns module (And why would you?), I think of pub/sub as breaking apart the act of writing something from the need for anyone to read it. Like writing a blog, sending out a tweet, or even posting on Facebook, the "publish" side of the action is something done only by the writer. Or maybe it's more like a town crier, shouting their message that "It's ten o'clock and all's well!" Or the muezzin chanting the dawn call to prayer from the top of the minaret, "It is better to pray than to sleep." Somewhere, the writer or the crier hopes, there is someone "subscribing" to their message. I sincerely hope, when I write one of these posts, that you subscribe and read. The muezzin sings not for his own benefit but to draw people to the mosque. Theoretically we could all just be shouting into the void. I guess one difference from my metaphor is that a pub/sub integration pattern has, by definition, some means of subscribing. That's what makes it an integration pattern. Fire and Forget This is the one that really didn't make a lot of sense to me at first. The "forget" part kinda' freaks me out! Do I want to work with any kind of integration that just sends off a message without knowing that it was received? It's like sending an SMS without even the notification that it was "delivered." Even when you get that—or even better, a "read" receipt—do you really believe the text was read before you hear back from your friend? I suppose any uni-directional integration is kinda' fire-and-forget, since the sending system doesn't necessarily get back data from the receiver. But I've mostly worked with middleware such as Zapier. The sending system might not get data back, but Zapier at least knows it has successfully taken action on the receiving side. So Zapier could report an error if needed. I'm not certain I can explain the difference between the two concepts, now that I think about it. "Pub" and "fire" seem basically the same to me. "Sub" can't be a whole lot different than making sure your "fire" is aimed somewhere that's ready to receive, can it? Maybe someone smarter about these things can help me out? Are Subscriptions Reliable? Can you fail to notice a platform event? Despite my lack of understanding, those combined concepts must have fermented in my subconscious. I think I had a vague notion that something called a "platform event" could be "published" (or "fired") and that a "platform event fired flow" could "subscribe" to listen for it. But I didn't know if I was missing some important context or nuance. And I really didn't know if it was reliable. Could the subscriber ever miss a delivery? I subscribe to the daily hard-copy newspaper, but there are plenty of days when delivery is late, never arrives, or the paper is wet and unreadable. Even e-newsletter subscriptions sometimes get diverted into my spam folder. And just because I "subscribe," that says nothing about whether I read the paper, let alone any given section or article. These were the questions that I've had about platform events for several years now. And platform events don't seem to get mentioned very often in blogs or presentations, so I didn't really learn anything more. Then at the end of August I stayed in the Amherst, MA, home of Salesforce MVP and brilliant system architect Chris Pifer, who I've worked with many times at Open Source Sprints. We were nerding out late into the night over Salesforce stuff. (As one does.) At some point Chris mentioned that he had been using platform events recently to allow for an interconnected and extensible set of automations in a large enterprise implementation. (At least, I think that's what he described. Honestly, he was way over my head.) That lead me to ask Chris some of my questions about platform events, including the big one that worried me: Could the subscriber miss the publication? Chris assured me it could not. I don't remember if this is how he explained it or not, but what I eventually took away was that the pub/sub of a platform event is similarly reliable to the create/update of a record and the "noticing" of that event by a record triggered flow. My gears started turning... Potential Use Cases Come Calling Mass Invoice Insert Over the summer I had a client with a need to create a whole bunch of invoice records each month. I created a screen flow that has a pause before calling a subflow, so the large amount of records that need inserting happens as part of a separate transaction. (In fact, there's another record-triggered flow that creates child records of those records, also after a pause.) I was concerned that even with the pauses my flow might still fail. What if the screen flow designated more records to be created than the subflow could handle without hitting limits? I tested as best I could in a sandbox and then crossed my fingers when I got to production. It works, but I still have a nagging suspicion that it could be brittle. (It's on my list to refactor, but for now we go with, "It ain't broke. Don't fix it.") Frequent Recalculation of Child Records Then in September I started work on a tangle of flows for another client, The Modern Classrooms Project. That task turned up an interesting dilemma: One of the flows we needed would fire upon delete of an opportunity product, calling a related flow that would determine needed revenue recognition child records for the opportunity. (Let's abbreviate "revenue recognition" to just "revrec.") But flows can only fire in a Before Delete context. That meant that our flow picked up the deletion of the opportunity product and called the opportunity flow to recalculate revrec records. But that recalculation ran before the product was deleted, which is functionally the same as not running at all in this case. I reached out to the community looking for suggestions to force my flow into an After Delete context. In the course of that discussion I wondered, after my conversation with Chris, whether we could have the before delete flow publish a platform event, then fire a platform event fired flow that would be in an after delete context? Consensus was that it might, but the only way to be sure would be testing. (The easiest option the community suggested was to pass the Id of the deleted record to the revenue recognition flow to be excluded in the Get Records for products. I went with the easier—and guaranteed—option.) But there was enough suggestion that it might work to make me want to revisit the question later. The Moment Arrives That same Modern Classrooms tangle of flows threw us another curveball that finally gave me the excuse to try out platform events. We realized that we need to force recalculation of revrecs for opportunities if they cover the period in which a new session is going to happen, or if a session's dates change to move it into or out of the period of a contract. Modern Classrooms is growing fast. I could envision a time not too long from now when there could be dozens or even hundreds of opportunities impacted when a session changes. I thought I could probably use the paused flow trick to process those changes asynchronously. But the idea of trying out platform events to process those changes closer to realtime seemed worth a bit of playtime. And it worked! It was actually surprisingly easy. Payload Delivered Platform events are like Salesforce custom objects, in that they can have fields with data in them. But platform events do not persist in the database as records. (And they can't be viewed in the user interface at all.) Platform events are metatdata and get configured, similar to a custom metadata type (CMDT). But unlike a CMDT, you can fire a flow when a new platform event is published. (I wanted to write "call a flow from a platform event record," but I think saying "record" would be confusing because that platform event "record" only exists long enough to be heard by a subscriber, there is no "record" sitting in the database for later viewing.) To expand my metaphors from earlier, a platform event isn't just published, it isn't just shouted into the sky—it can carry a payload of meaning. The town crier doesn't just make noise at 10pm, he can deliver a message that "All's well!" or "A storm's a-comin'!" Maybe it's the difference between a public clock that can chime only the hour and a PA system that can make a sound on the hour or give a news bulletin. Or it's the difference between birdsong that is "just sound" to us, but has meaning for the other members of the species. Or the hideous noise of a fax machine or modem that actually sends information from one device to another. Or the random-looking pattern of squares on a QR code that your camera can interpret as a web address. Or, you know, squiggles on a screen that you and I interpret as "writing." [Enough metaphors for you yet? I could probably come up with more.] So the heart of my first platform event-based solution was simple: I made a platform event that would carry a very small payload: the Id of a single opportunity, one whose revrecs need recalculation. When a session is created or updated, I have a flow that finds all the opportunities that are impacted and defines platform events for all of them. Then it publishes all those platform events, one for each opportunity. One platform event is shouted into the world for each opportunity that needs revrecs recalculated. Meanwhile a platform event triggered flow is subscribed to The Opportunity Network. Each opportunity Id, as it's shouted, triggers a very simple flow that finds the opportunity and checks a box on it called "Recalculate RevRecs." Can't get a lot simpler than that, right? There's one more flow in our solution. It's a record triggered flow on Opportunity. If Recalculate RevRecs is checked, it calls the revenue recognition flow and then it unchecks the box (to ready it for use in the future.) Depending on your Flow skills, this might either sound very simple or a little complicated. But I think you can follow that each individual flow is pretty understandable. So stick with me. One to Many to One The cool part is that with platform events we've now taken a single user action (create or edit of a session) and broken its consequence (need to update dozens or hundreds of opportunities) into individual pieces. In normal flow land—whether we do this in one big flow or break the work into a triggering flow and one or more subflows—a single transaction (the create or edit of one session) is going to result in a cascade of record updates (changes to the revrecs for many opportunities). Depending on the complexity of that cascade and how many records it happens for, that could be a whole lot of processing going on. And in normal flow land, all of that processing will happen within a single "transaction" that initiated the flow, so all of the processing together has to stay within the Salesforce governor limits. But instead of normal flow land, we process each opportunity individually because they're each kicked off by an individual platform event. This isn't a collection of "opportunities that need reprocessing" anymore. No worries about CPU timeouts, or flow element limits, or a slow page reload after Save. The session is created or updated and a very efficient flow in the background publishes some platform events. Easy peasy. Then one opportunity, then another, then another, in series or in parallel, it doesn't really matter, all do their revrec recalculation. The user experience is fast because the session save and publishing of events is all that happens in the user's transaction. Everything else is in the background. Get Around Specific Limits WIthin a week of finding using platform events for that cool case, we found another way to use them at Modern Classrooms. This time we're going to evade a very specific limit: You can't send more than 10 emails in a single transaction. Obviously you can send email templates and the like but most of the time you're sending a single one in a transaction. ("When an opportunity is moved to Closed Won, email the donor an acknowledgement." That's one email.) But if you want to call the sendemail() method (or, in a flow, use the Send Email action) you can't do it more than ten times in one transaction. This one's tripped me up before! But this is exactly what my colleague Terri wanted to do. She was building a screen flow to allow you to select multiple records in a list view and then send out a list email to the contacts that go with those records, similar to the native List Email function on campaigns. I mean, why should campaign members have all the fun? Terri's a fast learner and not afraid to try things out. So she built a little screen flow and dropped it onto a list view and tested it a couple of times in a sandbox. But when she mentioned it in a meeting, I asked if she had attempted it with 15 or 20 records. She had not. (There are never enough records in a sandbox!) I was pretty confident it was going to hit that send limit. Worse yet, the Send Email action has a limit of five email recipients among the three places you can add them. But I immediately wondered if platform events—my new favorite toy!—could come to the rescue. Turns out that they can! All we had to do was define a platform event with more payload: Recipient Subject Body Sender Set up the screen flow to publish a bunch of platform events, one per selection on the list view. Then a waiting platform event triggered flow (below) takes those fields and puts them into the right places on a Send Email action. Since that platform event triggered flow is working on just a single email, there's no problem with limits. In fact, that flow can even take the step to look up the contact who's the recipient (we originally sent from related records) and could look up records related to that contact... The freedom of working from an entirely separate transaction opens up lots of possibilities.
- Unlimited Edition Means No P10!
(an update to AEs are Salespeople) In my most recent post I noted that AE's are Salespeople and called out some of the ethical lapses I've seen. In response to that post one of my close friends, who is a senior consultant at a medium sized Salesforce partner reached out to ask if I could update my post to add a bit of information: Upgrading to Unlimited Edition means that you lose the P10 donated licenses. That is a very big deal! Let me restate it: If your organization chooses to either upgrade an existing Enterprise Edition or starts your new implementation on Unlimited Edition, you will not get any licenses free. Under the Power of Us Program all nonprofits get ten donated licenses, known as the "P10." These are licenses for an Enterprise Edition org (or "EE"). Unlimited Edition ("UE") is the next tier up, coming with more data storage and some other potential benefits. (That you don't need. Watch for a future post on this topic!) UE licenses, of course, cost more. They are $864/year, exactly twice the price of EE. So naturally AEs would be incentivized to sell Unlimited! But the P10 grant does not apply to UE licenses. So whereas the first ten EE licenses are free and then the 11th (if you ever grow that large) costs $432, on UE you pay $864 for every license, even your first. Thus the AE that talks a small nonprofit into UE has just garnered themself commission, even for a nonprofit that should pay zero dollars. This is a problem on so many levels. Plus. my friend told me that they have seen "increasingly sleazy" tactics from AEs pushing Unlimited Edition. I've heard that from other people as well, I just hadn't put together the cost difference. Just think about the math for an org with 20 users, which is not that many employees: 20 users on Enterprise Edition = 10 free+10 paid licenses = $4,320/year = 💰 20 users on Unlimited Edition = 20 paid licenses = $17,280/year = 💰💰💰💰 A lot of nonprofits won't realize that until it's too late that they have now signed a contract that gets rid of their donated licenses. It's Hard to Speak Out The person that came to me with this information asked me not to include their name. They told me that they've already had "an AE get cranky" when they pointed out that a particular thing the AE was trying to add to a contract was not worthwhile. This is someone that often is very forthright with their opinions, including in public forums. But they felt that pointing out this sales tactic problem could hurt them and their coworkers. Not The Last Word On This I've made an edit to yesterday's post to mention this particular information. I started this blog in order to give nonprofits the straight information on pricing and value. You'll definitely be hearing more about Unlimited Edition, AE sales tactics, and the like.
- Spoiler Alert: AEs are Salespeople
[NOTE: This post has been edited from it's original publication to include some additional information.] I don't think this should surprise anyone: The account executive ("AE") from Salesforce who reaches out to you when you create a new trial instance or when your organization applies for the free [like a puppy] licenses or when your contract renewal arrives is paid to sell things. They may (emphasis on may) have expertise with nonprofits or education and be able to also serve as something of an advisor. But their job—the only job they get paid for—is to sell things. Never forget that. It's not just the AE. That solution engineer who gave all kinds of interesting suggestions for how you might build your system? She's not actually going to build it for you. She's whetting your appetite so that you'll have a more ambitious implementation. The person who showed you a beautiful demo of the student portal that another university uses is not going to replicate that build for you. They're showing you what you could do if you added Experience Cloud to your contract. I'm not writing to complain that this is a problem. (Well, OK, maybe a little... 😉) Let's Be Realistic We live in a capitalist system. Salesforce, as I have said before, is a capitalist enterprise, a business. Not just a business, ticker symbol CRM is a publicly traded company. Even if Marc Benioff wanted to turn Salesforce into some kind of social enterprise or a charity, he could not. The other shareholders expect profits and growth. (Full disclosure: I am one of those shareholders. A very small one.) I don't particularly love capitalism, much less the late-stage American-style capitalism that has produced so much misery and inequality. But this is the system we find ourselves in, the game we are forced to play. And no matter my feelings about it or yours, Marc Benioff actually seems to be quite fond of capitalism. Given that, I take it for granted that executives throughout Salesforce are also on board with capitalism, even if they work in the nonprofit-serving arm of the company. The Incentives Are Wrong Back to those AEs. Even AEs working for "Salesforce.org" are incentivized directly by profit motive. (I used those quotes around Salesforce.org because I want to remind you that there is only a single entity at this point. Salesforce.org is a division of Salesforce, not a separate organization. The name implies more separation than it should at this point.) As a matter of fact, as far as I understand it, AE commissions are only based on new product sold. That means that when your org comes up for contract renewal, your AE makes no additional money when you simply renew your contract as a happy customer (even if you are continuing to pay for licenses beyond the 10 free ones). They only make money if you buy new licenses or add new products. Stop and consider that for a moment. Your AE does not make money if you are simply a happy customer continuing to use Salesforce for another year. Your AE may be glad to hear that the system is making you more efficient and effective at your mission. They may be thrilled that you work with a wonderful consultant who has built you custom functionality that you love and that by supporting that consultant you grow the Salesforce economy. They may appreciate that you have hired your first full-time Salesforce admin and, therefore, have grown the workforce. Your AE might even enjoy hearing that you have purchased products from AppExchange partners, growing the Salesforce ecosystem. But when it comes to whether or not your AE has met their job goals, none of that matters. Their commission and their job performance is only evaluated based on whether you buy more licenses or add new Salesforce SKUs to your contract. If your spend doesn't rise, neither does their bank account. Personally, I think that's a poor incentive structure. I realize that this is nothing more than my opinion—and that I have never worked in a sales environment, much less managed workers in one. But I think there should be room for AEs within Salesforce.org to earn recognition (including commission) for helping organizations that use Salesforce to thrive and to continue their use of the system. No Illusions Even if the incentives didn't deprioritize steady-state usage, I recognize that Salesforce and AEs would be more interested in the bigger nonprofits. Of course it's going to be better for the company to sell 100 full licenses and 500 community licenses to a larger nonprofit than to deal with a small organization that only uses the P10 grant or may someday purchase a single license. Of course it's going to make sense for the company to get in the door of a higher education institution than to spend time working to get or keep a tiny nonprofit customer. There's probably no way within a capitalist structure that this wouldn't be the case. I'm resigned to the fact that there are structural reasons why Salesforce.org is going to focus on larger nonprofits and higher ed. That will skew how AEs do their job, how products are designed and built, and what voices are heard by executives within the division. I recognize this reality. But those deals should still be structured ethically. AEs should not profit from selling unneeded products and services to nonprofits, draining scarce resources from their mission. Unfortunately, they do profit from this. Not a Rare Problem I regularly hear from consulting partners about deals where an organization was convinced to purchase all their licenses up front (even for an implementation that might take a year to build), or sold licenses for a Community ("Experience Cloud") that they would never need, or convinced to add a high-priced SKU to the deal, or sold Unlimited Edition licenses when their data volume would never justify the cost. I hear these stories too often for them to be rare—I'm just not that well plugged in to Salesforce partner gossip. If I hear about it as often as I do, it means the misplaced incentives are encouraging this to happen somewhat regularly. Here is another major problem: Salesforce.org AEs are pushing Unlimited Edition ("UE") and talking up the Power of Us donated licenses (the "P10"). But if you go with UE, you do not get any free licenses. The P10 grant is only for Enterprise Edition. For more discussion of this, see this update. Those are the egregious examples. But I also hear about small wastes of nonprofit money, like selling the 11th and future licenses after the P10 grant as "Lightning CRM Edition" (Sales + Service Cloud) for $576/year even though basically all nonprofits use "Lightning Enterprise Edition" ($432/year). Just a couple of weeks ago someone I know discovered that her client was paying $576 for all of their licenses, for absolutely no reason. Once in a very long while there could be an organization that needs an extra Sales+Service license, but it's a vanishingly rare occurrence. Someone in management for the Salesforce.org sales team should notice when one of those is sold and ask, "Are you sure?" Not watching for that is simply taking money away from the mission of nonprofits because nobody at Salesforce.org cared to correct the mistaken overcharge. Where are the Partners in this? Unfortunately, the problem isn't just with Salesforce's sales team, it bleeds into partners as well. I am not accusing the partners of actual wrongdoing, but let's "follow the money," as they say. If you are a consultancy that gets referrals from Salesforce (which is supposed to be the point of the partner program and is the lifeblood for larger consulting partners), then naturally you don't want to antagonize the company. If Salesforce sends you a deal that involves overcharges like excess licenses or SKUs, you're going to be put in a tough spot. By the time the partner gets that referred business the Salesforce contract has already been signed. Even if the partner wanted to counsel the client against the oversell, it's too late. And I can imagine it would be pretty awkward to start your new client relationship by telling them they've wasted money. I know there are partners that have that difficult conversation with their new client. Sometimes they do it quietly, arming the client for dealing with Salesforce when renewal rolls around, or trying to help them claw back part of the deal. I think they most often do this secretively, telling the client what they need to know, but trying to cover their tracks so that Salesforce won't punish them with fewer deals. But I also suspect there are some partners that either turn a blind eye or even participate in unnecessary upcharges if they get a cut of the deal. In fact, I edited the original publication of this post to include the paragraph in the previous section about Unlimited Edition not getting free licenses. (And this paragraph, obviously.) I added that because a friend that works for a medium-sized consultancy specifically asked if I could highlight that information. When I asked if I could identify them as my source, they asked that I publish this without their name. They were concerned for themself and their coworkers because an AE has already been upset with them for advising clients not to buy a product they don't really need. Full Disclosure I am a Salesforce Partner, at least on paper. A couple of years ago they made it free to register as a consulting partner. Since it was free and came with some potential benefits, I figured it couldn't hurt to sign up. Unfortunately, something about my login never worked. After several back-and-forths with Support, I gave up. Then, about a year ago, when the kerfuffle about new Nonprofit Cloud was breaking out, it became clear that there were conversations in the Partner Community that I might benefit from being a part of, particularly if I wanted to understand and interpret for my readers on this blog. And there are learning resources for partners that I couldn't access even as an MVP. So I put in the work with Support and finally become "officially" a partner. As a matter of fact, at the time of this writing, I actually can't log into the partner portal once again. No idea why. I've filed another support case. So much for accessing those partner benefits. I'm getting notifications for posts in the partner community but I can't even access the rest of the thread. Bottom line: I am a Salesforce Partner in name only. I have never gotten a deal referral from Salesforce and I do not register deals when I bring in a new client that is going to implement Salesforce. This is intentional. I want to maintain full independence to advocate for what I think is right for my clients, for nonprofits, and for the Salesforce community. I want to be able to say whatever I want on this blog without fear that someone could retaliate against me and hit me directly in the wallet. Last full disclosure: I'm a member of the Salesforce community. I enjoy opportunities to speak at community organized and official events. I get tons of Salesforce swag, from stickers to sweatshirts. And I'm proud to be recognized as a Salesforce MVP Hall of Fame member, with all the official benefits and swag that entails. These things certainly make a dent in my thinking about the company and probably temper what I write here. So you can take what I say with that in mind. (But I believe it's a far cry from relying on Salesforce to actually support my book of business.) Caveat Emptor (Buyer Beware) So take what I say with full knowledge of my situation. But more importantly, keep in mind when someone has a financial incentive undergirding what they are telling you. And that goes doubly when you're talking with an AE who is literally trying to sell you something. All I can do is remind every Salesforce admin to scrutinize your contract. Check the price guides, including the crowdsourced one that I maintain. Know what a product is before you agree to purchase it. And take a very skeptical look at anything new being suggested.
- No Dreamforce Wrap-up From Me
If you've been reading my blog for a while, you might have noticed that I didn't publish a post-TDX wrap up, nor anything in particular about Midwest Dreamin. And I'm not going to write a Dreamforce '23 wrap up either. Why? It's Been Done For starters, there's more than enough other content already out there on LinkedIn, the social media site formerly known as Twitter, the Trailblazer Community, Ohana Slack, and probably more. With the activity of some social posters you can practically experience Dreamforce in realtime, if you want to. By the time I would write something up it's practically stale! And I am happy to encourage you to read some of the other excellent Salesforce blogs out there, many (or most) of which did have a wrap up. So I don't think you really need one from me. Mostly Marketing Also—spoiler alert!—the content at Dreamforce is mostly marketing. [I hope this isn't coming as a great shock to you. If it is: You're welcome.] I actually don't mean that as any sort of complaint. Really. Salesforce spends millions of dollars on Dreamforce and the purpose of the conference, from their perspective (as I interpret it) is to sell product. It's a fun conference, incredibly well produced (think Disney level of attention to visual detail, but for a tech conference), with free access to a concert from a headline band (this year: Foo Fighters, my first time: U2), and interesting to experience. But the keynotes and the Salesforce-generated content are a chance for the company to make announcements about shiny new things and to generate interest and hype that will get good press and eventually result in profits. No more, no less. The nonprofit keynote had a surprise visit from Sprinty the T-Rex, and that was pretty cool. But it's hardly groundbreaking new announcements of features or products. And the actual "announcements" in the nonprofit keynote (to the extent that I paid attention) were all "AI blah blah" and "GPT blah blah." Nothing that we're going to be using for a while. (I'll write about that stuff when it seems actually relevant.) Before COVID, when Dreamforce attendance topped 150,000 (not a typo!), there were thousands of sessions presented by community members (like me), so there was a massive amount of learning and technical content available. In the post-COVID incarnation of Dreamforce attendance is lower and the number of presentations from outside Salesforce has also been reduced. It's hard to say if it's a proportional reduction, honestly. But if you're really looking for technical learning, you can get it at dozens of Dreamin events for less cost, so I would argue that Dreamforce is just a different thing. That's not to say you can't learn a lot of technical content at Dreamforce. You definitely can. You just have to learn to read between the lines of the session titles and abstracts. Tons of Networking So if Dreamforce isn't for the technical content, why did I spend the money on airfare and hotels? I actually didn't think I was going to bother until the Trailblazer Community Team decided to have a Salesforce MVP Hall of Fame induction ceremony and an all-day conference for MVPs. How could I pass that up? For me the event is about the networking. I saw and met tons of people. As an introvert, it's an amazing opportunity to sit down and go deep so that we really bond. (It's also incredibly overwhelming as an introvert, but that's a topic for a whole blog post sometime.) But it doesn't feel like a Dreamforce wrap-up about all the networking I did would be that interesting... If you weren't there, do you care? Which brings me to my main feeling about Dreamforce recap blog posts: Do people care? If you were there, you don't really need the post. And if you weren't there, am I just lording over you that I was? FOMO Much? If you read this post and all the other Dreamforce content and wondered whether you were missing out, I'll leave you with this bit of advice: Dreamforce is something to experience at least once. It doesn't have to be next year and it doesn't necessarily have to be a regular thing. In fact, I wouldn't even put it first on your list: TrailblazerDX (or TDX) has a lot more opportunities for technical learning and is focused on developers and admins. And it's also run by Salesforce, so you get a lot of the Dreamforce magic, but with fewer crowds. Dreamin events are far cheaper and easier to get to. Content is much more focused on admins and job seekers. You could probably attend three Dreamins for the same cost as going to Dreamforce. Local User Group Meetings - These are, by definition, local and they're also free. Go meet other professionals in your area! If you're involved in the ecosystem I would recommend you try out Dreamforce sometime just to say you have. But see if you can get an employer to pay for the airfare and hotels.
- Smiley Faces Form
If you'll indulge me, I'd like to brag a little bit about my son Arden while telling a frame story about making a cool FormAssembly mod. A few weeks back Jennifer Lange asked the FormAssembly VIP Slack community if anyone "has a scale of smiley faces that can be clicked to report your experience with a service? One question "How was your service today?" and then 5 faces - click one to rate and then submit." She pointed to a FormAssembly model that was close to what she wanted, but with stars instead of smiley faces. I immediately wrote that five radio button options in order like this would do the trick: 😭 😢 😑 🙂 😄 I was reading too quickly and didn't notice that she also said "NOTE: I know I can put an image of 5 faces, and then have the radio buttons under them - that's not what I want. I want clickable face images." Hmm. The code on that form seemed pretty understandable, but since we weren't going to repeat the same image five times I wasn't sure how to go about modifying it. Fortunately my son Arden is home for the summer. Time to call in help from the CS Major! It took Arden and me a couple minutes of fiddling but the result was this form (with code that you can reveal and use for yourself.) Cool right!?! Go use it for something in your org. And tell me what other fun FormAssembly tricks you've found!
- Free Things I Always Install: Unofficial SF
This is the final installment of my summer series of posts about free utilities I always install in a new Salesforce instance or that I install into existing instances once I come along to support them. I love free things! (These, by the way, are all free-like-a-beer.) UnofficialSF ("USF") It's the last post in this series, so I'm not limiting myself to one tool, I'm pointing you toward a site with hundreds of them. UnofficialSF is "a loose collaboration of bloggers, mvp’s, and the occasional Salesforce employee" that put out "Guides, Installable Actions and Components for Salesforce’s Automation Products." If you haven't browsed the amazing things people have built, I won't be offended if you switch tabs right now! The Flow Components library alone is a treasure trove! Look also at the Lightning Page Components if you want to customize your user experience. (You might even find something familiar looking on Applications and Utilities... 😉) What I Install As I said, there are a ton of great tools here that just might be exactly what you're looking for, even if you don't know you're looking. Several of them have been exactly that for me at one time or another! But I don't want to clutter up client orgs with more installed packages than I'm going to use. So when it comes to the ones I always install, I limit myself to the USF components that I need right away or am pretty confident I'll be using in the near future: Flow Action and Screen Components BasePacks - These are a required prerequisite for several USF tools so you might as well install them early. (Otherwise you're just slowing yourself down when you try to install something later.) With these in place other USF components can install and even have configuration tools within the Flow Builder. Navigate Everywhere - We've all been frustrated when building a screen flow and want to redirect the user to the record we just created. Navigate Everywhere gives you that power and more. Might not be used right away, but it's likely on the menu as soon as you I build a screen flow that creates records. Send Better Email - I used to use this all the time, if only for the ability to log an email as a task on the contact once it's sent. But that's now part of the standard SendEmail flow component, so SBE might not be as critical anymore. But SBE still gives other functionality that can be handy, so I like to keep it around. Datatable - The Salesforce standard Data Table component is getting more useful, but it still can't do all the things you're going to want and need. USF's Datatable sets the real standard for displaying and interacting with records in a table in a screen flow. Gratitude While I'm mentioning USF, I want to give a couple of special thank you: Alex Edelstein - I don't think I've ever met Alex. But I, like many, owe him thanks for starting and maintaining UnofficialSF. Eric Smith - There are many people that publish and maintain components on USF, but Eric seems to be the author of ones I use most often. I've been fortunate to hang out with Eric in person and also fortunate to get fast responses and help when trying to make one component or another do my bidding. Thank you, as well, to everyone that creates, publishes, and maintains the tools on UnofficialSF. Whether you've made one or many, you've helped me and many others do our jobs better.
- Free Things I Always Install: DLRS
This is the third in a summer series of posts about free utilities I always install in a new Salesforce instance or that I install into existing instances once I come along to support them. I love free things! (These, by the way, are all free-like-a-beer.) DLRS (Dolores) Getting a post out of this is almost cheating because I wrote a whole post about DLRS not too long ago. But my series would be incomplete if I didn't give it another mention. Old Dog New Tricks Expanding Salesforce's native rollup summary capabilities beyond just master-detail relationships is the core of DLRS functionality. But that's not all it can do. I've written about the rollup to relationship trick. Should also look through the great "cookbook" on the DLRS documentation site. There are all sorts of ideas for things you can do with DLRS that you might not have thought about. It Just Gets the Job Done Like the other tools in this series, DLRS is entirely free and it does what you need. What more is there to say?
- Free Things I Always Install: Mopsy
This is the second in a summer series of posts about free utilities I always install in a new Salesforce instance or that I install into existing instances once I come along to support them. I love free things! (These, by the way, are all free-like-a-beer.) Mopsy Mopsy is a replacement for the Today's Tasks component that is default on the Salesforce Home page. Today's Tasks Component Is Not Great Have you ever noticed that Today's Tasks just not that functional? For example, in this sandbox I created a task for myself that was due yesterday. Here's the Today's Tasks component: Phew! I'm thrilled that nothing is due today. Too bad it's not pointing out that I have a task that's overdue from yesterday. Using the carat in the upper right you can set it to show overdue tasks. But then it doesn't show tasks due today. (They're not yet overdue. Sigh.) Mopsy Fixes That I really only need one thing out of Mopsy and it delivers. Users can set it to show "Today + Overdue." There are actually quite a few additional filter options in Mopsy: But I am really after the option for Today + Overdue because it means my users are a little less likely to never finish those tasks from yesterday! It's also nice that Mopsy gives you a convenient button right on the component to make a new task. (It's that plus sign in the upper right.) I also like that the admin can set it to show some or all of the Comment field on the task. There are other features of Mopsy that you can explore. Like I said, I'm really interested in just the one thing. "User Selectable" Also Means "Inconsistent" One "gotcha" that applies to Mopsy the same as Today's Tasks is that the filter under that carat is user selectable. That means different users may set it differently and could, therefore, still miss tasks. There's no way for you, as the admin, to default Mopsy to Today + Overdue, and definitely no way to lock it there. So you'll want to train new users to set it and leave it alone. Right Tool If You Need It Your org might not use Tasks, or might use them sparingly. They can be handy as a To Do list that's tied to records and easily viewed by your colleagues. Tasks also have their drawbacks (which should probably be the subject of another post). But if your organization uses Tasks, then I recommend dropping Mopsy on your Home page so people can see what's coming up.
- Free Things I Always Install: Lightning Messaging Utility
This is the first in a summer series of posts about free utilities I always install when setting up a new Salesforce instance or that I install into existing instances once I come along to support it. I love free things! (These, by the way, are all free-like-a-beer.) First on the list (though it’s in no particular order) is the Lightning Messaging Utility from Salesforce Labs. “What’s Salesforce Labs?” you ask? To quote the AppExchange listing: Salesforce Labs is a program that lets salesforce.com engineers, professional services staff & other employees share AppExchange apps they've created with the customer community. Inspired by employees' work with customers of all sizes and industries, these apps range from simple utilities to entire vertical solutions. Salesforce Labs apps are free to use, but are not official salesforce.com products, and should be considered community projects - these apps are not officially tested or documented. Basically these are free apps that someone at Salesforce developed for a demo or in their spare time and they’re releasing them for us to use. That’s pretty cool! Labs is also the program that publishes Open Source Commons apps like DLRS. There are dozens of other tools out there released under the Labs program. I encourage you to try them out—and let me know if you find something amazing! Lightning Messaging Utility This is a simple app that does one thing and just makes it easy: LMU allows you to display messages on your Lightning pages that fit the Salesforce Lightning Design System and, therefore, look like they belong. I think it’s great that you can insert a rich text component onto a Lightning page and use it to display a message to your users. And you know I do it with emoji all the time! Or you can use a screen flow component and dynamically generate all kinds of informational messages, even if you aren’t using the flow for interactive screens. But when those are on the page they don’t quite look like the rest of Salesforce. I’m sure I could work at it to make these look a little closer to the rest of the page if I really understood graphic design principles. But I know it would still be just a little “off” no matter how much time I put into it. Depending on the use case, that might be OK. But often I want a simple message that should blend seamlessly into the rest of the design. It just makes things look more professional. That’s where Lightning Messaging Utility comes in. Here’s an LMU flag indicating they’re a current board member: Or a mentor Much better than Rich Text, right? Here’s a reminder for opportunities that don’t (yet) have products added. Sometimes you want to make it clear this was a major gift: Those examples are just taking advantage of LMU’s color options and the Lightning App Builder’s native conditional display of components. The possibilities are endless! Other Tricks One nice thing LMU can do that it’s very hard to do otherwise is display a pop-up window (a “toast” message). There are few ways to build pop-ups in Salesforce and sometimes you just wish you could force your users to pay attention. (Use sparingly.) LMU can also insert icons from the Lightning Design System. That gives you additional options beyond emoji, not to mention that those options all share the look and feel of the rest of Salesforce. Or you can mix and match emoji and SLDS icons, of course. How To LMU is free, so you’re going to get what you pay for. In LMU’s case the downside is documentation: You get a slide deck. That’s not ideal, so you might need to do a bit of futzing around. But this is a simple tool, you’ll figure it out!
- Apsona: The Golden App for Bulk Data Operations
If you’ve ever been in a conversation with me about my favorite apps or my Go To tools, you’ve heard me mention Apsona for Salesforce. I consider it so important that I require my clients to install it and maintain licenses as part of my contracts. I don’t want to waste their time (or mine) futzing around with other options for data import, export, and update. And despite a name that literally means “the golden app,” Apsona is not expensive at all. Let’s take a look at this little gem. The Apsona Tab When you click on the Apsona tab you get a “Salesforce inside Salesforce” interface where you’re going to interact with your records like a series of spreadsheets or list views. Apsona certainly has the ability to act on single records—including within the Apsona interface—but other than editing single records in a list view once in a while, that’s not what this is for. Apsona is your one stop shop for mass data operations. My Favorite Feature If I had to mention just a single feature of Apsona that puts it hand and shoulders above the Dataloader (or Dataloader.io), it would be this: You can copy/paste the data you want to import rather than needing a CSV. That alone saves me hours in a year. Think about it for a second. Excel always seems so surprised! when you select to save something as a CSV. You get a dialog box forcing you to confirm that’s really what you want to do every single time. (In fairness, it probably wouldn’t be. But Dataloader can’t handle anything else.) Apsona goes the extra mile to accommodate you. You don’t even have to save your sheet. You can copy several columns or the whole sheet, and then paste into a box in Apsona to do your import. (Works from Google sheets too, of course.) Bam! Fast Bulk Updates The other thing I use Apsona for all the time is its incredibly efficient interface for bulk updating records. Filter a list of records and it takes just three clicks to mass update a field (or fields) on those records. Super handy if you’ve just added a new field, updated a picklist value, or have to clean up a bunch of records. For example, what if you have 20,000+ contacts that have a value in Work Email but nothing in Preferred Email and you want to start encouraging users to utilize NPSP’s three email fields the way they were meant to be used. Simply make a filter for Preferred Email = null, they click Update All, select Preferred Email, and select Work. Apsona will churn through the records in a couple of minutes and you’re done. You can bulk delete records just as quickly. All I can say to that is, “With great power comes great responsibility.” 🕸️ Super Fast Export Probably next on my list is the ability to export records with just a couple of clicks. Not that I want you working outside of Salesforce that often, but we all know sometimes it’s necessary. Great for backups, too. If you’ve made yourself a tabular view, Apsona is smart enough to suggest the columns in your view for export. And then you can add additional columns just by checking a box. Columns on related records are also available. Click Export and you have a downloaded CSV in seconds. Other Features Apsona gives you a quick and easy way to make new list views and filter them and then it shows you the full record count. Since standard Salesforce list views don’t give you the total count and SOQL requires you to remember all the API names of fields, this makes Apsona almost always the fastest place to answer questions like “How many contacts don’t have a value in Ethnicity?” or “How many opportunities have a close date in the last fiscal year?” Working with Apsona you’re also not tied to page layouts the way you are in the regular Salesforce UI, which can be handy at times. Similarly to working in reports and list views, Apsona gives you the option of seeing fields that aren’t on the page layout or narrowing down just a couple of fields that you want to see at a time. Apsona respects user permissions so nobody is getting edit or delete access through Apsona that they wouldn’t have otherwise. And you can even set different configurations within Apsona by profile, so that some people might only be able to bulk edit certain objects or fields, depending on how you are doing things in your org. By the way: When you’re doing those mass operations Apsona defaults to batch sizes of 200 records at a time. But it’s very simple to lower your batch size if you’re running into problems. Sometimes I even set it down to five or even one at a time if an import failing due to timeouts (often caused by the NPSP triggers). Yes, the look is circa 2008 You’ve probably noticed from the screenshots that Apsona’s look and feel is a little…dated. What can I say? It’s functional and data-dense (translation: “That font is very small.”) but maybe not as lovely as it could be. I believe they’re working on an update. When that comes, I’m sure I’ll have gripes about not being able to find things anymore… Price I don’t feel bad requiring my clients to purchase Apsona because it’s a great bargain. For nonprofits it’s just $435 for three users, $145 each additional user. If you’re a tiny nonprofit (annual gross revenue not exceeding $250,000), Apsona donates three licenses for free. That’s part of the company’s commitment to nonprofits and the Salesforce community that I particularly appreciate. Most orgs will only give Apsona licenses to admins and power users, so you are probably looking at less than $1,000/year. The time saved pays for itself! Nice People The last thing I’m going to say is that Apsona is just made up of nice people. Their commitment to nonprofits is genuine, all are helpful and quick to respond, and they’re just lovely to hang out with. What more could you want?
- Tools I Love: DLRS (the Declarative Lookup Rollup Summary tool)
Let me introduce you to my friend, DLRS, pronounced either “dee-el-arr-ess” or, my preference, “Dolores.” That’s not its real name. It’s really the Declarative Lookup Rollup Summary tool. I think it’s more fun to call it Dolores because it helps me feel closer to this amazing, free, and powerful resource. DLRS was originally created by Andrew Fawcett to fill some gaps in Salesforce functionality. 🎂 DLRS is turning ten years old this month! That's something to celebrate! DLRS gives you rollup summary superpowers that no nonprofit admin should be without. But before I get into the superpowers, let me help you with some DLRS context, like what it means: Declarative This is the easy part. In fact, what it really means is “this tool is for everyone, it’s easy to use.” Declarative means that something can be done with clicks, not code. So from the start, we know that DRLS is built to allow you to do things that before would have required you to write code. (Quick side note: With the incredible growth in power of flexibility of Flow you could accomplish most of the functionality of DRLS now with Flow, which is technically a declarative tool. But that ability comes from the fact that flow has grown to straddle the declarative vs. development line. I consider it more work to build and maintain rollups via Flow than with DLRS, so I wouldn’t recommend that route. More on that below.) Lookup Lookup refers to the fact that DLRS can perform rollup summary operations across a lookup relationship in Salesforce. This is a simple relationship between records, where one has a reference to the other. Without getting too deep into it right now, there are times when a lookup makes more sense than the tighter relationship of master detail, often known as “parent/child.” Master detail relationships are not generally “reparentable,” usually involve cascade delete (if the parent is deleted, so are all the children), and also have implications for Salesforce record privacy (anyone that can see the parent can see the children). Standard Salesforce rollup summary fields (“RUS fields”) can only be built across a master detail relationship. DLRS allows rollups across the less-close lookup relationship. Rollup Summary Out-of-the-box Salesforce can make rollup summary (“RUS”) fields that show summarized information about child records, such as counting them, finding the largest (MAX) or smallest (MIN), summing, averaging, or the like. RUS fields generate some of the most interesting insights about your data, such as number of people enrolled in a program, attendance percentages, number of people in a household, etc. OK, that’s what it means. But the most important thing to know about DLRS is that it gives you rollup summary superpowers. And those are powers you might want to focus on master detail relationships as well. 🔋 Powers DLRS Has that RUS Do Not Whereas standard Salesforce RUS fields are limited to count, sum, mix, and max, DRLS adds quite a few operations you might want to do, including the ability to concatenate text. Two of DLRS’s powers that I think are worth calling out separately: Relative Date Filters One of the most common things people consider making a rollup summary about is to have a relative date filter such as “this year.” Perhaps you want to count applications “this year” or purchases “last month.” You can do that in a Salesforce report easily. And you can include relative date filters in formulas as well. But you can’t filter the records you’re going to summarize in a standard RUS field with relative date language. Averages Standard RUS fields can count or sum, but average is not an option. This means that the out of the box way to calculate a rollup summary average in Salesforce requires the admin to build three fields. (One to count child records, one to total the value in the child records, and the third is a formula that divides the total by the count.) Obviously this isn’t the end of the world, but DLRS allows you to accomplish an average with just one field, saving time and effort. So even if you are dealing with rollups across master detail relationship, DLRS is a great addition to your toolbox. Why DLRS and Not [fill in the blank]? There are two other tools people often suggest to meet a similar need as DLRS. Rollup Helper Rollup Helper is a freemium AppExchange tool. Nonprofits can have up to three free rollups permanently with Rollup Helper. Also, being a commercial product, Rollup Helper has a user friendly interface and, like DLRS, it can work across lookup relationships and do more kinds of calculations. Honestly, I have nothing bad to say about RollupHelper. I just prefer to save money for nonprofits, so I’ll go with DLRS every time. Flow As I mentioned above, Salesforce Flow has become a very powerful tool, with most of the capabilities of code. It’s not that hard to build a record-triggered flow that loops through related records to summarize them. One major limitation here is that if you want results in realtime you will have to build at least two flows: one on create or update of a “child” record, and one on delete. As of now (and I don’t think there is any roadmap for change any time soon), record-triggered Flows can have either a create/update context or a delete context, but not both. I also think that building and testing a flow (or modifying an existing flow) each time you find a new rollup summary need is significantly more cumbersome than building a DLRS rollup. Things You Might Want To Roll Up 🗞️ If you aren’t already brimming with ideas of things you want to roll up using DLRS or standard rollup summaries, let me try to jump start some thoughts: If you have students applying to colleges (or high schools) you’ll probably want to know: - How many applications does this student have? - How many acceptances does this student have? - How many students have applied to this school this year? - How many applied last year? - How many were accepted/waitlisted/rejected this year/last year? If you rescue animals you might need to know: - How many cats/dogs/rabbits are at each shelter? - What is the average length of stay in shelter? - What percentage of animals are awaiting urgent veterinary care? If you train teachers, you might want to count: - Enrollments in your mentorship program. - Completed/incomplete mentorships. - Teachers at each school that have completed your program. If you raise money for environmental causes you might need to know: - How many donations have gone to each nonprofit partner? - How many unique donors have given to each partner? If you run a women’s shelter you’ll probably need to know: - How many times has a client been in shelter? - What is her average length of stay? - How many services did she access while in shelter? This list barely scratches the surface, of course. Your own program is going to determine the fields you need. If you want even more inspiration, look at the DLRS Cookbook, which has example rollups and instructions for building them. [Full disclosure: I helped write that cookbook.] One More Thing To Love: DLRS is now part of Open Source Commons Andrew Fawcett and a handful of helpers kept DLRS up to date entirely on a volunteer basis for many years. We all owe them a huge debt of gratitude! "This tool was initially a solution looking for a problem and in part a technical demonstration of the Metadata API," says Andrew Fawcett. "And wow did it ever find its place as a solution for many of its users! At its heart at the very start was a desire to continue to do what the platform does best: democratize capabilities—and that continues to make it so popular today." In order to ensure the continued development and support of DLRS, in 2022 Andrew asked if people could step in to take over DLRS. Now it's become part of the Open Source Commons program. That means this app has a formal structure to support it, expand it, and ensure that it will forever be free for nonprofits and anyone else that wants to use it. "Thank you everyone for your support and encouragement over the past 10 years, I cannot wait to see what it looks like in 10 more years!" - Andrew Fawcett I’m proud to volunteer my time for the DLRS project, helping with writing and editing documentation. It’s one of the ways I try to give back to the amazing community of Salesforce professionals that have helped me so much. Go Out and Try It! I hope I’ve convinced you that DRLS is a tool you want in your toolbox. Be warned: as with any tool, you’re going to have to learn how to use it. (Even wielding a hammer is not as simple as just grabbing it and swinging!) I think it’s beyond the scope of my blog to make this or a future post into a full scale How To Build Your First DLRS. But don’t worry—the DLRS documentation is extensive and the documentation team is constantly working to expand it! Need further help? Just ask in the Community Project: DLRS group on Trailblazer Community.
- Rollup to Relationship: A Cool DLRS Trick
I’ve already written about DLRS, or Dolores, one of my favorite free tools that gives you rollup summary superpowers. Today I want to tell you about a cool trick you can do with DLRS that kinda’ isn’t a “rollup” at all. Most of us, when we think of a “rollup summary field,” start thinking in terms of math operations like average, or count, or min, or max. Makes sense. If you think about rolling up information about a group of related records (also called “child” records) onto one that they’re all related to (the “parent”), those are the main uses. I could count the number of support cases that go with an account. Or I could count the number of sessions a student was late for, then count the number of total sessions, then divide the former by the latter to get an attendance percentage. Or maybe I want to sort through all the memberships a family has purchased and roll up the date of the most recent one to know when their membership is going to expire. Or you could count the number of memberships that family has purchased over the years… But here’s some outside-the-box thinking: You can make a rollup summary field that itself creates a special relationship to just one of the child records. (I know it’s generally frowned upon to single out one of your children for special treatment, but…) Perhaps your database tracks a price each year: Campbell Scholars Program wants to be able to give solid college choice advice to their students. So they want to know the tuition cost of any college or university their students are applying to each year. PA Virtual Charter School is paid by school districts for each student enrolled. But districts have different rates from each other and those rates (of course) also change each year. In each case we have a custom object,Tuition Cost, that holds child records to Account (representing the college or the school district). For each account for each year there is a tuition cost record. (We also know that there must be just one for each year, so we take other steps—that I won’t outline here—to make sure there is only a single record per account per year.) We have a “year” field on that record that is either itself a date field or it can be translated into a date by a formula field. It’s now very easy to make a DLRS rollup that finds the last tuition record ordered by the date field. That’s not where the magic comes in. The magic is what we’re doing with what we’ve found. We're not looking at a number field (like the tuition cost) and doing math on it. Nothing of the sort, in fact. We take the Id of that record and we put it into a target field that is, itself, a lookup relationship field. In the Salesforce user experience when you see a lookup field it shows as a link to the related record. But under the hood that field actually holds the unique Id of the related record, which is 15 characters of text. So by using DLRS to put an Id in that field, we have actually created a relationship–a link to the “most recent child tuition rate.” Once you have a relationship field like that, you can make formulas that span that relationship. That means that if a Campbell scholar is interested in a particular school, as soon as we create a college application record (to track that interest) we can show the school’s current cost just by putting a formula field on College Application. When PAVCS wants to generate an invoice to a school district, the invoice record (child to school district) already knows what the current tuition cost is for that district. I think that’s very cool and there are lots of ways to use it. Can you think of nifty examples in your org?