Richard Clark is the Chief Innovation Officer for Provar Testing. He recently spoke at the 2021 Cactusforce virtual conference and, in his talk, he discussed integrating Slack and Salesforce together. 

Today we continue that conversation on the podcast.  Richard shares why Slack was an attractive solution for their sales teams, the various forms that the integration took and some of the pros and cons of “low” vs “pro” code solutions for working with Salesforce.  Have a listen and learn how you can build a Slack integration.

Show Highlights:

  • How Richard got into the Salesforce ecosystem.
  • Why he chose Slack as the integration point for Salesforce.
  • The problems he was trying to solve with the integration.
  • What the AppExchange plugin does.
  • How webhooks open up more functionality within Slack.
  • What External Services are and how they help with integration.
  • The considerations to take within Flow while integrating Slack and Salesforce.
  • Where Apex is needed in this process.
  • When to use Queueable Apex vs. the Future Method.
  • How users are reacting to this integration.

Links:

Episode Transcript

Richard Clark (00:10):
Engagement with the Salesforce and other technology communities, position of our product, and just thinking outside the box. So instead of looking inside all the things that, you know, we want to do and enhance the product on the micro detail, thinking more at a macro level, how we work, how we fit into DevOps pipelines, that kind of thing.

Josh Birk (00:29):
That is Richard Clark there describing his role as chief innovation officer for Provar testing. I’m Josh Birk, your host for the Salesforce Developer podcast, and here on the podcast, you’ll hear stories and insights from developers for developers. Today, we sit down and talk with Richard about a topic he brought to the Cactusforce Virtual Conference, that being integrating Slack and Salesforce together. But we start as often with his early years.

Richard Clark (00:53):
Yeah, that’s an interesting one. I, um, started in, uh, home computing area in the ’80s as a teenager. Uh, you know, when you used to, uh… You’re probably a bit young for this. Used to have to write games by typing them in from magazines, (laughs) and I used to do that, in fact I used to publish them as well. I used to actually, uh type up on the typewriter ’cause we didn’t have a printer, the games I’ve written and send them into magazines, and then helping with the bug fixes, (laughs).

Josh Birk (01:17):
No way-

Richard Clark (01:19):
Yes, that’s how it works.

Josh Birk (01:21):
So first of all, I wanna thank you for thinking that I’m that young, (laughs) because I remember like I almost… I almost had a, “I never wanna do computer programming again,” moment because I got so frustrated with, with a syntax error. So I was putting in because hi- was typing them directly from the magazine. But I love the fact that you are so old school, you’re actually the person who was typing those up for, for the magazine to publish. Okay, first of all, first computer, what was it?

Richard Clark (01:46):
Uh, Acorn Atom followed quickly by TI-99/4A.

Josh Birk (01:51):
Nice, nice. TI-99, I think was one of the first personal computers I ever played a game on. There was this thing where you… What was it called? Vector, or something like that. You’re f- you’re flying a ship in a cavern until you hit too many things, and then, and then Parsec, I think it was called Parsec.

Richard Clark (02:06):
Oh, Parsec, oh my word, I used to, uh, be on the leader board for, you know, when you just have to use that old fashioned camera to take pictures that you’d clock to Parsec, yeah, my word.

Josh Birk (02:16):
Right, right. Nice. Very cool. So, okay, you’ve always been in the community. How did you get into the Salesforce ecosystem?

Richard Clark (02:22):
So that was an interesting one. I’d actually been in IT quite a number of years, and I hadn’t realized at the time, I’d been developing CRM applications, of course we weren’t calling them then, we were calling them order management apps, and were calling them customer databases, and I was sick and tired of doing login pages, and registration apps and things like that. And, uh, I guess we’d come across master data management, but it wasn’t called that then either. But I, um, I was fortunate to join a company back in 2007, who wanted to be the next Salesforce, and they’re actually a Salesforce platinum partner now. And that was where we sort of ended up sort of one of our customers wanted to implement Salesforce says, “Okay, we’ll do this.” Um, and I think Apex had just come out, yeah, Apex had just come out, and I did a presentation about it, not realizing no one else had written a line of Apex yet. So I got lucky with that one, and it’s just been a, sort of a… More of an upwards rollercoaster ever since.

Josh Birk (03:16):
Okay. So today we’re talking about your Cactusforce presentation, that was Salesforce integrating and various ways back to Slack. But let’s start on that touch point; why Slack as the integration point?

Richard Clark (03:28):
Okay. So, really that started as a request from our CEO, Gerund.

Josh Birk (03:33):
Mm-hmm (affirmative).

Richard Clark (03:34):
He had said to me that he wanted to share all the wins, all the new business we’d won, with the whole company, and not… We only had, I think at that time we only had, uh, 30 people on Salesforce, now we’ve got more like 60. And so the other sort of 50% of the company were not on Salesforce, but we… They were using Slack. And he wanted to make announcements. And I, I think I started off showing him how implemented the apps from the app exchange and from the Slack app store,

Josh Birk (04:00):
Gotcha.

Richard Clark (04:00):
… I said, “Yeah, but no, I want to say this.” I was like, “But it doesn’t do that.” “Well that’s gonna, that’s going to be a few weeks work.” And I went away Googled it, found an article by Christophe Kendrix, I thought, “Let me try this and put it in New York that afternoon.” Then he asked for more changes of course that’s the way-

Josh Birk (04:16):
Of course. (laughs) That’s all right. So when you say, “Make announcements,” like why was that so attractive? What kind of problems were you trying to solve by being able to kind of broadcast things in a channel like Slack?

Richard Clark (04:30):
Yeah, I think as part of the sort of growth of a business, where from having, I think when I joined Provar, we had maybe 50 customers, we sort of tripled that in a very short amount of time.

Josh Birk (04:40):
Mm-hmm (affirmative).

Richard Clark (04:41):
So in terms of our accounts team and our customer service team, and our consulting teams, and our developers, didn’t actually know who our customers were anymore. Uh, so these names would crop up, and people wouldn’t know if they’re a new customer or not. But by putting that announcement out, one, we were able to communicate an indication of the deal size, how big a customer is this, it also gave people a feel-good over the brands that were there, the company brands that we were dealing with, just uh, excuse me a second, I need to let the cat out now.

Josh Birk (05:11):
(laughing).

Richard Clark (05:11):
There we go, first world problems of working from home.

Josh Birk (05:17):
Exactly, exactly. First of all, I have to ask, what’s the name of your cat?

Richard Clark (05:21):
Uh, that one’s Molly.

Josh Birk (05:22):
Molly, okay. Um, 50% chance that you’re gonna hear the same for me, my feral cat, Shadow has started making a habit of coming in and yelling at me, and then running out of the room. We’ll see what happens. You were talking about your broader audience, not knowing about new accounts and clients coming into your ecosystem, am I right?

Richard Clark (05:39):
Yeah. So, um, by building that awareness, it made everyone feel good. They knew, they could see what was happening without having to do a boring monthly, “Here’s the company revenue chart.” They were able to see things were happening. And we sort of extended that out to say, “Well, this customer has renewed. And this customer is an expansions.” We just sort of expanded that sort of share knowledge about customers. But I think the biggest gain was that where our staff knew a customer was new, they probably had more patience, and we’re more focused on being more reactive, more responsive to those customers, knowing that there were new customers. So that actually there were things they didn’t know, maybe they hadn’t seen some help documentation. So it really helped build awareness, I think.

Josh Birk (06:16):
So it sounds like you were kind of building a dial tone of information that was kind of stored in Salesforce that they would not normally like, they… It almost sounds like they would have to be logged into Salesforce constantly in order to be aware of this information.

Richard Clark (06:29):
Exactly. And I actually implemented as a chatter automation at first, but that was the problem that only the people that were already on Salesforce knew about it. The wider team just didn’t know who these customers were, or what the deal size was.

Josh Birk (06:41):
Got it. Okay, so you’re talking about solutions that work with Slack and Salesforce across the spectrum. We’re gonna talk no-code, low-code, pro-code, this being a developer product podcast, I definitely want to get in the weeds about like, you know, how were forming the Apex, and what are the advantages there, and stuff like that. But let’s, let’s go ahead and start at the low end of the spectrum. And you just mentioned it there, you’re installed… There’s an app exchange plugin, that works with Slack. What exactly does that package do?

Richard Clark (07:07):
So it’s actually been enhanced recently. It gives you an option to set up a number of, uh, events, um, almost like, if you think about how pushed topics are to messaging. Yes, you can say, “Here’s a predetermined event, and this information will be sent on this, uh, predefined channel when this event happens.” So there’s a number of configurations you can do with that, but you can’t really customize the format of the output. I’m not even sure if it, how it respects field level security and things like that.

Richard Clark (07:38):
So it, it does quite a lot of things now. Um, and you can actually extend it with code as well. But I like, if I start writing code, I prefer to sort of own the whole thing, and understand the whole [crosstalk 00:07:50]. Yeah, exactly. Rather than sort of build on top of something where I don’t really know what’s happening under the covers. I don’t know how it’s sharing record access, I don’t know how it’s looking at field level security.

Josh Birk (07:59):
Mm-hmm (affirmative). Because this is a managed package. So you can’t like, see exactly the lines of code that’s being run there, got it.

Richard Clark (08:05):
Yeah, yeah.

Josh Birk (08:06):
Okay. Okay. So that kind of answers my next question, but is there… Was there any other inflection point where you’re like, “I wanna throw a flow at this.” Or, “I want to throw Apex at this.”

Richard Clark (08:16):
Yeah, so that was, um, I’m a big fan of Vocable Apex, And I so, trying to always write something so that I’m not dictating the business logic when something will happen, I’m just enabling it. So I think even with that opportunity to publish, the first thing I did was do it within vocable Apex. And so I exposed that to our, uh, admins to use, and they could say, “Use that same Apex code for the opportunity, but actually, because they were writing the message, they could change what it said, uh, what the details were, what fields they wanted to include, and they were able to use on case. And they’re able to use it on, uh, our trial record custom object as well. So we had to reuse that. So I quite liked that. I’m a lazy coder, I don’t have to decode if I don’t need to.

Josh Birk (08:57):
(laughing) Nope, I, I love it. And that’s, that’s kind of… That’s, I find that interesting because it almost sounds like the plugin almost serves as a prototype, like a test thing, but it doesn’t seem like the amount of effort to put into your implementation that you showing at Cactusforce is so much more code and work, it almost… You know, what I, I’m like having ownership over that code feels like it’s more useful than just having a plugin that you don’t have to worry about.

Richard Clark (09:28):
Yeah, I’ve found the plugin was really useful for convincing the stakeholder. So it showed our CEO, “Look, this is what you can have. This works, and it’s free.” He’s like, “Hmm, that’s quite nice.” But as soon as you have that, can we just conversation? Invariably, it can become more difficult to adapt to, to those plugins, and use someone else’s code than actually understanding. I actually gained a lot personally from doing it, I, I’d never used the cube interface before, um, I didn’t realize some of the sort of reverse stuff I’ve done since, I’d never realized why I was doing was Apex rest services. I just thought, “Well, that’s fine. That makes sense. These annotations? Oh, it must’ve always been that way. I didn’t realize that I was new, that was just the… “Oh, that works.”

Josh Birk (10:12):
(laughing) Nice. Okay, so… And I wanna get into some more of those details, but let’s start backwards, and go into more details on how Slack itself is set up for this. So, like kind of define a webhook for me, and what kind of functionality are they exposing in Slack?

Richard Clark (10:29):
Okay. So that’s interesting that it, it, it has a lot of parallels, it resonates with me, the same way Salesforce does that.

Josh Birk (10:35):
Mm-hmm (affirmative).

Richard Clark (10:35):
If I wanna extend it, I create an app. And I create that app within my own workspace, and I can do that, I can sign up for my own workspace, for free, and I can build in there. And in those apps, there’s various things you can do. Um, you can even create your own bots, so conversational apps if you like, you can have buttons, um, you can give the app permissions to read from certain channels, to post messages, reply on threads. So it really feels like Salesforce in many ways, that’s really easy to sort of build something, and declaratively as well. And when you add an app, uh, you can add a webhook, and that webhook can, uh, then be given, assigned to a particular channel, and then just get a good word for that, or you can use, uh, uh, a OAuth to integrator.

Richard Clark (11:20):
The other thing you can do is, there’s a concept of workflow in Slack as well, that’s a paid feature, so you can’t use it on the free, uh, tier.

Josh Birk (11:29):
Okay.

Richard Clark (11:29):
The workflow is nice because, if you think about an org in Salesforce, the admin for that, isn’t normally going to be the same admin as for your Slack, probably completely different teams. May they talk to each other.

Josh Birk (11:40):
Right.

Richard Clark (11:40):
So with workflows, your Slack admin can control what the message is that’s put out, and what access it has all within their domain, and they can expose attributes or parameters that you want to include, and they could do the formatting and the message. And that was the sort of.. The low-code solution I did with flow, was around using a workflow instead, but both use webbooks at the end of the day.

Josh Birk (12:03):
So, am I getting it right? That the workflow can kind of set up like a, almost like a Mad Libs structure, and then you’re just putting in the nouns in the verbs that the message would go out to the channel?

Richard Clark (12:13):
Exactly, and then the formatting and the markup. Whereas if you do the sort of free web book version, there’s something called the block kit, and the block kit is the sort of Jason schemer for formatting messages in Slack. And it’s really powerful. I mean, you can do some fantastic, you know, graphics and buttons, and, uh, modal entries and all sorts of things with it, but it is extra work. Whereas if that’s done within the workflow in Slack, it’s kind of a, again, it’s sort of that low-code option to doing it, uh, instead of having to sort of maintain that outside the Slack application in something like Salesforce.

Josh Birk (12:47):
Interesting. I, okay so even in prepping for this, I was not aware… When, when I was looking and sit- seeing formatting and things like that, the concept of being able to even provide a modal window. So then you can have client interactions based on the webhook messages?

Richard Clark (13:03):
You can, yes, absolutely. And, they’re all simple buttons, or, you know, if you went to a poll application, things like that, you could bake the, the answers or the questions in or out of Salesforce if you wanted to.

Josh Birk (13:15):
Interesting. Okay, I want to touch back on what you said briefly there. So when you set up the webhook, you get a guide, which in and of its own right, is kind of security through obscurity. And you mentioned, you mentioned OAuth, but do you have any tips or suggestions for making that webhook secure?

Richard Clark (13:35):
Uh, I mean, just following the documentation. One of the challenges I had was I didn’t understand if I can have it as a connected app, what is the, um, system mapping on that, or I didn’t want to connect it as me. Um, so I wanted to make sure that that was only given away the permissions in visibility of data.

Josh Birk (13:53):
Right, right.

Richard Clark (13:53):
I wanted to… It’s definitely one to look at, and one where I didn’t have a problem ’cause I was pushing many from Salesforce, the content I wanted to push on very public events, um, but if I was writing a Slack app to query back into Salesforce, I’d be a lot more careful.

Josh Birk (14:11):
Got it.

Richard Clark (14:11):
Um, on the… Or the other way round, from Salesforce to Slack. I mean, you could, you’re only exposing from Slack saying, “Right, these are the public channels or channel that this app can talk to, and that webhook can only publish, their, their information.”

Josh Birk (14:24):
Got it. Okay, so on the Slack side, and how is the webhook, when you send a message to the webhook, who is… Is it like a bot user that’s being set p, or like an app user that’s being set up in Slack and that’s who says, “This is my message, to everybody?”

Richard Clark (14:37):
Yes, so the app has, uh, it says it’s posted by the app itself. Uh, so the app in a little logo or icon that you wanna associate to that is sort of broadcast and that rather than it saying from Slack admin or anything like that, it’s the app name. And I called it the app, I think the first one I called it was Opportunity Publisher. And of course when the admins then used it for cases, I was like, “Okay, I’m gonna rename the app. Of course it’s not there anymore, so yeah, you do need to think carefully about what that thing is, or you just create another app. Um, and you can even share those, you can publish those just like app exchange apps. You can publish them on Slack, share them with customers if you wanted to.

Josh Birk (15:13):
Got it over. Or refactoring dynamics go creep. I hear you, I hear you.

Richard Clark (15:17):
Mm-hmm (affirmative) Indeed.

Josh Birk (15:18):
(laughing) Okay, so then going back over to the Salesforce side, if we start going to… From the kind of no code, which is the plugin to the low-code, which is completely Sans Apex, I kind of feel like we’re about to go through like a penny tour of nouns, which have kind of come up on the pod a few times. So let’s start with probably the, the main one, which, which is external services. So what are external services, services on the platform and how are they helping you get this job done?

Richard Clark (15:47):
Okay. So I talked just now about the workflow in Slack.

Josh Birk (15:53):
Mm-hmm (affirmative).

Richard Clark (15:54):
The workflow in Slack has a particular format or schema. So you need to be able to generate an open API schema for that.

Josh Birk (16:00):
Mm-hmm (affirmative).

Richard Clark (16:01):
I was fortunate that someone else has already done that hard work using Swagger, And I took what they did, and boy… Oh boy, did I have problems when I wanted to adapt it thinking, “I’ll just add this in.” It’s like, “Well, why doesn’t it work? Why doesn’t it accept?” And I listened to your talk with Tony a couple of weeks ago, um, about waves of open API three, and I thought, “Aha, that’s what I need.” (laughing). Open API too it doesn’t work. So inaudible 00:16:27] is great way to call those functions without code, without writing those HTTP requests, for compatible interfaces. And that word compatible was quite key. And it’s was only ’cause someone else had done the heavy lifting that I found, “Uh, here’s a, uh, schema, uh, for that message for that open API interface that I could use.” And then the plumbing of… I’ve got to say, I know we say flow is low-code, but elements… If it wasn’t in a video, I’d struggle with, uh, sometimes. So…

Josh Birk (16:55):
(laughing) Well, and, and again, we’ve had that theme on the show several times. It’s like, and I feel like a lot of developers in their community do kind of push against the low-code branding, because… And they, they kinda replace it, and I, and I love that you just said that video said you’re… It said you’re right, because they’re like, it’s kind of like visual coding. You have something that’s like functions, you have something that’s like variables, you’re just not really calling them that, and if you don’t go through the right visual steps, then, you know, you’re… Your hands a little tied behind your back. But it, but it has a programmatic feel to that. Would you kind of agree with that?

Richard Clark (17:29):
I Would, at the same time though, as a programmer, your mind is objecting to…

Josh Birk (17:34):
Mm-hmm (affirmative).

Richard Clark (17:34):
… “Okay, now I declare a variable, now I give it a value, and now I assign it to this other thing.” And you’re like, “But I can do that in one line.” (laughs) And you sort of don’t wanna have three steps to do something like that. And that could be the, uh, that could be the challenge.

Josh Birk (17:48):
Yes, you have… You have just encapsulated my mental challenge with, with becoming a flow expert. And it is as primordial as muscle memory, I swear. Because it’s like, “I know what you’re trying to do, and I wanna, I wanna type the word, far.” And then you won’t let my fingers type the word far, and I’ve, I have completely been there. My next question-

Richard Clark (18:09):
But, so you want a debugging then-

Josh Birk (18:09):
Yes.

Richard Clark (18:09):
… it’s actually, you really appreciate how it’s broken down, when it comes to debugging, and what goes wrong.

Josh Birk (18:13):
Which I feel like is a huge evolution of flow. That that was one of the things that frustrated me so much about it in its early days, and I have heard… And seen over and over again that it’s gotten a lot more mature in its, in its more relea- recent releases.

Richard Clark (18:27):
Absolutely.

Josh Birk (18:27):
And I was gonna have a follow-up que- question about the role of Swagger and open API, but I think I will have to ping Tony, (laughs) and, and tell him that the role of open API was pointing in the right direction, I think that’s wonderful. Were there, was there stuff that you had to do in flow before you could just kind of build out that step to say, send this message?

Richard Clark (18:51):
No, I mean, once you’ve created that external service within the flow, and you create an action, um, one of the… I’m trying to remember one of the options, an action you had to go custom and pick, was that Apex-managed or something? It’s effective, I’m guessing create an Apex class view in the background, the same name as the external service.

Josh Birk (19:08):
Mm-hmm (affirmative).

Richard Clark (19:08):
That’s what I’m assuming it does.

Josh Birk (19:11):
Gotcha. Right

Richard Clark (19:13):
There’s just a magic that appears, and then because you’ve then picked that service, it then knows what the attributes of that service. So then you can use the dot notation to access and assign your, maybe it’s an input variable, or maybe it’s a field that you’ve read with a read on the object, depending if it’s a, obviously how it’s initiated, that flow, and then you do your assignment step.

Josh Birk (19:35):
Got it. Okay, so the external services are setting up the HTTP/rest handshakes, the schema is describing the dictionary that can be used to talk to that external service, and then within flow, there’s basically a push button way for some magical Apex to be written in the background, that you say, “Here are the inputs I want to put in that schema, go do all the hard work for me.” Does that sounds about right? Okay.

Richard Clark (19:59):
And I’m sure… Uh, that’s how it is. I’m sure I could probably put my own code in there if I wanted to as well, but it was kind of one of those sort of Eureka moments where you think, “I did that over here and by magic, I can now talk to it in flow.” Um just a special moment.

Josh Birk (20:15):
In any considerations within flow, like, does this work equally well in headless versus like a ScreenFlow?

Richard Clark (20:21):
Yes. Um, so I’ve made the… I, I use the ScreenFlow to test it, so that was the first thing. So if I get it working with ScreenFlow, I can do a lot more manual unit testing-

Josh Birk (20:32):
Oh sure.

Richard Clark (20:33):
Than if I’m trying to wire up automatically and thinking, “Did it not fire? Was my conditions, right?” Or, “Why didn’t I get message pop up?” So I tend to do everything with a screenplay first. And once I know that’s working, and my external service works, and my attributes are coming out as I expect, I can then create, uh, a lot auto-launched one or, uh, sort of triggered one. Um, obviously one of the key things is when I did it in Apex, I used curable because I wanted to have that ability to make sure it can scale, and that things that can be changed if I want to, so the messages arrived in the right order.

Richard Clark (21:07):
Now will flow, I didn’t have the option. I couldn’t say, “Make sure that this message is post-posted before this one,” it’s up to the platform, how files those events, and I still have to think about actually that this flow can be fired, I assume on multiple updates at once, and you wanna think about, “I probably don’t want within, uh, something like a Slack post, I don’t wanna fire 100 messages in one minute.” Uh, I’m ruining Slack if I do that. Um, because if people, everyone’s phones in your office, when we’re back in the office, start going, “Cutching, cutching, cutching,” uh, you’ll probably, uh, not be employed for much longer. (laughing) So you definitely wanna think about that as when it’s a, uh, not a visual-initiated flow.

Josh Birk (21:51):
First of two pro tips there, um, and I, and it’s, like I’m now I’m remembering, uh, Daniel Host’s, uh, episode where, where he’s like, “Yeah, it was great when I alerted all of my engineers that they were breaking their limits until I was doing it every single minute.”

Richard Clark (22:04):
(laughs).

Josh Birk (22:05):
And I was like, “Yep. Good, good tip.” It’s… Actually, yeah, Let me just follow up on that really quickly. So is there anything on the Slack admin side to throttle that, or is it really up to the implementer to be a good neighbor and not fall into that kind of behavior?

Richard Clark (22:20):
Yeah, I, I think it’s down the implementer. Um, one of the things you can do is use the threads in Slack. So if some extra permissions you grant, just to make sure scopes that you add to your Slack app. Um, if I was doing in with an Apex mind on what I would do is, iterate through those records and maybe say, there are 32 updates, and then post them on this thread,

Josh Birk (22:37):
Mm-hmm (affirmative).

Richard Clark (22:40):
… um, and then I wouldn’t necessarily get notification for every single one of those. Obviously within Slack configure as well, whether a channel is muted or not, I know I could try it for myself, I haven’t checked if it I can do it programmatically. But you’d probably want to think about those things, and not having it wake up your global sales team in the middle of the night.

Josh Birk (22:58):
(laughs) Yes. And how easy would it be just to like set up a test channel that you’re the only user on? I guess that depends on your [crosstalk 00:23:03].

Richard Clark (23:02):
That’s, that’s what I was doing. I mean, I use a test workspace first. So the first thing I tend to do is, like I, whenever I, um, do think like the cats sports talk, I, uh, try and use a free Slack workspace and work in there, so I don’t disturb anyone.

Josh Birk (23:16):
Got it.

Richard Clark (23:17):
Um, and then if I need to pay for it, I mean, I up- I upgraded for one user when it was at $10 a month or whatever it was.

Josh Birk (23:22):
Mm-hmm (affirmative).

Richard Clark (23:22):
Um, so it was nothing in terms of, uh, a little bit of investment of my time and effort to do that, to get extra features, but it’s quite easy to do that. And then when I’m ready, yes, I’ll put it in a channel that’s just me in that channel, no one else can see it,

Josh Birk (23:35):
Mm-hmm (affirmative).

Richard Clark (23:35):
… and, you know, I’m not big on adding everyone and their dog to a channel, and let people, uh, joining channels ’cause they’re public, and if they’re interested.

Josh Birk (23:43):
Yeah.

Richard Clark (23:43):
But we did actually put the opportunity announcements in our general channel because that was considered, you know, a company-wide communication. But more I was saying to people, “You got to think about what that channel is for, what’s its purpose, and don’t bombard people.” Same with email. You know, they don’t wanna wake up to 10,000 Slack messages.

Josh Birk (24:00):
Right, right. Exactly, exactly. Okay, let’s talk a little bit more about the Apex side of it… Side of the implementation. I think you just touched on it a little bit there, but if you have more detail on like that, because it’s… In my mind, thinking about the flow of external services seems like a very straightforward visual code implementation, pretty quick and easy to do. But what were some of the things that you were just like, “No, I really need Apex to solve this for me.”

Richard Clark (24:28):
So the main one was if I want to format that message, then the… I would hate to be trying to construct a JSON payload in flow. It’s not exactly… We don’t have the merge fields that you have in event process builder, for example, at the moment. Or I can look out to do them. So string concatenation in flow with lots of assignment functions is, is not nice. So if you want to format that message and use the block kit, then you 100% have to use Apex.

Josh Birk (24:54):
Okay.

Richard Clark (24:55):
If you want to… Um, as I say, if you want to make decisions on how you present that, so you may say, “Actually, I’ve got three options here, I might wanna put some buttons on, and make it bold, or I might want to, uh, make this part for thread. Uh, the other thing of course is, I don’t just have to post things to Slack. I can actually query things in Slack.

Josh Birk (25:14):
Mm-hmm (affirmative).

Richard Clark (25:15):
And I can’t do that easily, so I can tell with the flow, but in Apex, it’s much simpler to me to look at that and know, “Actually I’ve got that scope, I can actually go and see, has anyone been talking about X or Y?” Um, or if I want to go across channels as well, it’s easier to do that within Apex.

Josh Birk (25:30):
And are you still utilizing like the webhook implementation for that, or are you falling back on like a Slack API?

Richard Clark (25:37):
Uh, a mixture of both. So the webhook API tends to be bound to an individual channel.

Josh Birk (25:42):
Mm-hmm (affirmative).

Richard Clark (25:42):
Uh, so if you’re working on a single channel, that’s fine,

Josh Birk (25:45):
Mm-hmm (affirmative).

Richard Clark (25:45):
… uh, but you need to use the Slack API if you’re doing more [crosstalk 00:25:48] exactly.

Josh Birk (25:49):
Got it. Okay. All right, so talk to me about the curable annotation, and kind of, because I’m old school, and so I kind of, by going back to the muscle memory thing, I’m, I’m still fondly remembering at future. But how do those two compare, and why would you use one versus the other?

Richard Clark (26:06):
Yeah, so I originally did atFuture, and I think the first thing I hi- had long was, I’d created, uh, in a class to define the structure of the message I wanted to the pass,

Josh Birk (26:14):
Mm-hmm (affirmative).

Richard Clark (26:15):
… and of course you immediately go, “Oh, can’t do that.” And you think, “I want to use the next objet.” “Oh, can’t use that.” So in fact you could only use, um, primitive types,

Josh Birk (26:23):
Yes.

Richard Clark (26:23):
… made my I thought, “Um, this isn’t a very, uh, extensible solution.” And I’ve got to pre-format the message before I pass it in post, so I thought of when I came across the keyboard interface, and Christophe had mentioned it, and then I saw the light that I can pass these complex objects, and I could pass this array, and I can just do stuff with it.

Josh Birk (26:42):
Yeah.

Richard Clark (26:43):
Uh, that was the biggest one. And then seeing actually the governor limits were better, with that I could control the sequencing if I wanted to, have them chained so that my messages come out in the right order, I mean, those were, those were massive decisions as part of that.

Josh Birk (26:56):
Yeah, I mean, atFuture is a good old friend, but it really is, at the end of the day, is simply an antique annotation that does a little stuff in the back end, where curables, you know, it’s more of, um, I, I wanna say framework, but that’s not the right word, but it has a lot more tools in it’s docket.

Richard Clark (27:11):
Absolutely. It’s the, is there any way, probably… I don’t know if I’d ever use an atFuture again now. Um, if I, if I did a code review now and I saw an atFuture and it’d just been written, I’d be asking, why?

Josh Birk (27:20):
Why, yeah. And I’m kind of padding, if, this was in video padding atFuture on the head, but I completely agree with that statement. (laughing) So let’s move to the other important one, invocable method. Anything people should know if they’re setting up a class for that, invocable method is for exposing to flow or process builder, correct?

Richard Clark (27:42):
Yup. So I guess the first one is, un- unfortunately we can only have one invocable method per class, which can-

Josh Birk (27:49):
Gotcha.

Richard Clark (27:49):
… really constrain your thinking and redesign your a, uh, class model that you’ve carefully put together of what’s gonna be in there. Again, the ability to pass a complex object, you can do that,

Josh Birk (28:00):
Mm-hmm (affirmative).

Richard Clark (28:00):
… uh, and, you know, class get is a great way to do that, and making sure that you correctly provide descriptions for any attributes that you have, so you can control what people… and they know what they’re using. Otherwise, you end up the uh, if you’re not careful, you end up with just an array that appears in the say, process building, and you have to work out what goes in position zero, what goes in position one? So using those techniques, um, is, uh, a great, it’s a great documentation on doing that on Apex.

Josh Birk (28:26):
Got it. Because this is kind of like that portion of LWCC, where you have to be very mindful of the configuration, because code isn’t looking at this, it’s actually a user interface that an admin is gonna be looking at it, and you’re, you’re talking directly to a human.

Richard Clark (28:41):
Exactly, exactly. It’s just, someone’s going to be at the end of that. And it’s… I actually used to use process builder quite a lot, uh, but I was a late flow convert, um, I’m still waiting for that button, that I know you can view flow, uh, process builders in flow, but wait, that button just converts it for me, rather than me having to go through the effort. Um, but yeah, uh, that’s something I think I just find it’s easier. When you’re doing it you find it sounds, very, very simple, um, it’s just a nicer interface at times. Um, but it’s not the future, that’s for sure.

Josh Birk (29:10):
Cool. Okay, so let’s talk about like current state, like for… You started with the plugin, you, it sounds like your production code is, is kind of now to the pro-code side of things. First question is like, how, after you’ve gotten these requests and it’s kind of, you know, the scope creep has sort of pulled in, like how complicated would you describe your, your current solution for handling this?

Richard Clark (29:33):
Um, I think the… What we actually got in our production is still very simple, that we have, uh, flows that are, I say controlled by admins of the things I wanna post, I’ve got my Apex class, my Slack publisher class, which I recently put into a ORC-dependent package, you know,, that’s another subject.

Josh Birk (29:50):
Huh.

Richard Clark (29:50):
Um, so I just found… I wanted to maintain that outside of our outsourced Salesforce provider, I wanted to still own that code, so I put it in an unlocked package. So I could do that without worrying about scratch organization, so that was like, “Oh, this is easy.” So you’ve got a test class, some data, and a name credential I think, in there with the actual Apex class. So that was the easiest one-on-one package ever.

Josh Birk (30:13):
Got it.

Richard Clark (30:13):
Um, it’s, it’s really easy for me to do that, but the flow side stays within the org, so stays with the happy soup.

Josh Birk (30:20):
Nice, nice. Okay, and so, yeah. I think I need to clarify, because you’re actually using, you’re not really using the plugin anymore, but you’re using the whole spectrum of things so that whoever has to have access to this, to get their job done, whether they’re a hood or an admin, they’re just sort of coming at the entry level that they’re comfortable with.

Richard Clark (30:37):
Exactly. I mean, we try and limit the amount of code, but yeah, anyone else coding could again code the methods on there, and make the same codes and, uh, invoke the same actions, et cetera. So, absolutely. But mostly assays done, we try and have all our business processes in admin-friendly flows, or process builder, and in Apex triggers, we try and limit it to things that must happen, or are not business process related. Um, for example, when we have, uh, a new account that’s made active, we immediately create an entitlement object. I think that may have come in springs of feature anyway. So we used to do that. So that was in an Apex because it must always happen. There’s no business logic around it.

Josh Birk (31:20):
Got it, got it. Oka, so going back to the beginning, you had your problem statement, you wanted to be able to give a dial tone of Salesforce related information to your Slack users, without them having to be, you know, aware in Salesforce, how, how is it going, and how are your users reacting to it?

Richard Clark (31:36):
I mean, it’s brilliant. One of the things I hadn’t appreciated was the use of the sort of different likes and icons, and I think it’s really, really good seeing people, we know they’ve read it, because people have put a like on it or they put, uh, a thumbs up, or a celebration. And it really is, being able to hold on that and seeing who has liked it and seeing that’s across our whole company, across all regions or demographics, and the times of day people are working is a bit worrying at the moment, laughs) et’s say it, it’s UAM, there’s far too many people liking a win, um, but that has been good. And the fact that they can have a conversation about it, some way say, you know, they can add a personal element to it and say, “Well done,” to individuals who helped that deal.

Josh Birk (32:20):
Got it.

Richard Clark (32:20):
The other thing we learned was, my original version, we were saying, who the opportunity owner was. And that was actually quite, uh, divisive because obviously it wasn’t one person who’d made the deal happen, there’d been, uh, a whole team of people, not just those in Salesforce. So we quickly changed that recognition, that it was a whole company effort to win a customer, not just a sales person that’s got a signature on a DocuSign.

Josh Birk (32:40):
And that’s end of our show now. In the show notes, we will have links to Richard’s original presentation, be sure to go ahead and check that out. Now, before we go, I did ask after Richard’s favorite non-technical hobby, It’s one that’s come, uh, pretty common on the show. You might even call it, turning into a key ingredient?

Richard Clark (32:58):
Those that follow me on Instagram, and I tend not to mix my Twitter, uh, and Instagram community, uh, would know I’m a very keen, and able, I would say baker, with those breads, pies, pastries cakes. So that’s my sort of favorite way. And it’s a, it’s a like programming in a way, you’ve got these ingredients, you’ve got set tools, you follow some instructions, but I’ve got to say I’m probably a better baker than I am a creator at the end of the day. (laughs)

Josh Birk (33:21):
(laughing) I wanna thank Richard for the great conversation and information, and as always, I wanna thank you for listening. Now, if you wanna learn more about this show, head on over to developer.salesforce.com/podcast, where you can hear old episodes, see the show notes, and have the links to your favorite podcast service. Thanks again, everybody. And I’ll talk to you next time. (silence).

Get notified of new episodes with the new Salesforce Developers Slack app.