[00:04:52] Speaker 1: � Ladies and gentlemen, please take your seats. The program is about to begin. � Ladies and gentlemen, please welcome April Underwood, Slack's Chief Product Officer, to the stage.
[00:07:13] Speaker 2: � Good morning.
[00:07:16] Speaker 1: Good morning.
[00:07:17] Speaker 2: Thank you so much for being here. We are so excited to see all of you at a packed house. We're expecting a really great day ahead, and we appreciate you all being here. Many of you probably know this, but this is our first ever developer conference. So thanks for being a part of it. � So who are you? Here in the audience today, we are joined by developers on our platform, customers, as well as partners. And we all have something in common, which is that we're all building together a better way of working for millions of people. And we actually shared recently that that's 8 million daily active users working on Slack. 3 million of those users are paid, and those are across 70,000 of our paid teams. But they actually only represent a fraction of the 500,000 organizations that are choosing to do work on Slack. The opportunity is really massive, and we're so humbled by this adoption and by all of you coming here to join us in building for this future. So our mission here at Slack is to make people's working lives simpler, more pleasant, and more productive. And with our platform and with our community of developers, including many of you, that vision and that mission really becomes a reality. So those of you who have been with us for a little while may remember that we launched the Slack platform in December of 2015. And I cannot tell you how excited we were at that point that we had 150 apps in the app directory. But here we are today, and we have over 1,500. And that's just phenomenal, a 10x growth in just such a short amount of time. And we have 200,000 weekly active developers, 200,000 people building every week on top of the Slack platform for such a wide variety of purposes, from very custom needs within specific organizations all the way to building applications that are in the app directory that can be used by these 8 million daily active users. So in the audience today, two-thirds of you have told us that you are building internal integrations. You're building on top of our platform to build the tools and the capabilities and the notifications that your own team needs that nobody else would really need. They're tailor-fit to exactly your business's needs and your culture. And then one-third of you are building applications that are available in the Slack app directory. And what's even more fascinating is that there's a lot of overlap between those two groups. So many of you are building applications for the 8 million users on top of Slack, and you're launching those in the app directory, but you're finding along the way that there are all sorts of tailored ways that you can use our platform for your own company's needs as well. So I want to talk about a few of those partners that are building here. So one of them is Guru, which is a knowledge management solution. Are the Guru folks here? I know at least some of you are. So they launched as one of our Slack fund partners back in 2016. So they were a new application going after the knowledge management solution space, and they launched on top of the platform when they put their app into the Slack app directory. And since that time, they've seen adoption by just a really impressive customer list. So folks like Spotify and Ikea. These customers discovered and found value in using Guru because they saw that opportunity for it to work well with Slack. And building on Slack has been, you know, really such a vehicle for Guru's growth based on what we've been hearing from the team, and this is exactly what we like to hear. It's so gratifying to us to help bring developers, small teams that are building new solutions to a wide audience of customers through the Slack app directory. Quartz is a popular digital news outlet for people in the new global economy. And they have this fast-paced newsroom, and they use Slack for all sorts of different purposes, from critical newsroom activities to some pretty simple but also very important ways that they run their office. So the Quartz app pushes out a lot of mobile notifications, and, you know, it's really important to them to get them right. So they've taken advantage of Slack to build a bot, the Quartz bot, that pushes a notification to a channel where one more person can put their eyes on it before it goes out. And these are the types of simple workflows that Slack is great for. Simple, quick tasks that benefit by bringing the work to where people already are. Because Slack customers are connected to Slack for over 10 hours a day and actively using it for 2 hours and 20 minutes a day. So it just makes sense that these types of workflows that would otherwise be a big interruption of one's workday can come to Slack, can be resolved easily by the people who have the context and the ability to get the work done. But Quartz has taken it a few steps further. So in the New York City office, at times, people leave their key fobs at their desk. So rather than leaving people stranded outside or having to find ways to track down other employees to open the door for them, they just integrated Slack with an IoT doorbell and let the entire office know when the doorbell was ringing so that they'd have the ability for an entire channel of people to keep their eyes on it. And it would be pretty obvious if somebody was getting left out in the cold. But at times, it's also been very hot in this office. Their air conditioning broke during a hot New York summer. And so they built a simple integration to their thermostat so that employees could, from home, make the decision as to whether to come into the office today or whether to work from home. And they had a little fun while doing it. So indeed, I would not want to work in a 76-degree office. So this seems like a pretty useful and tiny little integration that makes Quartz more efficient. Finally, let's talk about one of our larger partners you probably many of you use, Dropbox. Recently went public. And they have over 500 million users. And what Dropbox has found is that teams which use the Slack app are 40% more active, and they actually are retained at higher rates than teams that don't use Dropbox with Slack. And this is something we consistently hear from even some of the largest partners with whom we work, that when customers use Slack along with those applications, they get more value from both of them. So I know it's a little campy to say, but there really is a lot of win-win in building on top of our platform. And ultimately, our customers, our shared customers, benefit. So we have so much for you today. You're going to hear from Brian Elliott, our relatively new general manager of Platform. He joined us about five months ago, and he's going to be sharing some really exciting new product announcements that we have today. You'll also hear from Brad Armstrong, our vice president of partnerships, about some of our latest partnerships and our Slack fund. And then finally, you'll hear from Bear Douglas, our head of developer relations, and she's going to talk about some developer tools and our community. And beyond that, we have just a great lineup today. The team has worked really hard and is so excited to have you all here. So it's my pleasure to get off the stage and welcome Brian Elliott.
[00:14:52] Speaker 3: Thank you. Not again. Thanks, April. Good morning. I'm Brian Elliott, general manager of Platform here at Slack. I am super excited to be here with you today at SPEC, our first-ever developer conference. I'm going to be sharing with you some of what's on our roadmap, the foundations, the specs, for what we're going to build for years to come to help you create better tools for your teams and your customers. Slack is a collaboration hub. We bring together people, information, and the tools they need to make their working lives simpler, more pleasant, and more productive. The platform itself is the basis on which you all work with us to make that collaboration work, bringing all of the best-in-breed tools that you create together. Enterprise software is changing. User-centric design is allowing people to pick their own favorite tools to use at work. In the words of one of our customers, I've got the Jetsons on my smartphone. Why do I have to use the Flintstones tools at work? Those best-in-breed solutions, though, create gaps. Seems that information falls through that make work harder at times for people. You've all had this experience every day. You get a notification in email. You click the link. The website opens. You authenticate in for the umpteenth time. You find the right tab. You click the link. You find the right spot. You approve the expense report. You click back out. Doing that takes you five to ten minutes. Doing it eight to ten times a day, five days a week, all year long, really adds up. The information also sat in two different systems. Slack's platform is how we actually bring that back together. It's the investment that we've made together in interoperability across our capabilities that really makes people's working lives better, and that's showing on a continuing basis in our growth. As April mentioned, we have over 1,500 apps in our directory and over 200,000 weekly active developers on Slack, but it's not just the products you're creating. It's the fact that they actually drive usage. 94% of paid teams on Slack use apps and integrations, and in fact, 65% of paid teams have built internal integrations, custom workflows and apps for their teams that enable them to get work done internally. Over 15,000 of these internal integrations are launched every week on Slack. That's great growth, but we can do more. So I'm gonna talk to you today about three things that we're working on that will help people get work done more effectively. Number one, how do you close the loop across apps? We've helped you bring work into Slack. How do we make sure that you can bring work back out of Slack as well? Number two, how do you deploy apps and integrations across entire organizations seamlessly? And number three, how do we provide you, our developer community, with the building blocks you need to create rich interactions for users? Let's start with the first one, closing the loop across apps. I am super excited. We have just launched Actions. This is live now, and I'll talk through some of the partnerships that are launching on it. Actions are actually two... You can hear, by the way, there's a small crowd back in the room that's cheering. There are two really big things here going on. One is interoperability, making apps work seamlessly together, bringing work in and out of Slack, and closing the loop across best-of-breed software solutions. The second, equally important, is usability, driving discovery of apps, bringing apps for the first time, your icons and descriptions, directly into the message pane. If you think about what we enabled today, most work is actually bringing work into Slack. Using notifications, message buttons, the Events API, it's allowing people to do work inside of Slack. This is actually my favorite example. This is actually the Concur Expense beta app. I disguised Liza's name. Liza's here today. But this is an expense report that I got. I can click the Approve button, and I'm done. I can click Send Back, or I can click More Info and go off into Concur if I need to do something more complicated. That's great, but how do I close the loop? How do I actually allow me to take action on a message on the content that sits inside of Slack quickly and easily to bring it back into other applications? Let me give you an example. Let's talk through what Asana has built and deployed this morning. Asana provides project management tools for teams. Tara and Rob are working on the Q2 launch project. Tara says, can we review this next week? Rob says, I'll set that up now. Rob clicks on the message, opens the Actions drawer, finds the Create a Task message from Asana. The series here is really easy, right? You've got a set of logos and quick, easy-to-comprehend descriptions for a user to take action on. Clicks on the task, gets a dialog box from Asana where he can assign it to a person, assign a due date to it, associate it with a project, and pull in the content that was already there from Tara. Can we review this next week? Click Create, and you get a success message back in Slack. Equally important, all this content now exists in Asana as well. The task that he created, the content he created, and most importantly, a link back to the specific message in the channel where it was created. I don't know about you, but I have this happen all the time where I kind of forget the context where something happened. You go and look at it a month later. This allows you to maintain that context and information across your applications. So app discovery on every Slack message is a big deal in this. This is the first time that we've actually done this. It's also a way to drive usability across a wide range of users because you don't have to use a slash command to do this. What would be great is if we actually did a demo for you. So let's do a demo. Please join me in welcoming to the stage Pranay Agarwal, the lead developer on Actions. Come on up, Pranay. ♪♪ Hey, Pranay. It's been an exciting morning. It has. The team's been pretty busy.
[00:20:32] Speaker 4: Yep.
[00:20:33] Speaker 3: Pranay's going to... A small amount of panic in Pranay's voice, but I heard the cheers in the back, so I know we're feeling good about it. Pranay's going to pull up a Slack instance here. Think of this as you've got a team that's actually working on the beta development of a product. Let's call it Project Nano. Project Nano's in beta. The team's been testing it for a little while. They're getting ready for the launch. As usually happens, you've got a multidisciplinary team that's working on this in Slack to pull it off, product design, engineering, sales, marketing, and, importantly, customer support. So Jennifer from customer support gets a ticket from a beta customer that says, I'm getting a redirect on the settings page. She shares that in this in channel in Project Nano. Zendesk has a nice little unfurl, so it actually shows the information and content. Nobody has to click it to read it, but they actually get the content and information. So, Pranay, what can we do with this?
[00:21:22] Speaker 4: I'm glad you asked, Brian. As you can see here, Steve, the product manager, knows that there's already a Jira issue for this ticket. Just by mentioning the issue number, he triggers another unfurl from the Jira app, which provides useful context for Jennifer and the supporting team in this channel. What would be even better is if this context showed up in Zendesk itself. Now we get to use our new feature, actions. I can highlight this message and bring up a menu containing all of the actions that you may already be familiar with, like marking the messages in red, creating a reminder, or deleting the message. Right below them, we've added a new section dedicated solely to apps. Your most used actions show up right here, and the rest of them are one click away. You can see relevant actions from all of the apps installed on your team. And of course, you can add your own. In order to keep this launch on track, I want to make sure that the beta customer gets the support that they need. This one is a known issue, so I'm going to use an action provided by Zendesk to add Steve's message, which is displayed above, as a note to the existing ticket. I click on the action, which brings up a dialogue. You can see that the message text is already filled in. I can edit it if needed. Otherwise, I can just enter a ticket number and hit submit. Zendesk immediately posts a reply right here in channel, telling me that the work I need is done. They've also linked to the ticket right here, so now I can click and hop right into Zendesk. Let me show you what this looks like in Zendesk. As you can see, the ticket just updated live and posted the message that I shared right here. So now any customer support agent that comes across it has all of the context that they need.
[00:23:15] Speaker 3: That's awesome. Not only do you actually have the content there, it actually shows who posted it. It shows it came from Slack, and you've got a link back to the actual message in the channel, too. So you can bi-directionally link back and forth. What else can we do to fix this problem here, Pranay?
[00:23:30] Speaker 4: Great question, Brian.
[00:23:33] Speaker 3: But wait, there's more.
[00:23:34] Speaker 4: As an engineer, I know the importance of staying on top of tickets filed by beta customers. So what would be great is to make sure that this Zendesk ticket is linked back to the issue in Jira so that the team is aware that more customers are running into this bug. You probably achieved this today by opening many different browser tabs and copying and pasting bits of content between them. Let me show you how you can do this in just a couple of clicks right from the Slack channel. So let's switch back to the channel. And over here, I can see that Zendesk has posted a new message containing the updated details of this ticket. Now I'm going to use another action, this one provided by the Jira app, to link this message to the existing Jira issue. I bring up the same menu, and this time click Attach to Issue. The app posts a message asking me to select the relevant issue. I can do that from right here. Then it asks me for confirmation. I click on it, and just like that, it tells me that my work is done. Way to go. Awesome. Thank you, Pranay. Thank you, Brian. Thank you.
[00:24:45] Speaker 3: Look, these are simple shortcuts and affordances for users, but this is a big deal. What you've got, and you all do this every day, you've got teams that use different tools. Your customer support team might use Zendesk, your engineering team might use Jira, and what Pranay just did is he integrated Zendesk and Jira with Slack. He did something else, too. He integrated Jira to Zendesk, because he actually took the Zendesk ticket, pulled it into the Jira issue, so those two are linked together as well. As developers, when you use Actions, you're not only integrating into Slack, you're actually making the integrations across the entire ecosystem work. That's pretty awesome. We're doing this with a large number of partners. Bitbucket for repos and pull requests. Alice can actually click on the message content, attach it to a pull request, assign it to a specific repo, and a pull request, and I get a success message back, which is great. There are teams that do this more broadly. Sales and marketing need support as well. Our friends at HubSpot have actually integrated Actions into their CRM, so Russell and Keely are actually working on Tea Time, an account. Russell says, let's work on that QBR for Tea Time next week. Keely says, thumbs up. We're ready to go. She opens up the dialog box, clicks add a task from HubSpot, gets a dialog between the two, can assign not only her name and who it's assigned to, can actually associate this with an account, a contact name, or a deal, clicks create, and gets the success message. This is live. We now have nine partners up and doing this coming up today, a wide range of partners, people doing customer support tools with Zendesk, sales and marketing support with HubSpot, project management with Asana, products from our Atlassian friends, Jira and Bitbucket, TeamLine, Pocket, Todo, and Guru. Again, simple shortcuts that help users use Slack to get action done and close the loop from an interoperability standpoint. We're ready for you to build on this starting this morning. The rollout is currently underway. Please come and join Tomomi and Marie right here at 10.40 a.m. where she'll talk through simple shortcuts, blueprints about exactly how this works. So actions help you close the loop across apps. We also need to help you deploy across organizations. Workspace apps. Workspace apps, the Workspace Token and Permissions API has been in preview for a few months now. And in fact, we've had some developers building on it. Brandon Keepers from GitHub will be up here talking about this later today. The Workspace Token allows teams to build apps and deploy them at the workspace level instead of the user level. The Permissions API allows you to progressively unfurl functionality and add it to your app without making the user reinstall your app. Both of those are great from a developer perspective and importantly from a user and admin perspective because it allows them to have more dependability and greater control over their apps and app usage. At the same time, last year Slack launched Enterprise Grid. This is our tool for large-scale organizations that have dozens and hundreds of workspaces. Slack's seen tremendous growth from an enterprise perspective. Overall, 65% of the Fortune 100 are paid customers of Slack. Bringing this together, the Enterprise Grid product allows different workspaces, business units, divisions, and organizations to live inside a single organization so that you've got single sign-on, administrative controls, and access to all of your teams and content while not forcing everyone into one instance. Workspace apps need to mirror the same capability. We need to allow you to install not only at the workspace level but organization-wide. Here's an example. Control from an admin perspective means that your team, if you're the admin at Comcast or IBM, might use Sentry for error tracking. You're probably going to want to install Sentry on a set of specific instances that it makes sense, IT and engineering. On the other hand, maybe you've actually decided that Google Drive is actually going to be your default file storage. And if so, as an organization admin in Slack, you want to be able to deploy Google Drive everywhere. All workspaces, all channels, all users. That's a big deal if you've got hundreds or even thousands of workspaces, which some of our customers do. It's also important if you happen to be an internal app developer. So if you built the IT Help Desk app, you really want to build it once and have it deployed everywhere, making it available to every employee in your company no matter where they are and where they go. Workspace apps will actually be up here on stage. Bert Feng, who's one of our lead developers, will be here along with Brandon Keepers from GitHub talking about what Bert's building from an org-level deploy perspective and what Brandon has actually been working on in terms of the actual GitHub experience. We're targeting this for general availability in the fall, along with the ability for people to have programmatic tools for converting user token apps to workspace token apps. Actions, close the loop across apps. Workspace apps helps you deploy across organizations. What about rich interactions? Today, we're previewing BlockKit. BlockKit is our new UI foundation. It's a set of tools to help you build richer interactions with customers. It's also providing developers with greater flexibility in terms of how they display those blocks and content, and it's about providing a consistent user experience across things like attachments and dialogues. Today, all apps are forced into a limited set of ways to display rich information. If you've looked at and seen and used all the different apps that are in Slack, many of them end up with the same layout regardless of what functionality they're trying to deploy. When in reality, what you need is a set of components that let you build rich, interactive displays that are easier for people to comprehend, digest, and act on. BlockKit, the version one of which I'll talk through today, is a set of basic and interactive elements that together allow you to control user experience and make for richer experiences inside of Slack. Let's flip through a few of these. The text block, it's basic plain text or Slack markdown. A text collection, this is a horizontal stacking of two text blocks. An image, including a caption. An inline image, a text description with a right aligned thumbnail. A context collection. Think of this as meta information about the content. It's a text and a small image stacked inline where you have control over the order and number of elements that you place. It's that little bit right down there where it says test passed. We're also continuing to support the color bar because the color bar, the color block, actually can do some similar functionality. The divider, this is my personal favorite, it's a divider. Think about it though, this is a simple separator that allows you to display content and information to users. It makes it much more digestible for them and easier for them to comprehend. Interactive collection, this is a group of buttons, selects, and overflow menus that you place together inline in any order that you want. Inline select, which is a text description with a right aligned select element. And two last bits, an inline overflow that nested set of additional options for users and a date picker, another personal favorite and one that I know a number of you have been asking for for a long time. Besides these blocks themselves, the other thing that this provides is flexibility in terms of vertical control. You decide how you want to stack components, how you want to place them on the page, and what order makes the most sense for your app and for your user base. This looks really good. If we're going to release this, we're going to need a builder that goes along with it. And in fact, it would be great if that builder had WYSIWYG capabilities and maybe did some prototyping. In fact, we actually have such a thing. So please join me in welcoming Jamie Mountz, lead front-end developer for the Block Kit Builder, to the stage. ♪♪♪ Thanks, Jamie, for coming up and doing this.
[00:32:51] Speaker 5: Thank you, Brian.
[00:32:53] Speaker 3: Jamie and the team have been working on this for a while. It's pretty cool.
[00:33:00] Speaker 5: All right. I'd love to show you how the Block Kit Builder can help us turn these Canoe app designs into code. Introducing the builder. All the V1 blocks are available along the left-hand side, like the text block, the image block, and Brian's personal favorite, the divider. Clicking them adds them to a central preview area to see how it'll appear in the Slack client. You can also remove the blocks here. On the right hand, you'll see the JSON that you need to describe this UI, automatically generated based on some sample content. You don't even need to leave the builder to understand how to read and write the JSON. You can open information and see the block's name, description, and the key value pairs that the API will expect. There's also a couple Slack designer-approved examples of how to use the blocks. Let's get started making our canoe app. It looks to me like an inline image block here describes the hotel, and a context collection block shows its location. We can select those two blocks from the tray to see how they'll look. Inline image and context collection. And look at that. It even has a very similar copy to what I need. Next, we need a button. I'm going to use the interactive collection block. We will have to customize this block. It has a couple too many buttons. Let's edit it to just have one main call to action. With some improved text. And an action ID that describes the content. This is looking great. Let's do a quick sanity check to see how it'll look on mobile web. Nothing is broken. Awesome. Over here, I have a Slack channel with my designer. I want their feedback and approval on what I've built. I can use the send to Slack button to send it into a channel. All the way down here. There it is. This is a really easy way for me to get quick feedback on my app prototype from my team. From inside my real Slack workspace. This is all looking great. Over here, I have a quick app that I've built using the Node SDK. My magic API needs the user ID and their hotel selection to reserve their room. When a user interacts with my app's button in Slack, my app will receive an action payload with all the information about that action. It's now easier than ever to understand the structure of that payload. We can click on this button and see an example payload that we can examine right here in the builder. I see the user object has the ID. And the action ID is what they clicked. We're all done. I'm just going to copy this JSON and send it to my users using the chat.postMessage API and our new blocks key inside of our attachment array. And just like that, I've built my first attachment using BlockKit. Woohoo.
[00:36:31] Speaker 3: Thanks, Jamie. That was amazing. Jamie and the team are great. They're actually going to be in the studio space after this and all day long talking about what's going on there. V1 blocks are intentional. We're going for simple, basic tools that you can use to build quick contextual work inside of Slack. We will continue to build on top of this for years to come, and I'll get into that in a second. The intent here is to make it easier for people to do work inside of Slack without overloading or overwhelming them. We're also going to continue to take this further. Consistency matters. Besides the attachments array, which will be part of V1, we're going to get into dialogues next, and we'll continue to build on top of it. We want your thoughts and opinions on this. V2 might include things like an image carousel, check boxes, radio buttons, a table, and maybe something like a face pile. You give us user IDs, we pull in the avatars, people can click on them to see the Slack profile of the particular user. The studio demo space will actually have this going for most of the day today. Jamie will be there to talk about the builder along with the rest of the engineering team, product managers, designers, show you more detail of what's in V1, and get your thoughts and opinions on V2 because we want to know what all you want, what your priorities are, and how we can make this better. So actions. Actions closed the loop across apps and also gave all of you greater discoverability and users greater utility inside of applications right on the message pane. Workspace apps is how you'll deploy across entire organizations, giving developers better tools and administrators easier ability to deploy across an entire company. And Block Kit is our next generation foundation for building rich interactive user experiences inside of Slack. Workspace apps and Block Kit are foundations that we will be building on for years to come. This is only part of our roadmap. The rest of it's over in the studio space. There's a lot more to be said and done on this, but we want your feedback and opinion. Please come and talk with our team over the course of the rest of the day today. Because as a collaboration hub, it's you, our partners, our developers, and our customers that are the key part of helping people get work done. And it's that partnership that's most critical. Here to talk more about the state of that partnership is our VP of Partnerships, Brad Armstrong.
[00:38:57] Speaker 1: ♪ Hey, Brad. Thank you, Brian.
[00:39:04] Speaker 6: It's so great to be here today at our first developer conference, and I want to give a special shout-out to all of you who were with us two years ago when we launched the platform.
[00:39:11] Speaker 1: Woo.
[00:39:14] Speaker 6: So I run partnerships here at Slack. We work with everyone from the largest enterprise software providers in the world to best-of-breed SaaS companies to early-stage startups. Our partners also span the entire range of enterprise software categories, from sales tools to customer success to dev tools and analytics. They're all partnering with us because they understand the power of our collaboration hub. Now, at Slack, partnering isn't just something that we do. It's a fundamental part of who we are. Over the last couple years, we've embedded partners into everything we do as a company, from building products to going to market to the tools we choose to get our own jobs done. Partners are critical to all of it. Today, we're going to focus on the early-stage side of our ecosystem. Entrepreneurs and developers, just like many of you, who are building their companies on Slack. When we launched the platform two years ago, we also launched the Slack Fund. Our mission is to foster the best companies building the future of work with Slack as a fundamental paradigm interface. We've been totally blown away by the innovation and momentum we've been seeing from these companies. Today, we're incredibly excited to announce six new Slack Fund investments. Aptly, Clara Labs, LearnMetric, Zylo, Epistema, and PullRequest. What's so notable about these companies is the range of use cases they're pursuing with the platform. From real estate property management to code review as a service to SaaS spend optimization, they're really pushing the limits of the platform and we're incredibly excited to be working with them. So, since we launched the Slack Fund, we've been incredibly busy as both partners and also as investors. We've made 38 investments to date in these great companies. Not only are they building the future of work, they're also building great businesses. These are the next great SaaS companies and that's really borne out in the reception we've seen from the investing community and the amount of capital that's come into these companies. So, across those 38 investments, we've seen $200 million in venture capital into these companies and 11 of our companies have gone on to raise subsequent rounds. They're showing momentum in their businesses and venture capitals are taking note and it's happening because the best VCs in the valley see the same momentum and innovation that we're all seeing right here today. It's happening on this platform. It's happening on Slack. Let's take a closer look at a couple of these companies. So, Loom allows you to record and share quick videos for work. It's a really great way to get the richness of video communication and put it right in Slack where you're already working. Loom has an enviable customer list and they already have 600,000 users. Great momentum there. Troops. Troops is bringing Salesforce automation right into Slack. So, sales is an inherently collaborative process and sales teams are getting a ton of value in seeing their CRM workflows come right into Slack. They have great momentum and enviable customer lists and over 1,000 teams using them already. So, best of luck to Troops. Donut. It's all about building company culture. Whether you're onboarding new employees, whether you're making connections between existing employees within a company, Donut helps you get there because people know that company culture is a major competitive differentiator. Donut has made, as you see here, 500,000 connections between employees within their customers and, I mean, that's a customer list that anybody would be proud of. So, the success we see today with Loom and Troops and Donut is something that's unique in this industry. Companies at this stage of their life cycles bringing in customers of this caliber and seeing this kind of traction. But it's really only a fraction of what's happening within the Slack partner ecosystem overall and you're going to see a lot more about that today. Finally, I want to thank all of you, our partners, our developers, our customers, for making this all possible. It's because of your partnership with us that the collaboration hub is a reality and we thank you very much. So, thank you for being here. With that, I'm going to welcome Bear Douglas on stage, who is our Head of Global Developer Relations, to talk about the global developer community and everything that's happening within that group. Thank you very much.
[00:43:35] Speaker 7: Hello again, everybody. We are so excited that you are here with us today. There are hundreds of you in the room today and hundreds more tuning in on the live stream for this, our first developer conference. And it's not lost on us that those of you who have made the effort to be here in the room today have come to San Francisco to meet us. Our global community is that truly global. With over 200,000 developers developing every single week on Slack's platform, eight out of ten of the top cities by developer population are actually outside the US. And we've seen tremendous growth over the last year in cities in Europe, in Asia, in South America, and in Australia. So, over the last year, the Developer Relations team has gone on the road to meet you where you are. We went on tours in Europe and in Asia, and we wanted to hear about the challenges you're facing and the kinds of apps you're building. One of the things we learned on the road while we were in Europe was that people needed a better way to test their apps, and that led us to releasing our testing tool, Steno. So, we learn so much from you when we come and talk to you in person that we know it's time to go on the road again. So, starting in June, we'll be going on a tour in APAC, visiting seven cities in Asia and in Australia. We'll be coming back to Europe in the fall as well, with dates in November, announcing a little bit closer to that. So, stay tuned over the next coming months. Now, we know that there are developers around the world in places that we can't get to on a single roadshow. We see you online answering questions that people have. We see you giving talks and helping people learn from what you know. And that kind of community support is critical to everyone's success on the platform. So, today, for the first time, we're rolling out a program to help you create Slack platform community meetups in your own hometown with our support. We'll be helping you with content, with guidance, and through our collaboration with meetup.com, free space, potentially, to host your event at a WeWork around the globe. So, if you're interested in hosting one of these in your own hometown, check out the link on meetup.com and fill out our application form. We'd be really excited to work with you. Now, if you're not ready to host your own meetup, but you're still interested in learning more about the Slack platform live and in person, we'll be partnering with Major League Hacking's Global Student Network to provide trainings around the world about how to build on Slack. If you're interested in hosting one of these, you can check it out on mlh.io and register your interest. These will be launching in the fall of 2018, and we couldn't be more excited to kick them off. Now, wherever you are in the world, we're here to help you get the tools that you need to build ambitious apps. So, here's what you might have missed over the last few months in our tooling updates. We have substantial updates to both our first-party SDKs for Node and Python, including TypeScript support in our Node SDK and enhanced support for the Events API inside Python. We've also released updates to Steno, our testing tool, including automatic token redaction so you can create tests and make recordings without worrying that you're leaking any sensitive information. Next up, we're going to be releasing file-based configuration so you can kick Steno off with all of the configuration you need directly from a file. About six months ago, we also released a spec according to the OpenAPI 2.0 spec describing our Web API. Today, for the first time, we are releasing a new Async API spec that describes our Events API. And coming soon, we're going to be releasing a schema for the Web API that conforms to the OpenAPI 3.0 spec. We're really excited to see what you can build on top of those specs, creating even better tools for developers. But we have something brand new for you today to check out as well. We've heard from all of you that you need a better way to build on Slack and test things out. And so today, I'm excited to welcome Colm Doyle to the stage. He's our Developer Relations Lead in EMEA to show you what we've got for you in Slack Developer Tools. Welcome, Colm.
[00:47:37] Speaker 8: ♪ Thanks, Bear. So when I go out and meet with Slack developers, we talk a lot about where Slack is where work happens. But as developers of Slack applications, there's not a lot of workflows that allow you to learn about your application, test it, and inspect how other applications work. So we've built Slack Developer Tools to help you with that. So I've already installed this SDT on my development workspace here. So I'm going to see what I can do by calling sdt help. Okay, so I have a bunch of options here. So I'm going to start with something pretty simple. I'm going to call api.test. So if I just do sdt call api.test, SDT is going to make a call to the Slack API. And you'll see here it's provided the response from the API as well as the original request that went out. But let's do something a bit more complex. Let's post a message into this channel. So if I do slash sdt, call chat.post, and do the call. Okay, so something's gone wrong here. I've used the wrong method name. But SDT has actually captured that for me and has looked at the method name that I gave and tried to define what message I was trying to call in the first place. So I wanted to post the message into the channel, so I'm going to pick chat.postMessage. And what SDT is going to do here is it's going to replay that call and it's going to take along all the original parameters but pass them to the correct method name. So I will just click yes here. Okay, but it's gone wrong again. Clearly I need to read the documentation. Previously what I would have done now is I would have swapped out to a browser window, gone to api.slack.com, and searched through our documentation. But SDT combined with the open API that Bear just mentioned allows me to do this right here in the channel. So if I just do slash SDT docs chat.postMessage. And what SDT is going to do here is it's going to give me all of the parameters that I need to call that API method as well as details of the scopes. So obviously I was missing more than one parameter, so I'm going to try one more time. So slash SDT call chat.postMessage. Text equals hello spec. Great, so that's finally worked. So as you can see here, what SDT has done is it has posted into the message. And as with the other API calls, it's given details of the response as well as the arguments that were passed along. So you can see text hello spec here. Now, that's a pretty simple message. It's not particularly hard to define how I did that. But if I swap over to this other channel here, you'll see there's a message here that uses some more of our more advanced UI components like message menus and buttons. And I'm sure as developers, we've all browsed the web and we've seen UI and UX patterns that we really like and we're curious as to how the developer has built those. And we've always been able to answer that question by just right-clicking on that element in our browser and seeing an inspect element. But up to now, there's never really been a way to do that for a Slack message. So using the actions feature that we've just announced, I can just go over here to the right, click, and we now have an inspect message action right there in the menu. So if we click this, what Slack Developer Tools has done is it's given us all of the JSON required to build that message so we can instantly see how it's done. And this will be updated to support BlockKit as well. Now, this is a lot of JSON to copy and paste. And what if we want to see what it looks like slightly differently? Well, we've got you solved there as well. Right down here at the bottom, there's a button open in Message Builder. When you click this, it brings you over to api.slack.com and prefills the box with all of the elements required to produce that message. So I can just simply go here, make a slight edit, and Message Builder is automatically updating so we can see exactly how this would look in our own application. And that's just some of the features of Slack Developer Tools.
[00:51:30] Speaker 7: Thank you so much, Colm. A round of applause. We're really excited to release Slack Developer Tools to you. It's designed for use inside development workspaces only. So stay tuned in the next couple of days for the release and guidance on how best to use it. So you can get started today with a lot of the things that we've been talking about. You can register your interest for hosting a Slack platform community meetup, for hosting a workshop with an MLH, and you can check out our whole suite of offering at api.slack.com slash tools. And if you're interested in a walkthrough live today, Ankur Oberoi, our tech lead for DevTools, is going to be walking you through end-to-end how to build an app using all of Slack's first-party tools, including SDT. So come check that out this afternoon. We've got a packed agenda for you today. So we've just made it through the opening keynote. We're about to release you out to the morning breakouts for the day. We've separated into two tracks, the plan track and the build track. Build is where we'll get down to brass tacks of actually building things at a code level. That's going to be in this room, and we'll cover everything from how to actually use actions to details of our developer tools and launching your first app on AWS. In the build track, you'll hear more of the concepts around ways people have built custom applications in the wild, how to build workflows with less code and more. So pick both of those from each of those tracks, and we hope to see you in each of them. But that's not all. There's active time for you not just to be listening, but to be doing and meeting with us. In the studio space off to the right, we have space in the morning for you to weigh in on our roadmap, for you to try out BlockKit, consult with us at the Slack office hours, or work to optimize your app for installs and distribution inside your organization. In the afternoon, we'll be switching that over into a mini hackathon station, where you can either build a simple app with an IoT button to help you announce when coffee is ready, or you can meet with our friends at Workado to try building a workflow app that you can deploy today to your own workspace. We're really excited to have you here. Welcome again, and let's begin.
[00:55:20] Speaker 9: applause music plays silence music plays You ♪♪ Then you fast-forward to 20 years ago. I heard one of the most life-changing sounds I'd heard at the time, which was dial-up Internet connecting. And that allows us and represents the capability to network computers and to tap into the collective knowledge of the world to kind of satiate this need to transform and need to think about information at a broader scale. Today, we are integrating best-of-breed technologies to work together and work faster and at better scale with our customers in tools like Slack. So that's just a little bit about the business transformation process that's happened over the last hundred or so years. But let's think about what that means in actual tactical processes. So in this particular instance, I'm going to go through this in a world where I don't have Slack and then I do have Slack as a customer support agent. So in my example here, what's going to happen is that I'm a customer support agent at Slack and I get a message in from a customer in Zendesk. And that customer is ready to upgrade from the free tier of Slack to the paid tier of Slack, which is really exciting for us, right? And me in particular. So I get to help my customer solve a problem, right? They may be experiencing some pain that I need to help them solve. And that's paramount to me. Then beyond that, I'm helping my organization grow by driving revenue. Now, I'm not the person that's actually going to service the customer. A salesperson will. So how do I get this message to that salesperson? And then how does that salesperson take action with the particular customer that I am serving? First and foremost, I need to reach out to the salesperson. So I might email them or call them up, or maybe I run into them in the kitchen or by the water cooler. Now, there's nothing saying that the salesperson is going to be available at the time that I'm reaching out to them. So that's allowing time to elapse in this linear process of me reaching out to the salesperson. When that salesperson eventually does respond, what's going to happen is they're gonna need to gather some information to be able to serve this customer accurately. So they might log into a CRM system, let's say Salesforce, to get the context and history of what's going on with this particular customer. And then once they have that understanding, they have to take action to solve this customer's particular need. So they're gonna be pulling from a number of disparate resources to ultimately get a response to this customer and help them upgrade their tier, so upgrade their product. So what they might be looking at are a knowledge base, number of different decks from similar customers that they have served in the past. And ultimately, what this process is taking is time. Any good salesperson knows that time kills deals. So as opposed to having this process linear, let's look at what it might look like inside of Slack. So the first thing that I wanna talk about with this custom app is that information's not being pushed into one channel, therefore making me the responsible party for that information. It's being pushed into a Slack channel where we have a number of different people who are able to see and take action against that information. So that immediately speeds up our time to serve this customer. So we have Zendesk pushing the signal into Slack, saying, hey, Slack, we're ready to upgrade from the free tier to the paid tier. And then from there, we wanna support our sales rep in gathering information very quickly. So in this custom app that we've built, what we have is Salesforce bringing information into this particular message that's being sent so that that salesperson can get into Salesforce and get up to speed very quickly. Beyond that, what we've done is brought in our knowledge base to really focus that salesperson on the solution that they can deliver in turn to their customer. What this is doing is speeding up my capability to serve a customer and ultimately giving greater context of that customer so everybody in our business understands this customer life cycle. This is digital transformation. And my water is tight. So what I wanna focus on and where I wanna spend most of the time today is on three customers who are building and delivering results on the Slack platform. Those customers are Sidley, Andela, and HubSpot. Now each customer has really kind of looked at Slack as essential to the core of their business communication. And it's really transformed their organization. And beyond that, the flexibility of the Slack platform has allowed them to transform their organization. So first place I wanna start is with Sidley. Sidley is a 550 person creative agency that's located in New York, Los Angeles, Paris, Montreal, and Toronto. And today we're gonna be focusing on their Montreal office. And Sidley's journey, excuse me, Sidley's journey with their customers has kind of centered around Slack. They work with their customers, or they work with customers who are the likes of Samsung, the North Face, and Honda. And their journey with Slack started with some of the common challenges that we think about and that we hear from our customers in terms of communication. Communication's fragmented. They're using a number of different resources to work with one another. From email to telephone to WhatsApp to Skype for business. And the challenge here was as organizations grow and change, information is not transparent and then information leaves. So three years ago, they saw the opportunity to go wall to wall with Slack and centralize communication in one particular place. Now, beyond that, what they saw was the flexibility of a platform that allowed them to grow and change along with the way that their business was changing. In addition, they wanted to integrate to all of the other technologies that they have around their organization. And one of those technologies was an intranet. Now, most of us here have worked with an intranet and we know that it can be essential to having information and storing information, but sometimes it's not the most used resource in an organization. So what they started doing with their intranet before they adopted Slack was using that intranet to book both client activity as well as the social and cultural activity going on in the organization. So Sidley Montreal has a restaurant associated with its office. And this is a restaurant where they take their customers or their clients and really kind of spend a little time building the relationships with those clients. If you do or have worked in advertising, you know how important that client relationship is. And it's in those little moments that might not be a status meeting where you really kind of develop that one-on-one love with that client. So they were using the intranet to book tables at the restaurant. Then beyond that, that intranet was also used to book social and cultural activities, as I had mentioned. Now, what they would do is allow their employees to go on the intranet, book that activity, and that employee was immediately added to two things, first of which was a calendar invite, and second of which was an email for every activity or for every employee added to that activity. Some of the challenges that they were seeing with this were low intranet adoption. Again, intranet's a great place to store information, but not necessarily the most used resource. So that low adoption was a cause for concern for them because they had spent so much time and so many resources building this intranet. Then beyond that, they had unmanageable event communication, right? So you're added to this email, and then you're added to a calendar invite, and then each time a communication occurred and somebody was added, you get a reply all. So think about the reply all nightmare that kind of leaves them feeling a bit like this, right? So what did they do? Max Levasseur, the IT director that's responsible for Slack, saw an opportunity to build on the platform, and what he built were two things, first of which was a bot called Freshly. Now, what Freshly does is take that restaurant and bring it into Slack. So what they're able to do is push through incoming webhooks, a restaurant menu into Slack for what's going on at the bistro that day. Beyond that, you're able to take particular actions, right? So you can book a table. If tables are all booked up, you can get on a waitlist, and then from there, information about your table or the waitlist is pushed into a Slack channel so that you are able to understand what's going on with your table or with the waitlist, right? That's ultimately helping their account people be more buttoned up with their clients because they have real-time understanding of what's happening in this particular restaurant that they're working with, and those buttoned-up steps are really important, again, in kind of engaging the client and making sure that they trust you with their business. Beyond that, they eliminated the reply-all nightmare by adding everybody to a Slack channel. So every time an event goes up and somebody registers for that event, a Slack channel's immediately spun up, and then as people continue to register for that event, what they're able to do is get into this channel, work together, coordinate maybe transportation to that event or just generate excitement about everything that's going on and then go to the event, and then once that event is over, two weeks later, that channel's immediately archived. So let's think about results here. Sidley is seeing greater engagement and attendance both at the restaurant as well as the particular events that they are pushing out for their employees to build the social and cultural life of that organization. Beyond that, if we're thinking about the investment in other technologies and how Slack can support your investment in other technologies, we, or Sidley, excuse me, was seeing a 1,300% increase in intranet usage, right? So Slack, being the glue that holds communication and applications as well as processes together, really drives results, not just for Slack and not just for the communication at your organization, but for the adjacent technologies that you might be using to ultimately serve your internal, or in Sidley's case, external customers. The second organization I want to highlight and talk about, which is really cool, is Andela. Andela was founded in 2014 with the mission of connecting the US and African tech sectors. Now, what Andela does is find the top technical talent in Africa and connect them to organizations globally so that they can help those organizations build better products. Off cuff, I've heard that it's harder to get into Andela than it is Harvard or Yale to tell you about the type and caliber of talent that Andela attracts. Now, Andela is 600, let me make sure I get that right because I think somebody from Andela's in the audience, 600, there we go, 600 plus people dispersed across six or more time zones at a time. And then beyond that, they have 50 to 100 single channel guests representing their partner organizations working in Slack alongside of them. So if you think about the global scale of this organization, what they really need is a tool to support them in making sure the communication is fast, simple, and transparent. Now, outside of Slack, before we even get to Slack, Andela built an app called Pulse. And Pulse is really about capturing feedback about partner check-ins. So, for example, partners are people who hire Andela developers and what they wanted to do was centralize information on those partner check-ins so that people could understand how the individual developers were performing as well as how their partners are feeling about the engagement with Andela as a whole. They captured qualitative and quantitative data in this particular application. And what this allows them to do is segregate communication by channel for each partner they work with and then make sure that they are driving visibility into the partner engagements and how those partner engagements are progressing. Now, they saw an opportunity to build in Slack. One of the challenges that they were looking to solve for was to ensure transparency across the entire organization on feedback that they're getting from their partners. Even for those people who did not have access to the Pulse application. So, what they did through incoming webhooks, the actual chat write scopes and the app token is build an integration from Pulse to Slack so that they could push information down from Pulse every time a partner check-in is completed into Slack so that people across the organization, even if they did not have access to the Pulse application, had visibility into what was going on in partner check-ins. Beyond that, the designers there made a really important design decision as they did not want their users having to digest information in different ways. So, what they did is ensure that information was as consistent as possible between the two applications so that the burden of understanding that information was not placed on the end user so that the end user could continue to understand what was going on with each partner check-in in accordance to the way that he or she wanted to see that. So, if you can see the consistency across the actual applications, that is very, very important to them. And how they did that was that they built a custom data parser that allowed them to remove the human element of formatting in pushing that information into Slack so that they could deliver that information again to the end user. Let's think about results that Andela saw. The core goal of this application was to drive greater transparency, and it did just that. It allowed people across the entire organization to start understanding faster, in real time, what was going on with each particular partner check-in. And then beyond that, the unexpected result was greater proactive customer service. So, as people were engaging with partners and Andela employees began to see red flags come up that may indicate a particular issue, they were able to be proactive about resolving the issue instead of being reactive in terms of solving the problem, thus having an angry customer on the other side. That kind of proactivity really kind of brings two organizations together and endears the relationship to each organization so that they can continue to work together for years in the future. Now, the last organization I want to talk about likely needs no introduction, but just in case, HubSpot is an organization that creates sales and marketing software. They were founded in 2006 right outside of Boston in Cambridge, Massachusetts, and they have over 40,000 customers and partners in over 90 countries, including the likes of Shopify and Slack. And what HubSpot was trying to solve for were supporting their customer agents, or excuse me, customer support agents in a better way as they were managing all of the channels that customer support requests came into. Twitter was a really key channel for them, and I'm sure you all can empathize that Twitter has global scale and can move at the speed of light. So, it was really hard for this particular group of customer support agents to manage their Twitter accounts. Now, Ben Becker, the developer who built this app, realized that Slack is the place that centralizes information and communication for HubSpot, which is what led him to develop against Slack to help solve for this challenge. So, what did they build? What they built was a custom integration between Slack and Twitter, and just to make sure that we're clear, this is a custom integration that is not the standard Slack to Twitter integration that allows Slack to pull down information from Twitter and bring it into a channel where their customer support agents live, and they ultimately are able to support their customers through responding to them. Now, as this information is being pulled down from Twitter, before it's pushed into the Slack channel, it's outfitted with a few things, first of which are two buttons that allow them to take action. There's a claim button to say and ensure that somebody is working on this particular tweet. Once somebody claims the tweet, that says to the rest of the group that, hey, we're working on this, you don't need to necessarily pay attention to it. There's also the delete button that allows them to discard the tweet. Let's say it's something that doesn't necessarily need a response or maybe a praise tweet, they can easily discard it to keep that channel clean. Now, in addition to that, what Ben did in the JSON payload is outfit each tweet with a timer that meets their SLA. So, customer support agents, as we all know, have SLAs that they are going to need to be able to meet. So, he's able to then push reminders into the channel if that customer support team is in danger of missing that SLA. And then, once that tweet is claimed, he can drop, again, that SLA timer so that you're not pushing a whole bunch of erroneous reminders into that channel, speaking to the flexibility of the Slack platform. Of course, once somebody has responded, you're able to resolve the tweet and move things forward at a very rapid clip. Now, I'm not necessarily gonna read the entire quote here, but the important thing is this. The fact is, they were able to manually, or excuse me, automate hours of manual searching out of their day so that they can then resolve particular issues and then turn their attention to other needs that they could be proactive about. Think about that time, right? If you're able to automate four hours out of your day, or four hours out of your team's collective day, what does that mean to you? What does that mean to your organization? And what does that mean to the speed and scale at which you can do business? Developing in Slack is going to support you in bringing together systems and processes that haven't been able to be brought together before. What it's really focused on is helping you serve your customers with speed and at scale, and then ultimately leading to your ability to surprise and delight those customers down the line because of the flexibility of the platform. So as we wrap up, I'll leave you with this. Be the hero today. Go out and build something awesome, and then come back and tell me about it so I can talk about you next year, in Slack that's going to make the lives of the people at your organization simpler, more pleasant, and more productive.
[01:46:38] Speaker 1: Thank you. Thank you. Thank you very much. Thank you. Ladies and gentlemen, please take your seats. The program is about to begin. Hi.
[01:56:46] Speaker 10: My name is Bertrand Phan and I'm a senior staff engineer on the Slack platform team. I spent a lot of time thinking about how developers can build apps for Slack, how customers use those apps, and how admins install and manage those apps. This is what we'll be covering today. I'll be providing context on why we're shifting to Workspace apps, what we've observed with our enterprise product, and how we can make the two work better together. First I'd like to talk to you about why we should consider building a Workspace app. As April mentioned, Slack launched its platform in December of 2015 with deep integrations into a number of products, including developer tools like PagerDuty and GitHub. Since then, we've seen customers can leverage Slack to do quick and contextual tasks like responding to notifications for an incident or managing internal support queues. We believe that Slack apps can play a significant role in the future of work, enabling our customers to deploy mission-critical tools to their teams. But there are some fundamental issues with how they work. Today Slack apps are tied to user accounts. When a user leaves the company, the app and its functionality are removed. We've seen this again and again in support tickets, where apps are uninstalled when the person that originally set it up leaves, and it severely impacts our customers' ability to do work. On one hand, this is a validation of the importance of the apps that you're building. Our customers rely on these apps to do their jobs, but it's an annoyance that our customers shouldn't have to think about or deal with. That's why with Workspace apps, apps are not tied to the installing user. When a user's account is deactivated, the app continues to work, which we believe makes them easier to install, manage, and develop. We've also introduced this concept of progressive permissions. The app is installed once, but it can be reconfigured as the customer integrates it more and more into their workflows. As your customers are using your app, you'll sometimes find that your app needs more permissions than it currently has. Rather than having the user reinstall the app, it could request additional permissions from them via the permissions API, and they'll be more likely to grant those permissions because it's within the context of what they're trying to do. As the usage of your app begins to grow within a workspace, you'll need a mechanism for accessing data on behalf of different users or linking their accounts to another service, and we think the permissions API handles those use cases well. Another advantage of Workspace apps is that they're treated as first-class objects within Slack's UI. When a user installs an app on a workspace, they're not just installing it for themselves, but they're installing it for all the members of the workspace to use. So after install, we're displaying them here on the sidebar for other users to discover. With one click, they can launch them and immediately start interacting with them. We're also changing the access model. Before an app would request access to a user's data, and it would have to get multiple users to install the app to get a bigger picture of the workspace, or it would have to ask for all-encompassing permissions that an admin is unlikely to approve. Workspace apps change this model so that the access an app has is restricted by conversations like channels or DMs. A user can invite the app to one of these channels, and the app will acquire the permissions for that channel. For example, you could invite the GitHub app to one of your development channels, and it'll gain the ability to post notifications into that channel. When we initially designed workspace apps, we were focused on improving apps on single workspaces. But our Enterprise Grid product, which our largest customers use, allows for the creation of multiple workspaces within a single organization. In a really large organization, having all the members and channels on one workspace can be overwhelming, and in some cases, unusable. Enterprise Grid allows admins to configure Slack along the logical groups and boundaries of your company, while using shared channels to join them together where it makes sense. In our current model, we've been installing apps onto each workspace individually, regardless of whether or not those workspaces are part of the same organization. Over the last year, we've met with a lot of Enterprise Grid customers who told us that they want to be able to deploy software to multiple workspaces at once. These customers don't want to have to ask their employees to manage Slack apps on each workspace. They want us to help them ensure that their users can find the business-critical tools they need easily. So we've taken this opportunity, while workspace apps are still in preview, to change the way that apps are installed on Enterprise Grid. Now apps can be installed across the entire organization. Let's talk about what the details of this change means. When an admin installs an app on Enterprise Grid, we'll ask them which workspaces they would like to give it access to. If they select all workspaces, we will install it on the organization and grant it access to all the workspaces inside of the organization. The great thing about this option is that your app will be available to any workspaces that are also created in the future without requiring reinstallation. They can also select specific workspaces while they get a feel for how the app works, and then at a later point, they can add additional workspaces or all the remaining workspaces. We believe that this creates a better Enterprise Grid experience for everybody. For admins, they could deploy an app to thousands of workspaces in an organization. This makes a lot of sense if there are specific tools that your company has decided to use. With a single installation, they could deploy that tool across all of their Slack grid instance. For third-party developers, we think you'll see increased adoption of your apps. A single organization can be the equivalent of hundreds or thousands of individual Slack workspaces in terms of usage. We think the experience of developing for Enterprise Grid becomes much simpler under this strategy, and it also gives you access to larger customers with larger budgets and needs. With workspace apps, we had reduced the number of API tokens that your app had to manage to a single workspace token, so you no longer have to decide whether or not to use the bot token or choose between different user tokens. We've taken this a step further, and all workspaces within the same grid instance will use the same token. The difference is that when calling our web API, we ask that you include a special header called x-slack-team with the team ID of the workspace that you're targeting, like this. And now I'd like to show you a demo of what this installation process is like and what the impact would be on the workspaces. So here we have an Enterprise Grid instance with three different workspaces on it, engineering, customer experience, and marketing. We also have a help desk app that you could request support from IT with. So if I click add to Slack, we'll go through the normal installation flow. Up here on the right, I have the team picker. I'll select the organization that I would like to install it onto. And now the difference is that when you hit continue, there will be an option where you could say, I'd like to install this app on all the public channels across all workspaces on the grid instance. And when you do that, going back to one of our workspaces, we can go into engineering, for example, and I can go into IT. And I could post a message that says, like, I need a software license for Sublime Text. And using our new app actions feature, I could turn this into a help desk support ticket by clicking request support, filling out this form of different parameters about the support ticket. And then when I hit submit, it will return a link to my new request ticket, which we can go to here. And you can see that it works end to end. Similarly, if we go to the marketing workspace within the same organization, I can go into AV issues and say there's an issue with the projector. And the app action is also available. So simply by installing it on the organization, it's now available across all of these different workspaces. And that's the experience that we're trying to achieve. If you're interested in learning more about workspace apps, you can try installing one. There are currently workspace apps available for Asana, GitHub, Sentry, and Zendesk. They're all available in the app directory now. You can also follow us on Twitter at Slack API, where we will make announcements about our upcoming release. And now I'd like to introduce Brandon Keepers, an engineer at GitHub, to talk about the new GitHub for Slack workspace app.
[02:05:16] Speaker 11: Thanks, Burt. Hey, everybody. How's it going? I'm really excited to be here to talk to you about our experience using workspace tokens, building the new GitHub app. So my name is Brandon Keepers. I've played a few different roles at GitHub over the years as former director of open source. Now I'm back in engineering trying to work on making it easier for you to bring your favorite tools to GitHub. My teammate on this project, though, who deserves just as much or more of the credit is Wilhelm Klopp. But unfortunately, he couldn't be here today. Hope you're watching online, Wil. Good to see you. So back in February, we launched a new version of the GitHub app. It was replacing the legacy GitHub notifications app that Slack had built years ago. And we wanted to start fresh and build on a platform that allowed us to evolve the app as both Slack and GitHub's platforms evolved. And this was something that we were really excited about. I mean, as developers and as an engineer at GitHub, we use Slack all day, every day. Our team's workflow is built around it. We use chat ops to deploy. So Slack's a crucial part of our workflow. And we were wanting to think kind of fresh about what it would look like to integrate these two tools. The other thing that we were excited about is we see GitHub and Slack as very similar platforms just in the way that we approach the problems that we're trying to solve. Slack is where work happens. But instead of trying to solve every problem you have at work, Slack makes it really easy for you to bring other tools and bring the workflows that you want into the Slack experience. And at GitHub, same thing. GitHub's where software development happens. And instead of trying to offer every single software development tool that you might need into a single suite, we're trying to help it make it easier for you to bring the software tools that you use and love to GitHub. And I mean, there's so many developers like us that use both of these tools together. So we wanted to try and start fresh here. When we started out, we gave ourselves a few constraints. We wanted to build this entirely on open platforms and public APIs for many reasons. But one of them, we thought that this was a really important way to build on a foundation that would allow us to scale for the future as these two apps grew and evolved. Kind of related to that, we thought that that would enable us to start to showcase the potential of integrating these two platforms as they added new features. And kind of the result of that, then, was we decided that we wanted to use GitHub apps, which was the new way of integrating with GitHub that was launched last year, and also Slack Workspace apps. So today I want to give you a little bit of an overview of the app that we built and jump into some initial code samples that show you just the authentication flow for Workspace apps. So you can kind of get a taste of that. I'll talk about some of the benefits and challenges that we ran into and give you a little bit of a preview of what's next. So the app that we built is pretty straightforward. We were intending to maintain backward compatibility with the previous app so that we could get everybody upgraded to it, and then we could start rolling out new features. So you can stay up to date with the repositories that your team is working in, so you subscribe in Slack and you'll see that activity start to come in to your channel. We'll roll up the activity, so as a pull request is opened and the tests start running and the tests pass and a review is approved, you kind of see all of that happening right in your channel. And then we also did link unfurls. I think when we started this project, there was about 300,000 GitHub links a day shared in Slack. And all of those are conversations about code. And so we thought it was really important to try and give more context to those conversations so that you don't have to jump back and forth between Slack and GitHub as you're trying to debug an issue in production or think about how you want to implement this next feature. So we added the ability to do link previews. So I want to now dive into some of the code that we wrote and give you just a sneak peek at the workflow for authenticating as a Workspace app. The secret is it's actually really easy, and it's the same as if you built an app using bot tokens or user tokens. The process is effectively the same. So to install the GitHub app, you go to either our marketing landing page or the app in the app store, click the add to Slack button, and that takes you to our first bit of code. Our app is written in JavaScript, runs in Node.js, so all of my code samples will be for that. It's a little bit simplified from the actual code, but all of it's open source, as I mentioned, or I don't know if I mentioned that. I'll mention it again. All of it's open source, so you can go check it out. But here this is just a simple action that that button links to. We declare the initial scopes that we want, do some stuff that's required for OAuth, and then we redirect the user off to Slack. They see this page that Bert was just showing where you can select your team, and it gives you a preview of the permissions that we're asking for. You can then select which channels you want this app originally in, and once you hit the green button that's off the bottom of the screen here, it takes you back to our app. So this is the code that we wrote, and we basically have a handler that looks something like this. We have a bunch of error conditions that we'll handle. We verify the state, which is a kind of required step in OAuth, and then we exchange this temporary token that Slack is sending us for the workspace access token, and redirect back to Slack. I'm going to skip over the verify state. So here's the interesting part. For our app, so we're using the Slack SDK that's written in Node. We call the OAuth.access method, and it returns an access token. So this is our workspace access token, and the only thing that we need to make API requests in the future. So we save that off, along with some other information about the workspace. And then we redirect the user back to Slack, and this is actually kind of not that big a deal, but something that ended up being a pretty important aspect for us. This app redirect feature is really nice. You can send users directly back to the channel that they came from, directly back to an interaction with your app, and what this allowed us to do is there's actually no user interface for the app that we built. You're always either in Slack or GitHub. You do go through some end points that we wrote, but those transparently redirect you, which was really nice. So then you end up back in Slack interacting with the app. From here on out, any time we need to make API requests, we just look up the workspace by team ID, and from that, we have that access token that we can then use to post messages, unfurl links, anything that our app does. So that's it. It's pretty simple. It's actually the same workflow as if you were writing user OAuth or using bot tokens. The next interesting thing that came from us, so this is only authenticating workspaces, so now we have your workspace installed in the app, but everything that you do in the app, we want to authenticate you as a GitHub user. So for example, if you go to subscribe to a repository, you're actually going to see a message like this, and there's probably a few different ways we could have implemented this. I'll talk briefly about the method that we chose, but this allowed us basically to just kick you off to GitHub. You do a quick OAuth flow, and then you come right back to Slack, and it actually resumes the command that you ran. So again, to show a little bit of code for this, so assuming you're not authenticated, this code is what's run to kick off that process, and so the first thing we do is we save the command that you were trying to run, and then the nice thing is that command has all of the information about who you are, it has your Slack user ID, the channel that you were in, so that we can get you back there later, and then we give you a link to our app, which looks something like this. This kicks off the GitHub OAuth workflow. I'm going to skip through some of these a little bit fast, so I hope you're not trying to copy down code. It's all open source. You can check it out later. This then takes you to the GitHub side, where we actually verify your GitHub identity there, and then you come back, and this is where we actually connect your Slack identity to your GitHub identity, so it's a pretty neat, simple workflow, and then we can resume the command that you were trying to run, so this was kind of a, I know it's probably not rocket science or groundbreaking to anyone, but it's a little bit of a challenge for us to get out of the mindset of thinking, connecting user identity to user identity, but you're connecting work space to work space, and I'll talk a little bit more about that here in a second. So the benefits that we saw kind of break down into two categories. For our users, this has been a really good experience. I mean, the installation process is pretty smooth. The progressive permissions is really nice. We can only ask for the minimal permissions that we need to get the app running, and then as we start shipping new features, we can ask for those as a user interacts with those features, and then being able to invite the app to specific channels has been really great, and then specifically for us as implementers, I mean, we had no problems building this app. I was joking with the Slack team that we were talking with a lot that we expected to run into more technical issues, and it just worked. It was really nice, so no complaints there. The single token to persist and use is really nice. You don't have to track a whole bunch of data and figure out which token do I use in the context of this request, and being able to keep everybody in Slack or in GitHub has been really good, actually, for the users, because they aren't presented with an interface that's unfamiliar to them, and then briefly the challenges, like I said, none of this was overall this was really easy. None of our challenges were technical. I mean, it was more adjusting our mindset and how you build these integrations when you're not just connecting user to user but connecting organization to organization or workspace to workspace. So the first one was just simplifying setup. We wanted to get the app installed and start using it as quickly as possible, but you're not just authenticating a user, but you're giving access to all of your workspaces or giving access to your workspace on behalf of other users, so there's obviously a couple steps to go through there that we've already talked about, and then since our app is both a Slack app called GitHub and a GitHub app called Slack, we now have twice as many workflows that we have to send users through, so we see the same thing on the other side where you've got, you know, install the GitHub app, authorize which organization and repositories it should have access to, identify the user, and then eventually we get them back into Slack where we want them, so that was our first challenge. The Slack team did a good job actually at pushing us to simplify this because initially we had some not ideal workflows where a user might have to run a command multiple times to get it to actually work after they've connected everything, but now it's pretty smooth. The second thing that was a big challenge for us is this identity and access problem. We're used to connecting user to user, but we don't know, at least for me, I hadn't thought about how do you connect workspaces and manage identity and access? So in our example, so you have an organization and a workspace where now I'm trying to connect those two and map users and also map the access that each of those users have when you're in channels and repositories. What makes this even more interesting is that the GitHub user model allows you to have the same user across multiple organizations, so this is where it got complicated for us, so if GitHub user 2 shares a link from repository B in what's supposed to be channel A, there's a mix-up on the slides there, what happens? If that link is private, you don't want that to be unfurled, even though GitHub user 2 has access to it. If that link is public, we actually do want it to be unfurled, like if I'm sharing a link to an open source project or a bug in this channel. So these are some of the issues that we've wrestled with, and we still haven't found a great solution to it, but it actually starts to get even more complicated, because now I can have another workspace where that same user is also in that workspace, and so now I have, like, compounding permissions issues. What we ended up, I'm going to skip through some of this, what I think we've settled on, and I'm feeling pretty confident in, is instead of trying to map identity and access across users and organizations, just connecting the work product, so connect repository to channel, and from there, delegate access. So these are kind of our takeaways. We haven't had a chance to fully implement them, so it's something that we're still kind of wrestling with, but I'll be curious to hear other people that have this experience, what solutions you come up with. All right. I want to chat real quick about what's next. We last week started rolling out a few new improvements to the app, so now you can start to take action from within Slack. We initially did slash commands. Hopefully we'll get the action stuff that was shipped today implemented very, very soon, because that's a feature we've been dying for, so we're really excited about that. We also shipped this experimental API, and this is something that we're not really sure where this is going to go, but the idea being, so at least at GitHub, we have a lot of workflows built around repositories and Slack, so we use chat ops to queue ourselves for deploy, and then once production is free, I can go and deploy myself, and so we've built a ton of custom apps and tooling trying to integrate all of these things, and so our question is, what happens if we live in a world where we can expect that GitHub and Slack are connected to each other and know about each other, and I can start to do things that I couldn't do before, at least without having to build a custom app, so in this case, I'm making a curl request to our custom API, and for those that have used the GitHub API, notice it looks very similar, so it's Slack.github.com slash repos organization repo. The token there is any valid GitHub token, so that can be a personal access token, it can be a GitHub app token, it can be an OAuth token, and as long as that has access to that repository, you now have access to post into Slack anywhere that there's subscriptions for that repository, so this is something we're kind of playing around with, we'd love to see what other people build with it and see where that goes, and then next we're starting to look at bidirectional interaction, so most of our focus so far has been on improving the Slack experience, so making sure that you have context for the conversations that are happening there. We want to start thinking about how we bring that back. For our team, at least, a lot of times we'll discuss something in Slack, make a decision, and then at some point that decision gets lost, you know, maybe we're a very distributed and asynchronous team, so maybe someone wasn't around when that decision was made and didn't catch it in the scroll back, or for whatever reason, so we're starting to think about how can we start cross-linking that, and again, some of the features that were shipped today will be really helpful for that. And then just lastly to wrap this all up, it's all open source, it was kind of one of the things we want to do when we set out to build this, so you can come help us improve it. If you have ideas about what would be a better GitHub and Slack integration, check that out. And it's actually built on Probot, which is another project we've been working on, a framework for making it easier to build GitHub integrations, and we've actually been working on adding Slack support to that as well, so that you can have kind of a unified framework for building integrations with both platforms, so, yes, just to wrap up, I mean, the Slack team has been awesome to work with, we're huge fans of the Slack platform, and so, yeah, I hope you all use Workspace apps, I'm excited to see what you build, so thank you. I think we have a few minutes, so I want to invite Bert back up on the stage, and if anyone has questions for either of us, we have time to take those now. We have mic runners here, so they'll, yeah, get your hand up, and they'll come find you.
[02:22:03] Speaker 12: So, you've made it easy to deploy to, say, all channels that were public, why not all channels? In my situation, we're going to have lots of people creating direct channels, but they'd want to have the app in there as well.
[02:22:18] Speaker 10: We've found that private channels and direct messages are, people consider them to be privileged conversations, and with this model, we want people to really invite the app into those channels so that people can feel secure knowing that the app just doesn't live everywhere, but I think at a later point, we may introduce apps that, for example, have more far-reaching access across your Slack instance, but for this initial phase, we want to release it just to all public channels, and then you add progressive permissions onto that.
[02:22:53] Speaker 12: That sounds reasonable for a general approach, but, like, in our particular case, it would be natural to just let it be there. Thanks.
[02:23:02] Speaker 11: One thing we found really nice is you can just, like, slash invite the app name, so, like, we've seen a lot of people doing that with the GitHub app, where they'll just quickly invite it to the channel if it's not there.
[02:23:15] Speaker 1: Sure.
[02:23:20] Speaker 13: Yeah. Hi, there. Maybe, can you talk a little bit about the migration from existing apps, user token apps, both tokens, and how do we go to app tokens?
[02:23:32] Speaker 10: Yeah, so the question is, how do we take the existing user token apps and migrate them to workspace apps, and this is something that we're working on, and we'll announce a strategy for it in the ‑‑ I don't have a good answer for you right now, but we're going to release a strategy very soon.
[02:23:54] Speaker 14: So in the meantime, what's the best practice?
[02:23:57] Speaker 10: I would suggest that if you're developing an app now, we have a developer preview, and you could try building a workspace app now, and I think if you follow us on Twitter, we'll announce a general availability fairly soon, and so by the time your app is ready for production, the timing should be good that you could release it to this platform. Especially if you're building an internal integration, you could also just build it there and you won't have the block on the Slack app directory, for example.
[02:24:34] Speaker 11: Got one in the back corner there.
[02:24:37] Speaker 15: So you mentioned earlier that one of the challenges that you had was around permissions for private content posted to public channels. Can you talk a little bit about how you started to think through that challenge and how you solved that problem?
[02:24:52] Speaker 11: Yeah, sure. So we actually just last week shipped the ability to do link previews for private content in channels, and the approach we've taken so far is when a user posts a private link, we just ask them, do you want to show a preview for this in this channel? There's a couple options. We have always for this repository, always for this channel. I can't actually remember all the options, but right now we're putting it in the hands of the user that shared the link, which I think is working pretty well. I would love to see us eliminate some of that and just say if there's already been an established connection between channel and repository or even channel and organization, we don't even need to ask. We can assume that if you've invited somebody into that Slack workspace, we're now assuming that you intended for them to see whatever work products are related to that. It's an ongoing challenge, but I feel we're pretty comfortable with the solution we have right now.
[02:25:55] Speaker 1: All right. All right. Thank you. Yeah, thanks, everyone. All right. All right. Thank you. Yeah, thanks, everyone. All right. All right. Thank you. Yeah, thanks, everyone. All right. All right. All right. Thank you. Yeah, thanks, everyone.
[02:26:01] Speaker 10: All right. All right. Thank you. Yeah, thanks, everyone.
[02:26:10] Speaker 1: All right. All right. Thank you. Yeah, thanks, everyone. All right. All right. Thank you. ♪♪ Ladies and gentlemen, please take your seats. The program is about to begin.
[03:56:48] Speaker 16: ♪♪ Hello.
[03:56:49] Speaker 17: Hey, everyone. How's it going? Good. Great. So hope spec is going well so far. We're going to talk to you today about building secure apps, making the most of the Slack platform, and how to keep security in mind as you are building your applications and integrations. So, I'm Max Feldman. I work on the product security team at Slack. I run our bug bounty program. I work on internal feature reviews. I work on some of our app directory reviews. So, if you have an app on our app directory, it may have been me reviewing it. And this is my colleague, Kelly.
[03:57:30] Speaker 16: Hello. I'm Kelly. I'm also with Slack's product security team. I work very closely with the app directory team to kind of ensure that our app directory is a safe place for people to continue that trust that they have for the Slack platform. So, today we're going to talk about why app security matters, which I hope that you all know. As you're here, you came. Next, how we review apps, security best practices, and Max is going to talk about some of our new features with platform security that we're really excited to introduce today. And then, finally, we'll open it up to Q&A. So, first, why app security matters? So, apps in our enterprise environments are handling highly sensitive information. They're handling our trade secrets, our unannounced deals, our features in development, and occasionally, our live security bugs. Our customers are trusting us both, Slack and you, the developers, to keep their data secure. And finally, a breach can be disastrous. Nobody wants to be the next headline talking about apps as a security surface, as an attack surface. So, yeah, we want everyone's imaginations to run wild and to build cool apps, but we really want to help you do it securely. So, how we review apps. So, we perform automated web app scanning and network scanning just as a sanity check for the security posture of your infrastructure. We'll perform manual verification of your proper scopes. So, what we're trying to do here is ensure least privilege design where we have some really broad scopes and you have a lot of power and flexibility to choose what kinds of data your application is going to access, and we ask that you not overscope your apps and not request more data than you actually need access to to build your cool integration. So, if your app is overscoped, we will contact you and ask you to correct that. We'll also perform some manual testing of functionality for possible vulnerabilities and misuse of some legitimate functionality of your application. And finally, we'll perform a manual architecture review of your app. So, what we're looking for, first and foremost, is this a malicious app? Is someone trying to introduce malware into your Slack platform? Second, we look for the OWASP top ten, so the most common security vulnerabilities that apps introduce, that app developers introduce. Third, we're looking for overly permissioned apps. Again, ensuring that principle of least privilege. It's important to consider these issues even if you aren't building a public app because you want to be mindful of opening up attack surfaces for your channel guests and insider threats. So, we work really hard within Slack and within Slack Security to make our platform really secure, but we just don't want to open up attack surfaces with our integrations. So, what do we find? Most common vulnerabilities, cross-site scripting. How many of you know what this is or are familiar with it? Cool. Great. So, you know, as you know, with a communications tool, you are relying so heavily on user supply and input, and you want to make sure that you are properly handling that and output encoding. Second, TLS configuration. This is a really easy one, an easy win that you can check off just by making sure that you're, you know, up to date with the most proper protocols and cipher suites. Information disclosure is a big one that we see as well. Most commonly, this is things like leaking tokens via URLs. So, again, I have another slide to talk about how to properly handle tokens because that is so important. Authentication issues. Again, think about how you're handling those cookies. And just some honorable mentions, security patches and keeping up to date on those libraries and software. And debug mode and prod. Again, this is an easy win. Just make sure that you turn off debug mode so that people can't flip that and leak some of your secrets. Security best practices. So, token storage best practices. These are your most sensitive asset to protect. First and foremost, do not pass tokens via the URL. Let me say that again. Do not pass tokens via the URL. Pass them safely in headers and bodies of post requests. Do not hard code your tokens. Don't publish them to your code repos, even if they're private. This is a huge attack surface. We have a token nuker and we're finding and revoking tokens from GitHub every day. And Max will talk a little bit more about that later. You want to store your tokens safely in something like Vault or pass them as environmental variables. General security best practices. Have an SDL. Have a secure development lifecycle process. We recently published a blog about this, about what we use here, and we open sourced a tool that we use at Slack, Go SDL. You want to make sure that you are designing securely from beginning to end and make sure you revisit your code whenever you're making changes. Just sanity check yourself to make sure that you're not introducing new vulnerabilities. Second, do not trust user input. This is the easiest and most viable attack surface for hackers. Again, cross-site scripting is something that we see the most because our application is user supplied input. Make sure you're outputting and coding properly. Consider where dynamic data is influencing control of your application and be aware for opportunities for code execution. Finally, get into that attacker mindset and think about how an attacker might abuse your system using legitimate functionality that you didn't even consider a vulnerability. Once you're in that attacker mindset, stop attackers before they have the chance. I'm going to pass it over to Max now to talk about some of those new platform security features.
[04:03:37] Speaker 17: Thank you. How many people here have written an app for Slack? Nice. How many have one on the app directory? Okay, cool. This will be relevant to everyone for both internal and external integrators. As Kelly said, we have a lot of things that we test when apps are getting onto the app directory. We have a lot of those guidelines online, so our documentation is extensive. We're trying to make it bigger. If you have feedback, we also welcome that. With that, I'm going to talk about some of the features that you can leverage to harden the security of your apps. First, we have IP whitelisting. This applies if you're building an internal or an undistributed integration. It lets you limit the access to the web API to defined IP ranges. You could, for example, limit your application to your corporate network and make sure that tokens for a particular app are only coming from within your corporate network. This can help provide defense in depth against token theft, against other breaches, for example, or perhaps token disclosure. As Kelly mentioned, we have a token nuker that sits and looks at GitHub all day and watches for tokens and deletes them and invalidates them, but if your token gets breached in another way, if it gets published in another way, it won't be able to be abused because of this IP range restrictions. Requests originating from outside the range that you specify are rejected by Slack. They are not allowed to use the API. The way this works, you have two IP address ranges in the OAuth and permissions pane of the application management page. There's a restrict API token usage section that allows you to specify your whitelist. You can use CIDR notation. You can use a particular IP. If you know the IP range of your corporate network, for example, or if you know that there's one box with a static IP address and that's the only thing that should be performing as this application, you can lock it down there, save it, and then bam, those tokens are restricted to that IP range. Another feature, that exists. You can make use of that. The next couple features are coming soon, but very soon and you'll be able to make use of them. How many of you have built a slash command before? How many of you are familiar with the verification token of the slash command? How many of you have verified that token when you receive a request from Slack? Great. That's good that you're doing that. Request signing is a feature that's coming out that's going to allow even more hardening to ensure that a request you receive is actually Slack. It's going to allow hardening in more complex environments and situations. It provides defense and depth. It's going to provide security even in the presence of an active man-in-the-middle attacker. I'm going to show a diagram of that. Basically, request signing gives an extra amount of hardening this defense and depth over the current verification tokens. Let's say we have an environment in which there is a man-in-the-middle attacker. When you have an active man-in-the-middle it's someone who can read all your traffic. It's someone who can modify your traffic, intercept, stop your traffic. This attacker is somehow in your infrastructure before your app and they are seeing these requests as they're coming in. The way request signing works is when Slack sends a request to you and your infrastructure, instead of just sending a verification token along, it sends a signature of that request. A signature is a cryptographic construct that will prevent an attacker from forging it or modifying it or even replaying it. We start with Slack has a shared secret with you and your app and that is what's providing the security within this signature. When we send the request out, we don't say here's the request and here's the token along with it because an attacker could look at that, they could reuse the token, they could modify that request. What we send instead is basically a hash of the request and the secret. A hash is going to be a cryptographic hash function. It's a one-way function. It can't be spoofed because of the secret. It'll have a time stamp in the request body so it can't be replayed. This attacker can see this whole request and they can see this signature but they can't change the request. They can't wait later and send the request again and trick you into doing an action twice. When you receive a request from Slack, you, using your shared secret, are able to calculate this hash, make sure it matches so you verify this signature and then you have a guarantee that this request as it was sent by Slack is what you have actually received. Even if you have more complicated infrastructure, if you have requests going through various proxies or other things or you want to keep these things secret from your own internal users, you'll be secure against that. There's no potential for spoofing as long as you verify the signature. Like our token infrastructure now, if you don't actually verify the token, not so great, but same with the signature. Signature works if you verify it. Along the same vein, we're also going to be releasing mutual TLS. Who is familiar with TLS or SSL or HTTPS? If you've used the internet, it's probably going on there. If you connect to Slack, it is happening. We use TLS. This is going to be another way to continue to trust and elevate the trust of the origin of requests that you receive. When you receive a request from Slack, you're given another way to verify that this was indeed Slack sending the request. This is going to operate at a lower level. Whereas the signature verification happens within your application logic, mutual TLS can be done at more of an infrastructure level. We have app level, higher level for tokens, for signatures. We have infrastructure level for mutual TLS. The server, which is you, is able to authenticate the client. Slack is a client. It sends a request to you that says, hey, here's some information. When Slack sends that request out, it sends it over HTTPS. We verify, we check your certificate, and then we send the data over after establishing that connection. Before that step happens, you're able to authenticate that Slack is indeed Slack. Slack will release a certificate signed by a certificate authority. You can set your infrastructure up to mandate certificate checking. We have mutual authentication now. Right now, we authenticate you with mutual TLS. You can authenticate us. As we see here, Slack communicates with your app. We perform a verification. You request our certificate and you make sure that before you even receive data, this connection is from Slack. This offers additional security. It offers defense in depth, especially with regards to the previous diagram I showed, active man in the middle attacker, someone who can modify your traffic, read your traffic. This will also provide more resilience and make things a little more robust in the face of complex infrastructure. If you have your app routing different requests to different places, it's going to help you out in ways that provide more defense in depth. Depending on who runs parts of your infrastructure, maybe you don't want them seeing a verification token. Maybe you only want a certain endpoint too. In this way, they can never spoof Slack. This is often, depending on your infrastructure, just a switch that you flip or just a small configuration change. You don't even have to write your own code for that. This is also coming soon. Moving to a little bit more of access control. Kelly mentioned earlier this principle of least privilege. You want to keep your app scoped to the lowest possible privilege that it should have. In the event of a breach, this means that if your app token gets stolen, it won't have access to more data than it should need. It provides defense in depth. It encourages apps to be acting in a good way, following best practices. For example, if you have an app that should just be sending cat pictures, maybe it doesn't need to read all of your channels and impersonate users when it does that. The permissions API is an aspect of workspace apps. It grants the serenity to more precisely manage your app's capabilities, privileges, and resources. It's a collection of web API methods and events, API event types. There are a variety of ways you can employ this. Basically, what it offers is that you can change your permissions and access over time. This allows for a richer and more secure experience. Let's say you start by following the principle of least privilege and you say, cool, I only need a little bit of privilege. I only need to send a message. But then you come up with this awesome new feature and you want to read messages so that you can provide more value to users of your application. You can then request it. This provides a more seamless way to have granular access control to ensure that you follow the principle of least privilege but you aren't restricted from the future where you can develop more, expand your app, but still follow the principle of least privilege as you continue to develop your application. Another aspect of Workspace apps is short-lived access tokens. This is going to help with another way for you to have defense in depth and follow best practices in an easier way. You can rotate API tokens without downtime and without forcing users to re-authenticate. This will provide an improved experience for both internal and distributed apps. This is coming soon but hopefully very soon, you'll be able to make use of this. Let's say you want your tokens to rotate automatically or you want tokens to expire every day so that you have tokens that are only living for 24 hours. You can do this in a seamless way. You'll be able to use the API and our interfaces to keep these tokens rotating. Let's say your application or your servers do get breached completely. The impact there is mitigated because all of those tokens will expire soon enough anyway. You can also rotate them in the event of a breach without negatively impacting your users. It gives a lot of defense in depth and it also gives a way to deal with emergent situations. You keep using the same APIs here but there's more power to proactively rotate tokens to respond to such situations. You can also reduce the impact of unknown token leaks. Maybe one of your tokens makes it out, not GitHub but Pastebin or some other site out there on the internet. Someone plucks it and they try and start abusing it. With frequent token rotations, the impact of an attacker doing that is limited to a very particular time frame. Instead of a token that's living for a long time where you have to further investigate, you automatically prevent an incident from going on for too long. This is also coming soon. To sum everything up, there are a lot of security best practices that Kelly talked about and you want to be following those. The highlights there, as she said, don't trust user input. You have rich applications but people will try and abuse them. Don't always trust what's coming in. Make sure you're thinking through it and try and think with an attacker mindset. Think how someone would try and break your app, not just how someone will get the most value out of it. With all of those security concepts in mind, we're trying to and continuing to expand our platform to offer more security features so that you, the developer, can provide these enterprise ready apps. Apps that will work in a variety of corporations, in a variety of networks, and provide security and peace of mind to all sizes of customers so that we can keep our mutual customers secure. People who use your apps are people who use Slack and we want this ecosystem to be secure for everyone. With that, we're going to have some time for questions and answers. Anything else to add before we move to that?
[04:16:48] Speaker 1: Cool.
[04:16:49] Speaker 17: Thank you, everyone. Now we have some time for Q&A. I think we have time for one question, actually. Cool. Oh, okay. One. Wait, sorry. Can you stand on the mic? The question is, are there any plans to publish a whitelist of IPs that Slack is using? Currently, no. The nice thing about MutualTLS is you don't need that whitelist because you'll always be able to verify that Slack is the one talking to you. So, if you want to publish a whitelist of IPs that Slack is the one talking to you. At an infrastructure level, you can trust Slack without actually knowing the IP. Okay. Sorry. That's time. We'll be hanging around for the rest of the conference. Please feel free to come talk to us. Thank you, everyone.
[04:18:04] Speaker 1: Thank you.
[04:26:27] Speaker 18: ♪ Hey everyone. My name's Helen. I'm a partner engineer on Slack's platform team. And what that means is that I work with partners every single day to help them create and refine their experiences for Slack. Though I mostly work with partners to create third-party integrations, I'm certainly no stranger to the internal integrations world as well. There's a lot of delight in being able to streamline your own workflows and connect services together. But it can often be cumbersome to build up the infrastructure that support these apps. And that's where Lambda really shines. So today, I'll be walking through the process of building my very own Slack app in Lambda, starting with a brief introduction into what Lambda is. Then we'll look into how to trigger these functions through Slack. And finally, we'll build out a small utility function, which is a slash command that I'll randomly choose a winner out of all the members in the Slack channel. So first things first, what is Lambda? In essence, Lambda is just a platform to build serverless functions on AWS. It's really streamlined the process of creating smaller, on-demand applications that are responsive to events. And we at Slack have continued to partner with AWS over the years to create content as well as to create blueprints that make the process of creating these Lambda functions even easier. And there's a lot of out-of-the-samples that you can start off with that are actually available through AWS, I'll show you soon. But we're going to be creating our own from scratch today. So Lambda functions will only run when they're invoked, and you're really paying for them on a per-use basis. And they support a variety of different languages. We'll be using Node.js today, but you can also use Lambda functions through Go, Python, and lots of other things. So Lambda functions are actually triggered through invocation hooks, and there's quite a variety of different triggers. If you're an engineer at Osperson, you might want to trigger them through other events that are happening in AWS. For example, if there's a CloudWatch event that occurs, or if an object is created in S3. If you're into playing with IoT or things like Alexa, you can connect those as triggers as well. But for us, we're going to be working with API Gateway today as a trigger for our Lambda function. And I think that's probably one of the most popular methods to actually start these off. So AWS Gateway is a way to create powerful APIs for your application. You can create, publish, and manage your endpoints. But we're just going to be setting up one single endpoint today to field requests from Slack, from Curl, or essentially it'll just be a public URL that you can hit, and everything about those requests will then be proxied over to our Lambda function. So with that, let's switch over to the demo, and we can show you how to create one of those.
[04:29:19] Speaker 1: Cool.
[04:29:20] Speaker 18: So here you just see my AWS dashboard, and I'm going to go into Lambda itself. So right here, you can just create a new function. And as you can see here, there's a lot of blueprints that you can use to kick off a Lambda function as a template. So if you search for Slack here, you can actually see that there's quite a few Slack examples out there already for things like a slash command or things like posting a CloudWatch event or alarm into Slack. But we're going to be authoring ours from scratch. So I'll just give this a simple name. I'll call it slack-spec, leave it at node six, and then choose an existing role. I'm going to be creating a custom role here, and roles are essentially a way to define the permissions that this Lambda function has. It's taking a little bit of time to load, but essentially because our Lambda function isn't going to be doing very much in terms of connecting with other AWS services, so I'm going to zoom in here. We're just going to allow that and set its role to basic Lambda execution. And there we have it. We've created that function. So now, if you scroll down, you'll see that there's actually a CLI that's available to you from right within the browser, and you can use this to start creating your function. But first, let's actually set up our API gateway trigger. So you go up here, click API gateway, and then you can start configuring that trigger. By doing this just through Lambda, what you're creating is called a proxy integration type for API gateway. And what that means is it's just the most simple way to create that endpoint. It's going to accept really any requests that you're throwing at it, no matter which HTTP method it is. So let's give ours a name. We'll create a new one. I'm going to call this slack-spec as well. Leave the deployment stage at prod. And we're actually going to configure this as the security as open, just so that it receives every single request. So now we've created that. We can save our changes. Awesome. And we can start adding in our code. So you'll see here that Lambda has already given you some starter code. You can see that a Lambda function will take in some sort of event. This is essentially all of the data around that request that's being proxied in. And we'll do some sort of work here and pass back a callback. But the thing about API gateway is it's actually expecting in the callback a sort of HTTP response object complete with status codes and with a response body. So we'll actually have to change this up quite a bit. And for the, for safe time, oh my God, have a snippet. Okay. We're just going to construct our response body. We're going to make that an object with sort of a text as hello world. And then we're actually going to echo back that entire event that's being sent in currently. Then we'll construct the whole response itself, setting the status code to 200 and then stringifying that whole response body. And we save that. That's it. The Lambda function's live. So let's try to hit that Lambda function now. Wait, actually, let me go get the invoke URL. So that's on the API gateway level. And you can grab that just from here. So if you go into curl, you can just make a simple get request to that. I'm going to pipe that into JQ so we can see the response a bit more clearly. And as you can see, you get that hello world text back along with all of that input. So there's a lot here, which means you can do potentially a lot with that Lambda function. For instance, you get the resource, the path, the HTTP method, all of the headers that are involved. And if we had added anything to that request body or to the query string parameters, it would be here as well.
[04:33:49] Speaker 1: Cool.
[04:33:49] Speaker 18: So now we know that that works. Let's actually try to hit this Lambda function through Slack. So to do that, we have to, of course, create our Slack app. I'm going to name that Slack-spec as well and add that to my development workspace.
[04:34:10] Speaker 1: Okay.
[04:34:11] Speaker 18: Okay. And you can actually hit Lambda functions through a lot of different parts of the Slack API. For example, you can connect a button press to a Lambda function. You can configure your events API subscriptions with the invoke URL so that, for instance, if a new emoji is added to your team, a Lambda function gets called. But today, we're just going to stick with the humble slash command. So we'll create a new command. Our first one, I just want it to be something simple to prove that it works. So I'm going to call it echo. And what this will do is it'll just echo back whatever the user types in as a text after the slash command. And then for the request URL, you can use that same invoke URL from API gateway as well. Give it a description.
[04:35:09] Speaker 1: And I'll save that.
[04:35:09] Speaker 18: Okay. Okay. And now we have to install this app onto the team. Sorry. Bear with me, the Wi-Fi's a little bit slow. Okay. So now I can install that app onto the workspace. And after you install an app onto your workspace as a single team app, you'll get the OAuth access token here. I'm just going to copy that and make it an environment variable in our Lambda function. While we don't explicitly need the access token for our echo command, we'll need it a bit later on as we make calls to the Slack API. And the other piece that we'll need from the Slack settings is the verification token. So with every single slash command, or actually with any outgoing requests that we make from Slack to your app, we want to send along this verification token so you can verify that the request is indeed coming from Slack and not coming from some third party or some malicious entity. And we give you that verification token here. And you should treat this token just as securely as you're treating the access token. Okay. So now that we have that saved, we can start reconfiguring our handler to actually respond in a Slacky way. But actually, we first should figure out what exactly that slash command sends over to your app. So now let's switch back to the slides so we can investigate that. Okay. So what you can see here is what a slash command payload contains. We give you all the information we can about that slash command request. So for instance, we give you that verification token, information on the team and the channel that the slash command occurred in, as well as the user who triggered it. Importantly, we also show you which command was called because each Slack app can contain up to five slash commands as well as the text that the user typed in afterwards. So this is all well and good. But the thing to also note is that this is being sent over to your app as a form URL encoded request. So what does this look like after it goes through API gateway and into Lambda? It looks something like this. Now, if you remember from that curl request, there's a whole lot of different things that are turned back. But what we really care about here is the body of the request. And all of those parameters are being sent in right there. And this looks a little bit messy, but we can definitely clean that up and parse that ourselves. So now let's switch back into the code. And we can start modifying this. The first thing we'll want to do is to actually use the query string. Sorry, make that a little bit prettier. Modules so that we can start parsing that body into something that we can really work with. Okay, and next I'm just going to delete all this for simplicity's sake. We can start by creating a shell of a response body that we will start to return. So what that needs is a status code, which we'll set to null for now, as well as a body, which we're just going to set to an empty string. Okay, and now we can create a variable called params that will contain all of our event body in a parsed way so that we can start asking it for the specific command or the user. And since that's on the body, that's what I'll pass in here. Okay, great. Now before we do anything else, I get very nervous live coding, so I know all of you just saw like 10 typos within one line, but it's okay. I got them all, I think. Okay, the first thing to do is actually check that verification token that we saved as an environment variable. So we'll do that by seeing if what we've saved is equivalent to the token that we have passed back in to us. And if it's not the same, that means this request is a little bit suspicious. So we'll, or at the very least, it's unauthorized. So we're going to set the status code then to 401, and we'll set the response body to a simple unauthorized. Great, and then we can just return back from there with the callback. Cool, so that takes care of checking for the verification token. And if it did go through this, then that means we can just return a 200, and set the response body to actually be equal to the text that we have in params, because if you remember, that's basically the text that the user has typed in after the command. Okay, so we can save all of that. And now if we go to Slack, we should be able to find that echo command and say something to it. Something is wrong. Okay, oh, duh, I did not, I didn't return it. All right.
[04:41:45] Speaker 1: Cool.
[04:41:45] Speaker 18: So now let's try that again. And you have high spec. That's exactly what I typed in before.
[04:41:51] Speaker 1: Thank you.
[04:41:56] Speaker 18: I'm really embarrassed that there was clapping for that small feature, but we're gonna go and take that a little bit further. Okay, and we're going to make that sort of roulette, picking a random winner feature that we talked about before. So in order to do that, we'll need to add a bit more scope to our app, and we'll need to create a new API call method. And we need to really start to retrieve that conversation member information. So we have a method for that. It's conversations.members, and it's pretty straightforward. When you call that with a, by the way, the request up there is wrong, and I'm just gonna call attention to that. You'll want to send in the access token and the channel ID, and it'll return back to you the list of the members that are in that channel. And that's all we really need for this, right? Now let's go back to the code. And we can start configuring our app for that. So the first thing we need to do is to call conversations.members, but conversations.members will actually require some scope, because if you remember for our app right now, all it really knows is the slash command. So we'll need to give it some new permission scope, and then once we're looking for our channels read, which will give you information about public channels on a team, and why don't we go ahead and add groups, colon read as well, which will give you information about private channels on that team. So we'll save that. And you can see, as soon as I save the permission scopes, Slack recognized that, hey, you added new scopes to this app, so you need to reinstall it before any of the tokens take the new scopes into effect. So we can just click that, authorize it, and now we're back. And we'll also want to add that new slash command in as well. So I'll create a new command. I'll call it random winner. I'll use the same request URL that I did before. Let me copy that in from Lambda. I'll save it. Short description, right? Picks a random winner. Save that. And now we have two slash commands on our app. So now all we have to do is go ahead and implement that. For time reasons, I am just going to paste that in here, and don't worry, I'll walk you through what I did. So before, when we only had that one slash command, it was really easy for us to just set the body of the request to exactly that text and return it back, and we didn't have to check for the exact command itself. But now we can check for it. If it's echo, we'll do that. And otherwise, we can start picking the random winner and assume it's the other command. So first things first, we have that URL that we're going to make that request to. So it's conversation.members. We're gonna pass in a token as well as that channel ID. Sorry, I have trouble scrolling back without going back on the page, because of how zoomed in I am. And then we'll then just go ahead and make that request itself. So we're just going to be using the HTTPS module for this, because we're only making one GET request. So there's no sense in importing something like the request library. But if that is something that you're interested in, you can certainly do that as well. Just know that in Lambda, you have to upload all of these modules yourself if you're using something that's not off the shelf. Okay, so once you make that request, at the end, once you receive all the data, you'll just parse that response body into result. And then for that members array, we're just going to go ahead and pick a random member from it. So we're multiplying random by the length of that array, and then doing floor. And then you should be able to get that winner user ID right within this variable. All right, so let's save all of that. And test that in here. Hmm. Access token. Right. Yeah. Oh, I see what I did. Thank you.
[04:47:03] Speaker 1: Clicking.
[04:47:03] Speaker 18: Okay. That totally makes sense why that didn't work. Let's try that again. Great. And you're able to pick a random winner from that channel. It's pretty simple, but when you run this over and over again, you can get different people. Randomness does work this way, where it doesn't always pick a different person each time. Oh my God. Okay. This totally is a very lucky person, so this makes sense, but it's fine. I'm over time right now, so we'll just leave this be. You saw my math. It's good.
[04:49:29] Speaker 19: Thank you.
[04:55:51] Speaker 1: Ladies and gentlemen, please take your seats. The program is about to begin. Thank you.
[04:56:57] Speaker 20: Hello. Thanks for coming to this one. We are gonna be talking about managing Slack at scale. My name is Jim Ray, and I work here on our developer relations team. I work primarily with our enterprise and large enterprise customers, and I work a lot with engineers that are building internal tools just for their organization. If that sounds like you, please find me and let's chat afterwards. But today, I want to talk about some of our APIs for scaling Slack along with your growing organization. So by now, you've no doubt heard that communication is at the heart of what we do at work. And the Slack platform is all about creating this central communication hub for your team. So whether that's increasing transparency across your org using something like public channels, creating this automatic and always growing corpus and history of all of your company's communication, or using apps to bring more conversational context to the communication that your team is doing all the time, Slack is what is gonna bring all of this together. So Slack has always worked great for small teams and for startups. And last year, we launched our enterprise grid product. And so now we're able to help organizations with tens of thousands of team members do their very best work. But as an organization grows, it faces a slightly different set of challenges than maybe one of these smaller companies or maybe the challenges that you had when you were a startup and Slack itself becomes something that needs to be managed more directly. So we want to talk about a set of APIs that you may be less familiar with that will help you keep your Slack org humming along nicely. So specifically, I'd like to introduce the eDiscovery and DLP APIs, our fairly new audit logs, and then I'm going to bring up one of our engineers, and he's gonna talk about using SCIM to manage the information about the people in your organization. So first up is a duo of APIs for managing the security and compliance of your enterprise grid org. These are called eDiscovery and DLP. So the first thing to know about these is that they are enterprise grid only. So if you need a compliance solution, this is a great reason to move up to enterprise grid. And these APIs allow the administrators within a Slack organization to discover and secure any of the data that is in a Slack org. This includes public channels, direct messages, private channels, and even files uploaded to Slack. And so while these two APIs are often grouped together out in the marketplace, they actually do slightly different things. So eDiscovery is broadly all about this process for discovering and isolating information that might need to be used later for, in a legal context, for legal reasons. So regulated industries or governments often require an eDiscovery solution to be in place in order to keep electronic data secure and in order to actually keep it around for later discovery process. DLP stands for data loss prevention. And this is similar, but this is actually a technique for identifying sensitive information, such as employee or customer data. And then a DLP solution will actually let you specify a query so that you can proactively remove or redact that information so that it's not able to be accessed or compromised later on. So you might set up a query that says something like, look for a string of letters that look like a social security number and then automatically remove or redact that information. So our eDiscovery and our DLP APIs, they're built primarily to work directly with eDiscovery and DLP partner applications. And if you work in a regulated or a government agency, you probably recognize some of these names. That said, if you are interested in building your own discovery or DLP solution, we can actually help you out with that. We'd need to enable some things in the back in there, but we can enable this for custom applications as well if you're interested in building your own. And if your company builds an eDiscovery or a DLP solution and you're interested in getting on this slide, then come talk to us a little later. Next up is the audit logs API. Now this is the newest addition to the Slack platform family. And these are there to sort of keep a watchful eye on your org. So like eDiscovery and DLP, the audit logs are currently for enterprise grid orgs only. And these are perfect if you've ever wanted to store data about your Slack workspace or your org in an SIEM tool, or you wanna get more insights about how your team is actually using Slack. And they're also ideally suited for watching for potential security issues by being able to track things like user logins. So the way that the audit logs work is they generate this log that is read only, and they create events that provide metadata about the workspaces on an org. So each audit event contains an actor which takes an action on an entity within a certain context. So for example, when a user logs into a workspace, they are the actor who takes the action of logging into that workspace. So here are some of the more common events that you can track with audit logs. You can keep watch over some big changes like a new workspace was created within your org, or something slightly less eventful like a new alias was added to an existing emoji. And we're gonna continue to build out the audit log events that you can track as we continue to grow and evolve the platform. And so finally, there is our SCIM API. Now SCIM may be something that you're already familiar with. It's an open standard that's been around for almost a decade now. And SCIM is available on both our Plus plans and on Enterprise Grid. So SCIM is a RESTful API, and it supports the standard REST verbs. And with SCIM, you can automatically sync the data about your team inside of Slack with an identity provider that you might already be using or some sort of internal user directory. And you can, the real power though is that you can provision and deprovision team members, you can update their profile information, and you can manage user groups all programmatically. So now I would like to introduce Arca Ganguly, who's an engineer on our identity team, and he's gonna cover using SCIM in depth. Thanks.
[05:03:55] Speaker 21: All right, thanks, Jim, for that great intro. My name's Arca. I work on the Enterprise Identity Team at Slack. Our team is mostly responsible for ensuring that companies of all sizes, large and small, can safely manage and deploy Slack at scale. We've built many of the APIs that Jim previously touched on, including the SCIM API, which I'll be taking a pretty deep dive into. Okay, but before I get started into that, what, oh, oops. Does anybody in the audience actually know what SCIM is? Okay, I saw some hands go up, that's good. For those of you that don't know, it's pretty simple. SCIM is just a standard for exchanging user identity information between software systems. I know, exciting. But really, this is pretty important in today's day and age because just think of all the different software systems you use to get your work done on a daily basis. Slack might just be one of those tools, but you might be using like 10 other things on a daily basis to be just able to do your job. And SCIM is just the standard that says how the schema of exchanging user identity between these systems should be like. Specifically at Slack, the SCIM API can be used to provision, deprovision, and update user information programmatically. Now, that's great, but why do we even need this API? Like you can go into the Slack admin right now and you can add new members, you can easily deactivate members, you can even update some information about members in your Slack workspaces. Well, the problem is this is great for when you're just managing a few users using your Slack instance, but really what companies see is that they need to deploy Slack to their tens and thousands of employees at this company, and they have no way of going in and doing this manually. Like they're not gonna go in and add 10,000 users manually via the UI. So we need an API for that, but also we need to be able to automate a lot of this process, because things change all the time. Like employee titles are always changing, their departments are changing, their role in the company is changing, and you wanna be able to sync this information down to every single system that that employee has access to so that you always have the most up-to-date information everywhere. So if we take a look at what an example setup looks like, this is what many of our customers that use the SCIM API might have. The thing to note here is that there's really one source of truth. There's just the information directory, which is where you enter all your employee information and update information. Ideally, what you want is any changes you make to a directory sync down to each of these different software applications that that employee uses to get their job done on a daily basis. This is great for consistency, but it's also great for just security. You need to be able to know that when you deactivate someone at your directory, that they were actually deactivated in Slack and that they have lost access to that system. SCIM is great for this because it's like the common language that talks between all these software systems. So you can just build one application or connector that consumes this identity information, and you can connect it to as many different software applications as long as they support SCIM. The other thing to note is that the SCIM API at Slack is actually arrestful. This is a distinguishing factor because most of our regular APIs are actually not restful APIs. Now, why do we make the SCIM API restful? Well, firstly, it's a standard, and the standard says that it has to be a restful API, so we didn't really have much choice there. But the other good thing about it being a restful API is that developers know what to expect when interacting with this API. Like, if you're a developer, you're probably already familiar with the HTTP verbs, and you know what those HTTP error codes mean. And having a standard like SCIM allows you to very easily and predictably build applications against this API. We're gonna be talking a bit more about HTTP verbs later on, so I just wanna do a quick refresher. I know everyone in the room probably already knows. But, so our SCIM API supports the standard HTTP verbs, get, put, patch, delete, post. A get request is just to get an existing resource from the server. A post request is used to create new resources on the server. Put and patch are used to update information about a resource on the server. They're slightly different in that a put request will overwrite all fields with whatever is sent along with the request, whereas a patch request is an incremental update to a specific field. And finally, a delete request is just a delete. So, if we take a look at how this all fits into our SCIM API, you can see here the three high-level use cases that we talked about, which is adding new employees, updating employee information, and deleting employees can all be done pretty simply just by sending these HTTP requests. So, firstly, we're gonna send a post request, in this example, anyway, to our SCIM users endpoint, and that's gonna return us like a 200, it's actually a 201 created response, but anyway. It's gonna return us a successful response, and it will give us a unique identifier for this user in Slack. That's that UID. Then we can use this unique identifier to make any subsequent requests, such as patch, or put, or delete, and update information about that specific user profile in Slack. We're gonna be digging deeper into each of these cases a little bit more, and seeing actually what the payloads look like, but here's like a very high level of how basically most of these SCIM connectors work. Because if you're using an identity provider at your company, you most likely are already doing this behind the scenes, because we already have SCIM connectors for identity providers like Okta, OneLogin, and so on. So, the first case we're gonna be looking at is onboarding users. This is pretty important, because you've just bought Slack, you want your employees to start using it, but you need to be able to give them access to it. Now, again, you could do this manually via the UI, but as we talked about, that is not feasible for larger companies, so you might wanna use the SCIM API and do it programmatically. What that might look like is something like this. Let's say you have a new employee starting, his name's Arca, and he's an intern at your company, so you need to add him to your employee directory. So you do that, and then you wanna create this user in Slack, so you can use our SCIM API to send a POST request with all the relevant information, and it'll create that user profile in Slack. The important thing to note here is that all these fields we're sending, such as username, name, display name, title, these are all set by the SCIM standard. Slack didn't make any of this up, there's no ambiguity here. Any other system that you integrate with will also support the exact same schema. So as a result of that POST request, you might have a Slack profile created with the pieces of information you've provided us. Great, that works, awesome. Now let's say we wanna update these profiles, because that's also pretty common, because most of the time, you are not just gonna wanna create users and forget about them, you still need to update their emails maybe, if that changes, if their name changes. In this case, let's say we wanna give Ark a profile picture, and maybe we wanna change his title. Oh, on the slides, I see the title and ID are gone now. But those were very important. Anyway, you would send a request like this. In this case, let's just focus on the photos. So as you can see here, we're sending a photos attribute, and we're sending a patch request to the specific identifier for Arca in Slack, which is that WID thing there. So then Slack receives this request, and we know exactly what user you're talking about and what fields you wanna update about this user. So as a result of that, you can see now my profile in Slack was updated with the profile picture, and my title, and some other things were updated too, which we didn't see in the other slide. Anyway, this is also another cool feature that we have in Slack called custom profile field syncing. So the title is just one of the fields you can sync. You can actually set up up to 25 fields that you can automatically sync every time something changes in your employee directory or identity provider automatically. Great, and the last use case we're gonna look at is offboarding users, because people leave companies all the time, and you wanna make sure that they have lost access to Slack, and you wanna be confident in that because that's a security risk if they didn't. So there's two ways we allow you to offboard users using the SCIM API. One of them is you can send a patch request. Again, the text is missing, but if you send a patch request with the active attribute to false, it would actually deactivate the user in Slack, or you can send a delete request, and it would have the same effect of deactivating the user ID you provided in Slack, which will in turn make their account look like it's a deactivated account. One thing to note is that Slack never actually deletes user accounts, so we just disable them. You can always reactivate these accounts later if you'd like. So that was a look at how you might use the SCIM users API to manage users individually, but again, that's not really feasible for companies at scale, so we offer user groups too, and user groups are just simply a group of users, and they support the exact same operations you can do with the users SCIM API, but just in bulk. So you would create a group by sending a post request to the SCIM groups API, and that would give you a unique ID for that group, and then you can add users to these groups and make bulk updates by sending patch put requests with the group ID. So you could imagine having a group for full-time employees, and maybe contractors, and maybe interns, and maybe you wanna do different things with those groups. Maybe some groups get access to some workspaces, some groups don't, and you can do that all really easily using our user groups API, which allow you to basically do all of those things I talked about earlier, but just for a bunch of users at once. That was a quick look at how our SCIM API enables large companies to manage user lifecycle at Slack, and yeah, I'm happy to talk about any of these things here after you can come find me outside. Thanks for listening.
[05:21:09] Speaker 1: Thank you. Thank you so much. Good job, we made it. Oh, look. Oh. Thank you. And thank you for listening. Thanks, everybody, for this incredibly neat talk to you, and I appreciate it. I'm Prof Blake, and with that, I'd like to get to our next speaker, but I think there's a couple more that I did not mention. ♪ Ladies and gentlemen, please take your seats. The program is about to begin.
[05:46:33] Speaker 22: ♪ All right, well, welcome, everybody. Thanks for coming to this session about Slack's awesome first-party tools. I'm excited to talk to you all about some of the tools that Slack has been building to try and make your lives as developers a little bit easier. My goal here is actually to talk to all of you all and start to make you feel a little bit more like power users when you jump into using the Slack platform. And my name is Ankur. I work on the Developer Relations team. We're a team that's actually... that helps build some of these awesome tools. And as somebody who works on the platform, I think a lot about what it takes to make a really good, compelling developer experience, not just a product experience. And I can't help but sometimes draw some parallels to video games. Because for that first level, when you first walk into a video game experience, a lot of times you're shown, like, one kind of interesting little experience. And you find out something about this world you never explored before. You eat a mushroom, you get a little bit bigger. You can do things like attack different kinds of enemies. And for developers, we call that experience Hello World, right? Like, it's that first moment where you say, huh, I've just learned a new capability. There's something here that I didn't know about before. And you start feeling super empowered, super intrigued about what might come next. So right out of that gate, there's that first mushroom, or the coin that you got, or a fire flower. And you start to learn that... Oops. You start to learn a little bit more about what's going on in this world. You start to figure out which cases you want to reach for which tool, right? So you got to make a long leap over a big platform gap. You're going to go try and see if there's a mushroom around you. Or if you want to make a long-range attack to another enemy, you might try and find that fire flower so you can spit some fireballs. So you start to become accustomed to whatever your toolkit is, what's in your tool belt. And that's what I think leveling up feels like on a platform. It's about knowing exactly what problems can be solved in which ways and how you can find the right tools to do it. And just orienting yourself around that experience. So it all starts with an idea, right? This one's kind of silly. I'm a very lazy... Oh, wait, this wasn't my idea. Never mind. I'm not the lazy and over-caffeinated individual. But Slack is very fortunate to have an awesome workplace team where some really fantastic humans help us in the coffee bar and make us coffee. So one day I was thinking to myself, you know, wouldn't it be great if I didn't have to wait in line once I got there? What if I could just place that order ahead of time and I would save myself a whole two to four minutes? Of course, I know this sounds silly, but I think actually a lot of us find inspiration for building ourselves little quick fixes in our everyday work life this way. I mean, you start with something silly like this, but you might eventually say, you know what, I know how to aggregate some diagnostic reports from some equipment, or I know how to automate some part of a sales workflow. But really, we build tools for ourselves to be able to solve our own problems in the beginning, and then we start understanding where else we can take these possibilities. So I'm going to start with that use case, this use case where we want to build a little app to help us make coffee ordering a little bit easier. So can we switch to the demo, please? So in here I'm in my Slack workspace. This morning we got a sneak peek at SDT, the Slack developer tools. I'm going to go ahead. I kind of want to start with like a menu, a menu for coffee items. I think that might be a good way to start my little coffee app. I don't really know much about formatting or styling. I really just want to like do this as quick as possible. So I'm going to click over to the actions menu and inspect this pretty nice little menu that I saw in Asana. Asana is one of the partners that's already being, who already has an app with actions in the app directory. So right here I can take a look. I can see exactly what it looks like when, how to build a message that incorporates a menu. And I'm just going to jump over to, oh, hey, Message Builder, right? That was a pretty cool part of the keynote that we saw. Why don't I see if I could use that? All right, so we're over in Message Builder. I want to start trying to customize this menu a little bit, make it feel like the coffee app that I'm trying to build. So why don't I just start changing some of the text around in here. It'll be make a drink order. We can remove some of these fields. They don't look like they're necessary. And maybe what would you like to have? And we don't need a button. So we can go ahead and remove the button. But we will need to customize this menu a little bit. That's not right for us. So let's see. Oh, Options. There's just a big array of text and values. I guess I could just replace those. Cool. So now I got something that looks a little bit more like a menu you might use to select yourself a drink. Not bad, right? What I love about this experience so far is I haven't had to open a code editor. I haven't had to write anything yet. But the platform feels alive. I can start testing it out, poking, prodding, and learning a little bit more about what the capabilities are, kind of like that first level. So can we switch the slides, please? So we just saw here where Slack Developer Tools and Message Builder are working hand-in-hand. To summarize, Slack Developer Tools was the way that we were able to inspect the JSON structure of a message. You could also use it for various other use cases. We saw some of these showcased in the keynote this morning. You could use it to invoke various web API methods. And also, one of the things that I think is super valuable is you can painlessly traverse the authentication prompts. A lot of times, the biggest hurdle in starting to build an app is actually trying to figure out, how do I get the right tokens? And Slack Developer Tools will help you out with that process in a way that feels transparent and feels like you're not getting stuck in the weeds of things. And then there was Message Builder. Message Builder is a live, updating preview of whatever you want to build inside Slack. So this is super useful. I've seen it being used by design teams. And one of the greatest parts about the Message Builder is the URL is also live updating. And a lot of people don't realize that. So as you're editing a message, you can send that off to a colleague and ask, hey, what does this look like? Do you think I could improve anything? Should I change the color? Should I change the text or the copy? So these are all really cool ways to start touching the platform without even having to write any code. Can I switch to demo, please? So in the next demo, we want to start actually doing something with this message that we just formatted really nice. So one of the other things that we offer is the OpenAPI spec. Now, the OpenAPI spec is a JSON file that describes all of the web APIs that Slack offers in one big blob. Why is this useful? It's an open standard. It's not a proprietary format that we came up with. So there's actually an entire ecosystem of tools out there that will use the OpenAPI spec to help you build requests or to visualize data or maybe even implement some testing in your app. So one of the things that I love to do with these API specs when I find them around the web is to import them in a tool that I often use called Postman. So I'm just going to take this raw JSON here off of GitHub. By the way, it's hosted on the Slack API GitHub where a lot of our tools are hosted that you should check out if you get a chance. And then I'm going to go ahead and import. So this is Postman. It's basically a GUI client for invoking web APIs or RESTful or HTTP-based APIs. And they have this handy feature where you can actually import a collection based on an OpenAPI spec. So I just paste that in, and I'm not going to hit import here because I've already done it a little bit ahead of time, but essentially you'll end up with a browsable, clickable menu of all of the methods in the Slack API. Now, this is super useful for being able to switch back and forth between testing out method implementations and understanding what the requests and what the response look like. So we have that little menu that we wanted to build, right? So why don't we try sending that out to Slack? The method that I'm going to want to use here is called chat.postMessage. So I've already got it loaded right here. In the headers, I've already kind of populated in my app's token. So this is the point in your process where you typically want to go out, create an app on the Slack API web page, and plop in your token to make sure that you're doing it the right way. So I'm going to go ahead and add in our little drink menu order. Now, there's one item missing from this, which is our channel argument. A quick little tip trick that you may not be aware of is if you're browsing Slack and you're opening up to a channel, the channel ID is actually right here in the URL bar. So I'm just going to go ahead and copy that, throw that in, hit send. Oops. And take a look. There's our little drink order menu rendered right in here. So that's great. I still haven't had to write any code. I've just been copying and pasting things, and I'm still already almost there. I just need to figure out how to take that order. Wonderful. So if we could switch back to slides, please. To summarize, the OpenAPI spec is, again, a machine-readable format. In this demo, I showed how you could use Postman to create a library of requests to trigger the Web API and to try out any methods that you might want to. But I've also seen projects out there that utilize this open format to go as far as to generate an entire library in your favorite programming language to use as an SDK. So we're really excited about the possibilities of OpenAPI. We've also released specifications in AsyncAPI for the Events API, as well as added new OpenAPI version 3 support to our specs on GitHub. Can we switch to demo, please? So I've been avoiding writing code because that's the part where I feel like I need to start actually doing real work. But as I said, I'm lazy, so let's go ahead and actually start doing some of this work. All right, so what I have here is a basic Express app. I'm going to be using Node.js for this demo, and I'm going to be demonstrating some of our first-party tools, our SDKs. But notably, there actually is a set of tools that we have in Python, and there's a great community of community-authored tools out there as well. So for anybody who's used Express or Node.js, this probably looks familiar. This is basically the hello world of writing a web app in Node. I'm going to go ahead and start by importing a library. This is the Slack Events API library. It gives you one method, this createEventAdapter method, that you can call with your verification token. So one of the greatest things about the first-party tools that we have to offer is we built in... It's built in a lot of the best practices that we've seen, and we've built in a lot of use cases that we believe help, or sorry, patterns that we help believe give you good security, good, sane defaults, and just a good overall experience. You'll notice that in this case, the method straight up asks for the verification token up front, and that's because on every incoming request, the Events API adapter will take care of checking your verification before it ever lets your app even see the request. Now we just call one more method on the Slack Events API adapter called Express Middleware. And for anybody that's familiar with the Express framework, it's just the easy way to plug in the building blocks of the framework itself. And it just takes a ‑‑ all you want to do is make sure that it's available at the URL that you have configured for your app to send its requests ‑‑ sorry, its events to. Now I have to start thinking about how do I actually want this menu to appear in my app. It's not going to just post itself randomly, right? There has to be something that triggers it. Well, the Events API is a great starting point for triggering workflows in your own app. And right here I'm using a specific event called an app mention. And what I think is really great about this event is that it doesn't actually require any permissions for your app to read any messages coming out of a channel. It's completely passive. Unless somebody actually mentions your app with an app mention, you won't actually have to worry about where that data goes and how to secure it. It just solves so many of those sort of privacy‑related issues without you even having to think about it. So now that I have a place to hook into, the Slack Events API adapter will actually ingest that HTTP request and invoke my handler right here. Well, what do I want to do in this handler? Of course I want to go ahead and send that menu back out, right? So I'm going to bring in one more handy tool from our first‑party toolkit called the Slack Node SDK. The web client that comes out of the Slack Node SDK is just a really easy wrapper for using all of our Web API methods and end points. It does, again, the right thing by asking you for your authentication token up front, which I brought in through an environment variable. And then it gives you an awesome little interface where you can start calling Web API methods directly on the actual instance. Now, I see something pretty interesting happening here. Does anybody else see what's going on? We're getting auto completion on the Web API. I mean, my IDE doesn't know anything really about Slack. How did that happen? Not only are we figuring out what the method names are, but it's telling me what kind of arguments it takes without me having to do much. This is thanks to some of the latest work we've done in the Node SDK. I'm in a regular JavaScript file. If you take a look, my file name here is just demo.js. But we've actually taken the time to describe all of the data types in the events API request parameters using TypeScript metadata. And what TypeScript does for us is it brings this, like, rich experience right into your editor. It doesn't matter. I'm using VS Code here. It doesn't really matter what editor you're using. There's probably an extension available. There's probably some great tooling around TypeScript and the work that that team has been doing that can do something similar for you. And it's great because this really saves me the round-trip effort of having to go out to the docs just to check, oh, does this thing take a string, and what is the name of the text that I have to send? Is it text or message? So I really love using the JavaScript SDK because it helps me save time this way. So I'm going to go ahead and I'm going to just copy the message that we took out of Postman and provide it here.
[06:05:02] Speaker 1: Great.
[06:05:02] Speaker 22: I'm going to make one simple substitution here, which is I don't necessarily always want to go back to the same exact channel that the event that we tested the event out in. I actually want to send it back to the channel where the user had mentioned my app. So I'm going to go ahead and change that to event.channel. Now there's one thing that we haven't figured out yet, and it was still kind of a problem back in the way that we saw our app before. What happens when you click one of these menu options? Well, Slack's APIs have another section called interactive components. And with interactive components, you get a chance to react to button presses, menu selections, dialogues, and today with message actions. So I'm going to go ahead and import another handy tool that we have. I'm going to go ahead and create a new instance of that one as well. The Slack interactive messages component is super similar to the events API component. It gives you those same great defaults, that same secure processing of each incoming request, and it enables you to just start thinking about how you're actually going to integrate this into your project. So I'm going to go ahead and mount it in the exact same way. All right. We're ready to go. Oops. Okay, cool. So now that we have the interactive messages component imported, all we have to really do is route the incoming message requests out to our handlers. And just like the events API, we get a handy little syntax for routing these handlers, and it's just using a method called actions. The first argument of action is going to be its matching constraints, and that's described as either a string or a callback ID that you created when you were ‑‑ you assigned when you were creating the action. So in this case, I'm just going to say order coffee. And then we're going to use a callback. Before we move on, we want to make sure that that order coffee callback ID is also represented in the menu that was sent. Great. There's one more cool thing the interactive messages adapter does for you that the events adapter didn't necessarily have to deal with, and that is the asynchronous timing of events. Now, typically when you're using the interactive messages framework, you want to be able to respond to an incoming request within three seconds. That's because if you don't, the user is going to see an error, and that's no good for anybody, right? It makes you look bad, it makes Slack look bad, and you want to make sure that your users understand exactly what's going on when you submit an action. So what the interactive messages adapter does is it allows you to just worry about doing the action, and you can return a JavaScript promise, and it doesn't actually matter when that promise resolves. The interactive message adapter will do the right thing by responding with an okay acknowledgement request if it doesn't reach, if it doesn't, if your promise doesn't resolve within a specified timeout. And if it happens later, we'll end up using an asynchronous response URL to go ahead and update the message. So this entire problem is completely invisible to you. So what I'll do here is I'll just return a new promise. And for demo purposes, my promise will never really fail, but we call, we resolve the promise with a simple message. And in this case, I'll just say, thank you. Your order has been received. Cool. Can we switch back to slides, please? Great. So what you saw just now was the events API for Node and the interactive messages adapter for Node working together. And like I said earlier, we actually have very similar products available for you to use in Python as well. So the Node API, the events API adapter for Node has the semantics of a normal event emitter that you're used to using in Node. This is a very common paradigm. It's super seamless. And it gives you all those same defaults without you having to think about them. The interactive messages module lets you handle button clicks, menu selections, and dialogues. And it gives you even a fine-grained control over the selectors you use to constrain them. Today I showed you how to use a callback ID, but you can also constrain your callbacks by what type of interaction it was and what the values were inside of the interaction. You can respond both synchronously or asynchronously, and that's kind of up to you. I have one last demo, so can we please switch over to demo? Great. Now before I start socializing this neat little coffee app that I've been building with all my other friends and tell them how great it is and try and get everybody to get on board, I want to make sure that this is something that works and it will continue to work. Because we all know that people are going to come ask me for new features and I'm going to have to develop them and I'm going to have to say yes to some and I'm going to have to say no to some. But in the end, the core functionality, I want to make sure it's rock solid, right? So the dreaded task, we have to write tests. So writing tests has been one of those sticky areas that's plagued Slack app developers for quite a long time. And the reason is because you're kind of always playing this whack-a-mole game with the API. Every day the Slack API, the Slack platform deploys multiple times. And sometimes a request or a response might contain more data or less data than you expected than the last time. And this is natural. A lot of people have gone about solving this problem by building mock objects to put inside their application when they're running in test mode. Now that's a completely valid approach and there's nothing wrong with that. But when I started thinking more about the problem of what was actually going on, I thought there was room to try and describe a new solution to this. And the team got together and we worked on that solution and the embodiment of that solution is our tool called Steno. Steno is a testing framework that allows you or it's actually a testing helper, sorry, that allows you to that embraces this idea that the Slack platform is constantly changing. So it flips the conversation from how do we get great mocks and make sure that they're in sync with the platform to how do we make it as cheap as possible to record and replay requests that are coming out of Slack API so that when inevitably the Slack API's values change, it's super quick and easy for us to patch our tests and to make sure that everything still works. So that's what Steno does. Steno is programmed to record and replay incoming requests coming out of your app as well as requests coming into your app from Slack. Now, I'm going to be honest with you guys as the audience and say that we had this amazing demo and backstage certain things stopped working. But what I will be able so I won't be able to run Steno for you here, but what I will be able to do is to walk you through some of the test code that in a sample app that uses Steno successfully today. So what Steno gives you is a directory full of scenarios. And a scenario is basically sorry, it gives you a directory full of scenarios and within each scenario there are a directory of interactions. And an interaction is basically one HTTP request and HTTP response in a really plain readable format. You can always come back and hand edit these later. You can try out new things and new behaviors that you can't even reproduce in the wild just by jumping into the scenarios and making those changes for yourself. After you run Steno in record mode, you're going to want to write some tests. Now, this is not as hard as it sounds because your app is already doing the work. All you really have to do is make some substitutions around what tokens you're using and what URL you're sending your request to. So in this case, what I've done is I've just made sure that I've set my environment variables to a fake token and hard coded in some URLs that I can use for this test case. And then I need to start Steno up in replay mode. So the way that it works is in replay mode, Steno will read from that directory of interactions and load them up in sequence and say, hey, I've got to replay this first interaction. And that's actually a request coming out of Slack into the app. So it will go ahead and send those requests to your app. It will also wait for requests coming out of your app. And every time any of these interactions run, it's keeping a running history. So in order to keep that history accurate, what you'll have to do is to tell Steno using its control API when to start and stop a specific scenario. The control API is nothing more than a couple of restful endpoints. In this test case, I've wrapped it in a little helper method. But as you can see, there's just a port that Steno is listening on, and I just call start on it with the name of the scenario as a JSON object. When I'm done with a test, all I do is do the same, except I call stop. And after I stop a test, I'll end up back with a payload that looks a lot like that actually describes the interaction history that actually occurred. So my code here, right after I'm done stopping the replay, I have an object called history. Within history, there is some metadata about the requests, including how many incoming requests were matched or were unmatched during that time. It's a really good idea at the end of your test case to just make sure both of those values are zero. Then you're absolutely sure that there wasn't anything in that test that didn't actually run. In addition, you should always try to test out the actual behavior of your app. So if you wanted to make sure something was added to your database, go ahead and write the code to make sure it was added to your database. You can also reach into the specific interactions within a test case, within, sorry, the history, and find out if the message looks like what you expect it to look. In this case, this app is assigning tickets to users who interact with it. And I can actually reach inside the text of that request and make sure it has the exact copy that I was hoping for. Can we switch back to slides, please? So Steno is scenario-based testing for your Slack apps. It exists as a proxy between your app and Slack, and it records your app's interactions in realtime. But we only want you to use that in development. We would never want you to do this in production. Those recordings are then reused as the scenarios in which you conduct replay, and that happens at test time. When you're replaying these behaviors, you want to be able to verify that the results are what you expect. And new in version 1.2 of Steno, we have just released a new command line option on the tool itself called replace tokens. So the natural next step, once you've developed your test suite, is to check that code back into your repository and make sure that on every check-in, your continuous integration verifies that the behavior is still correct. But we would never want you to commit sensitive data like Slack tokens or other API tokens. So what we've done is to take that problem out of the equation, and while you're in record mode, we substitute fake tokens into those interactions for you. So thanks for coming to this session and hearing more about the tools that we develop here at Slack to make your lives easier as developers. I hope you have started to feel like you're leveling up a little more, started to feel like you're more of a power user of the API. And sooner or later, you're going to be that invincible Mario moonwalking through Goombas. Thank you.
[06:24:15] Speaker 23: Welcome to Designing APIs for Evolving Products. My name is Brenda Jin. I'm a staff engineer on the developer platform at Slack, and I'm really excited to be here talking to you all today. So why did I want to talk about this? Most API design resources give you recommendations and suggestions for greenfield opportunities. So a lot of the literature we have is about designing APIs for the very first time, when you get to make all of the decisions and mistakes you want to make. But there's not a lot of times in a product's lifecycle where this is actually applicable. How many of you have had careers where you designed APIs for greenfield opportunities exclusively? Oh, I got one hand. I didn't see any other hands, though. Most of the time, we are actually balancing, making changes while balancing the decisions we've made in the past with where we want to go in the future. And this is really where a lot of the API design challenges come up. It's reconciling the decisions we made a long time ago for a different context and a different problem and making sure that they still work with all the new problems we're encountering and all the new things we want our users to be able to do. So we've actually learned a lot about evolving APIs for growing products. And Saurabh Saini, one of my coworkers who's with me, he'll help answer a Q&A at the end, and Amir Shavat, and I've actually written a book about this. So check it out if you want to read more. It's coming out in September. So what's on the agenda today? I'm going to talk about who's on the developer platform team at Slack and how that's structured so you have a little bit of context about who makes what kinds of decisions and who's designing APIs at Slack. And then I'm going to give you four tips for designing APIs for growing and evolving products. All right. Where does platform fit in? Whoops. This is supposed to be a tree. So we're loosely, well, we're organized by product development groups at Slack. So developer platform is one of the product groups. But there's also other product development groups like core product, which works on files and messaging, enterprise, working on the enterprise grid products, and a couple other groups which aren't featured here. And who's on one of these product development teams? It's actually a lot of people, and specifically a lot of people for the developer platform team. We've got web engineers, mobile engineers, product managers, design. It's very cross-functional. We've got QA, customer experience, developer relations, marketing, business development, and probably more functions that I couldn't fit on this slide. And who all is involved in API design? Everyone except for marketing. So we're constantly getting feedback from our developers from so many different sources. We get people writing in for support, and we get that feedback. We get feedback from engineers across the organization. And it's just coming in from all over the place, which is so awesome on a cross-functional team because we can get feedback from all different places, and that feedback informs our design decisions. So let's talk about four tips for designing APIs for growing and evolving products. Tip number one, never assume what developers are doing. Now, you might think this is a really basic tip, but I want to tell you a little bit of a story about how we made an assumption that we didn't even realize was an assumption. Until something went wrong. So in 2015, we decided we're going to make our payloads really consistent. We had this one field, the bot ID field, and sometimes it was present and sometimes it wasn't. And we decided, hey, this field, it should always be present. When we have a falsy value, we're going to set it to null. No more of this sometimes there, sometimes not there. What we didn't realize is that there was implicit logic when the field was unset. And developers had taken advantage of the fact that sometimes this field was unset to build applications. So when we made this change and we said this field is always going to be set, we actually broke those applications. So when we're sending JSON, we have no idea which fields are actively being used by developers. And because our product is different from our developers' products, our code base is different from other developers' code bases. So what seems like a totally innocuous change because falsy is falsy in our code base could be devastating in another code base. And that change can actually break apps. So the second tip is lean into consistency. I talked in the beginning about balancing the past with where you want to go in the future. So you might have made design decisions in the past that you regret. Does anyone here ever made one of those decisions, a design decision that they later regretted? Okay. I see some nods for those people who don't want to raise their hands. You might be super tempted to fix these mistakes in later releases of your APIs and later changes. But the result is that now you've got two names for a field, not one. You've got two paradigms, not one. That's a lot of overhead for developers to manage. So say you have 2,000 apps in your ecosystem, and each one of those apps has to fork their code for both the old name of a parameter and the new name. That's now 2,000 more forks. And you know who pays the price for that? It's actually the developers. And so it's actually better to be consistent for cosmetic or superficial changes, even if the old ways of doing things are eyesores, because it's really hard for new developers to come into a system where there's different names for what they think of as the same thing. Tip number three, an API is more than its endpoints. Earlier this year, we released a new rate-limiting system. We decided to roll out a simpler, more understandable system for developers. So while a majority of the apps were actually going to hit fewer rate limits, there were some apps that were going to be rate-limited more. Although this isn't considered a change to the inputs, outputs, or effects of an API call, we really had to think about the backwards compatibility implications of making these changes to access, because from a developer perspective, if I'm continuing the same behavior that has always worked, it shouldn't ever break, right? Like it would be a really bad experience all of a sudden to get rate-limited for the same amount of traffic. So an API is more than its endpoints. From docs and authentication to SDKs, there's so much that goes into exchanging and sending and receiving data on the internet. Stability doesn't just come from the ins and outs of an API. It comes from everything around that API that supports developers. And consistency and stability should be a part of all public-facing aspects of an API, including the access patterns that developers are already using. So my final tip, tip number four, is to expect change. In 2017, we launched the Enterprise product, and teams started migrating. To launch the Enterprise product, we had to fundamentally change the architecture and infrastructure of Slack's web application. Now this is a really scary thing to do sometimes, and you have to make really tough decisions about how you're going to make sure your product scales. In that process, we decided to change the way that user IDs worked inside of Slack. And this was a change we had to make in order to support the type of product that we wanted to have and the type of experience that we wanted our customers to have. Now if we had just let this change go through the API, there would definitely have been applications that got confused about why one user that they'd stored state with all of a sudden had a different ID or appeared to be a new user. So when things do happen and products do change, it's really important to put the developer experience first. And when possible, and it's not always possible, but when it is, it's worthwhile to mitigate these breaking changes. So what we did at Slack was we actually built an editor that would translate these IDs back and forth so that app developers could continue to receive a consistent ID for the users that they were interacting with. So in sum, these were the four tips. Never assume what developers were doing, lean into consistency, an API is more than its endpoints, and expect change. If you have any questions, you can follow me on Twitter, Cybernetic Love, or I'd actually like to invite Sarab Saini, one of the co-authors of the book and fellow engineer on the developer platform up to the stage and open it up to you for some questions from the audience. Thank you. Thank you very much. We have a mic coming.
[06:37:18] Speaker 24: How do you balance bringing things to market quickly and taking consistency into account between APIs?
[06:37:28] Speaker 25: So the question is, how do you balance getting things to market quickly and balancing the consistency?
[06:37:36] Speaker 24: Yeah, consistency over time and consistency between products.
[06:37:42] Speaker 23: So I think that's a question we ask ourselves every day on the developer platform team. And it's really, it can depend on how your code base is structured, how your organization is structured. But we're always wanting to make sure that we have the right velocity of change with the quality that our developers come to expect. And that ratio or that negotiation might actually change over time. So in the beginning, if you've got a lot of developers who are really flexible, maybe it's okay to just create all the features that they want really quickly. And if they're willing to work with you, that's fine. But at a certain point, there's a lot of developers relying on you now to do business. And I think the balance shifts a little bit. So you have to be way more careful about stability than maybe you did before.
[06:38:31] Speaker 25: I think one of the things I would like to add is, one of the things we try to do as we launch new features is have some beta partners. And as you see today is like when we launched a new feature, we already have a few apps who tried those features and actually built on top of it. And through that process, we get a lot of feedback, which we use back in updating our product and making sure things are consistent. So we essentially follow a very iterative cycle of development, which helps us keep our speed up at the same time, as much as possible, keep things consistent.
[06:39:07] Speaker 1: Yeah.
[06:39:08] Speaker 23: And we've actually evolved our design processes over time because that feedback is so important. We also now have, and we didn't necessarily have this before, and we're still working on the best way to do this, but we're adding feedback earlier and earlier into the design cycle. So more and more, it's a standard for us to get internal feedback before we make big API changes and actually get it in front of more people before the whole product is developed.
[06:39:49] Speaker 26: As far as possible. So there's an inevitable need of introducing breaking changes to the API. What is the approach you guys are doing at Slack? Is it like versioning or formatting?
[06:40:01] Speaker 25: So your question is, what are we doing to handle breaking changes to the API? For instance, versioning. So I don't know if you went around the roadmap booth, and one of the items we have is around versioning. And that is one of the items which we are exploring right now. It's something which is in our long-term roadmap, and we are exploring. So that is definitely one of the areas which we are looking into.
[06:40:35] Speaker 1: Yeah.
[06:40:35] Speaker 23: In the past, we've done things like trying to namespace new suites of APIs, trying to fix things going forwards, and I think we really need to think about how that's going to work best for our developers, especially for new developers. I think for existing developers who already have apps and maybe they're not changing them that much, it's okay if the API just doesn't change as long as everything's working. But for new developers coming in to see a lot of inconsistency, especially if something has more than two different names, and it's more than two fields that have different names, it's not easy for them to jump right in and start. What's the name of the book you're writing? What's the name of the book we're writing? The early name is...
[06:41:37] Speaker 25: Designing Web APIs.
[06:41:41] Speaker 23: Let me go back all the way. Whoops. Designing Web APIs, building APIs that developers love. And it's... If you're interested, it's available for pre-order on O'Reilly as well as Amazon.
[06:42:07] Speaker 13: Yep. Hi. So what's your view on versions of the API, like v1, v2, v3, versus being able to, you know, improving, adding changes without, you know, being backwards compatibility? That's my question.
[06:42:24] Speaker 23: Yeah. So one of the things that we're thinking hard about as we consider versioning is how to give developers a better experience while not being disruptive to our own workflow and to developers. So making sure that if we do versions, developers can do that in a way that works for them and as seamlessly as possible. So that's one of the things that we are exploring right now.
[06:42:47] Speaker 25: Yeah, we are exploring different ways how we can do versioning at this point. There are a lot of different ways people have done it before. And we are trying to figure out what would work best for the Slack API. If you folks have feedback, please do share with us. And we would love to learn more what has worked well for you in terms of versioning previously.
[06:43:13] Speaker 7: I think we have time for two more questions.
[06:43:19] Speaker 13: Sorry, and I have one more specific about Slack. I think something about Slack is that you guys have the web API, then you have, like, the events, and then you have, like, the slash commands, and then the interactive buttons. And then if you look at all those payloads, you know, they're not consistent. So how do you, you know, I think that's the other problem. Like, how do you manage consistency at that level when you have so many different products and can imagine different teams and different schemas? But, you know, for us, you know, for the developers, we'll lobby the old kind of, like...
[06:43:49] Speaker 23: Yeah, that's definitely one of our challenges, which is why I recommend consistency over correctness. Like, even if you think that payload before was like, oh, I don't think I like the name. I think we've learned kind of the hard way that it's really challenging for developers. Like, one off these decisions seem like a good idea. But then two years go by, and you're looking at a lot of different types of payloads and names for things. And it is really hard for developers. And that consistency is one of the motivations for why we're exploring versioning, to see if we can give developers a better experience as far as consistency.
[06:44:25] Speaker 25: So just to add specifically in the outgoing payloads, we have these inconsistencies where something is JSON, something is application form encoded. And that is definitely one of the things that we want to fix. And that is definitely one of the things that we want to fix. And versioning could be a way how we may end up fixing it. Or there are definitely other ways how we could address some of that. But eventually, like, the feedback we have heard is, like, people want everywhere full JSON. And that's what we want to send in all outgoing payloads eventually, and have you an option to get it as full JSON. At the same time, we want to make sure that we don't break any apps. So we need to balance these two things together.
[06:45:17] Speaker 23: Last one. Cool. Well, come find us after if you have any other questions. And we're so excited that you were able to join us today. Thank you.
[06:45:26] Speaker 25: Thank you.
[06:45:31] Speaker 27: Thanks, everybody. And just before you get up, I want to let you know, this is our very last breakout session of the first ever SPEC conference. So please stick around if you're going to be in this room.
[06:48:33] Speaker 1: Thank you. Hi.
[06:55:27] Speaker 28: Hi, everybody. First of all, I would like to thank you. Thank you very much to Slack for welcoming me in this very cool event. I have to say that I'm very excited to make this talk at SPEC with Slack in San Francisco. That's why I've made a long trip to join this meeting. Actually, I have traveled all around the globe through Iceland, very close to the North Pole, by plane, okay, from France. Yes, I'm French. I hope you like my exotic accent and that you will understand what I'm talking about. Hello, I'm the CEO of MailClark, the French startup of nine people based in Lyon, second city after Paris, very close to the French Alps. I don't want to bother you with MailClark, but in a few words, if you consider that Slack's goals are to improve internal communication in your team, MailClark is a Slack bot whose goal is to improve external communication. We allow people using Slack to send and receive emails to the outside world, your customers, your lawyer, and to do that without leaving Slack. But actually today, I'm here to talk about onboarding. It won't be a theoretical lecture about onboarding. I just want to share with you our experience about three years of continuous iteration. I'll show you five keys, five key iterations, excuse me, with our onboarding process, and each time I try to say what was a success and what was a mistake from the point of view of user experience. And I hope it will be useful for you as a software developer. We developed Klebel.io, our first Slack app in 2015. Unfortunately, it was the result of a pivot because we had previously developed another application, Klebel.com. We have always been convinced that email is a very powerful tool, so we wanted to reinvent email groups for companies in order to reinvent collaboration. We were very ambitious, but at this time, it was already clear that Slack was the best company for reinventing collaboration. And you know, it's better to be a friend of Slack rather than to be a competitor of Slack. But we were still convinced of the power of email. We then decided to pivot and to launch Klebel.io, which was a software that could allow you to install an email group in a Slack channel. So here is the first screen of our first onboarding in August 2015. This is the screen you could see after you push the button, add to Slack, after OAuth. For technical guys in the room, I guess we have some. So we had very simple software. So we absolutely wanted to have a simple onboarding. Onboarding at this time was made in a browser, not in Slack itself. Because at this time, it was easier for us to do what we wanted to do in a browser because Slack wasn't fully featured as it is now and we had more freedom to do whatever we wanted. So here you can see that the user was invited to choose the Slack channel where he wanted MailClack to be present, to fill the emails of the external people he wanted to communicate with, and to choose the subject appearing in the subject of the emails. And last is language. That's all. The email group was ready to go. After clicking, we were now back to Slack. And at this step, everything was ready for sending every message written in the Slack channel to an external list of emails and receiving the answers. You could then mix a conversation between pure Slack users and pure email users. You can see, for example, the beginning of a conversation where Pierre, working in Slack, invited Elisabeth from England to participate to a debate. Elisabeth uses email, of course, and she can now exchange his royal point of view with the Slack team despite the fact that she will probably never go into Slack. Well, maybe one day, I don't know, in fact. What were the results of this first onboarding? Well, we can say, in fact, that it was our first success. The process was a fluid experience. A good point is that it was a one-step setup. People don't like configuration. The shorter, the better. Secondly, there was almost nothing to learn to get started. Once the setup was made, it was almost self-explaining. I have to confess that in addition to the onboarding, we always push our bot, MailClark, to explain very carefully what is it precisely doing. Oh, my God. Whoa. So terrible. And three, the localized experience, it's always better when users can work in their own language. It was in English and in French. And to give you an order of magnitude, we had at this time 250 teams onboarded with this process. But a lot of them vanished away. In fact, the first week turn was not less than 19%. Not bad, but really too much if you want to make serious business. So you can see here some reactions from our first users. First point, we at MailClark, we are very happy to have a setup in a browser. But the opinion of some of the users wasn't the same. Just take me to Slack, they said. And more serious, the software was considered too basic. It was just a little more than a proof of concept. We then still had the hard work to do again. Even for us, in fact, Klebel.io was too basic. We already wanted to offer a fully featured email bot. We then gave up the brand Klebel and we launched MailClark. We launched MailClark. MailClark is a play on words with email and clerk. The guy with the mustache is the clerk of email. I hope you understand this wordplay because it has been created especially for American people. So we have a new bot. We needed a new onboarding, of course. This time, since the software was a little more complicated, we decided that we had to be very didactical. To really teach users how to get the maximum out of MailClark. We then introduced the onboarding process with what we call the test emails channel. That is a channel you could, in a way, call sandbox, a place where you can play without any risk. So right after we add to Slack, after OAuth, if you prefer, users were displayed a very simple web page. But this page was only here for a confirmation that everything was ready. Just had to click on the button, you can see, and you were redirected to Slack. Here we are in this channel, which is created mostly for the guy we call the champion, the team leader. And here takes place a conversation between MailClark and the champion. You can see here the first step, how to send an email from Slack. As we introduced a lot of new commands, it was very important to be didactical, precise, very step-by-step. You can see on this slide that MailClark said very precisely what the user had to type to make it work. And it worked. What was the result of this onboarding process? Good point. It was very integrated in Slack. We wanted it to be quite invisible. Objective, zero web interface. People wanted to stay in Slack, they could stay in Slack. Secondly, we really engaged users by getting them to practice. In fact, the users were nearly obliged to learn. MailClark School was a very classical school. You could learn step-by-step at your rhythm like a young student. And three, a dedicated channel is a good sandbox because you feel comfortable. You're not afraid of making mistakes. That's very important. It's not a shame of asking for help. You're not exposed to the rest of your team, and people appreciate it. On the other side, many people found that we had gone too far in the Slack integration. And the apparition of new commands wasn't a good news for everyone. You can read that in the reaction of some users on the slide. In fact, well, it's difficult to make everyone happy. The software in fact was richer, but we didn't succeed to keep the user experience simple. And regarding the complete integration to Slack with no interface, in fact, we've been too purist. In France, we say, plus royaliste que le roi, more royalist than the king himself. That wasn't a good news for the population of our little kingdom. As a result, we left it at a terrible pace of 25% on the first week. We had lost fluidity. It was too complex. We then made a third iteration based on the Slack slash invite command. We first removed some of the commands we were so proud of having invented before. And for the inboarding, now you just have to invite MailClark wherever you need it. Wherever you need him. I don't know if I have to say it or him. So here is the page after the Add to Slack button. In fact, it was a two-ways onboarding this time. You can see that we send people back to Slack and suggest them to invite MailClark in the channel of their choice. But in the same time, we used the direct message to give support and help to users. You learned to use MailClark in a series of direct messages with MailClark that could teach you all the possible use cases. You can see in that list that MailClark could now do a lot of other things than just sending emails to Elizabeth. In fact, direct messages is also a good place for teaching people how to use your software. Because again, users don't want to make mistakes in a public place. That's really nothing worse than that. So what results for this onboarding? A lot of users had a native feel. Just inviting the bot was a good thing. It made a big simplification. But on the other point, excuse me, the focus on use case was very positive as well. In fact, you always gain to be user-oriented rather than technically oriented. And last but not least, there were less commands but not less feature. They were just simpler to use because they were replaced by pop-up likes. In fact, we didn't want to be purist anymore but rather pragmatic. And users seemed to like it. As a result, the first week churn was much better, 18% you can see on the left. But as you can see, our process was simplified but it wasn't simple. And a problem appeared we didn't anticipate it. In fact, you can see a bunch of user reaction that shows that a lot of people wasn't able to invite Mail Clack, you know, three of them and we had reaction like that every day. In fact, we naively thought that all Slack users knew how to use Slack commands. That's not the case. It was a mistake. So be careful about that. So let's go to another iteration, number four. A lot of things appear at this stage, the concept of inbox and the fact that we consider now that the users firmly prefer clicks of the commands. We also introduced new services such as the possibility to communicate with your Facebook page and your Twitter account. And a little detail, we started to monetize. Here is the onboarding. No more commands, just clicks. And now the onboarding is 100% made in Slack with message menus. You just add a menu that actually allowed you to create an inbox that invited Mail Clack in the channel of your choice. And everything was made automatically. Just after that, you were invited to choose which service you wanted to connect to your new created inbox, email, Twitter, or Facebook. You can see that at this time, we were able to use the newly created Slack buttons and you even add a hamburger menu. We were very proud of that. The results, very good point is that we made the most of buttons and menus and the fact of removing commands whenever possible was really good news for users. The fact of needing a little Slack know-how is positive too. Every Slack user is not a developer. I repeat it, but people don't like to write lines of code when they are using a software even though they are used to it. The most natural way to interact for a lot of people is probably clicking, that's all. So with buttons and menus, we succeeded to get more interactions and after all, to keep complexity away. That was a success. We are now 9,600 teams on board. But the bad side is that the abstract concept of inbox was too complicated to understand and that actually due to the use of buttons and menus, we were too much integrated to Slack. At this time, we didn't have our own user interface and I must confess that a lot of users were very troubled as you can read here in this reaction. As a result, the churn has raised to an unusual rate of 33%. Too abstract, too invisible, in fact, to exist and to be understood, don't act like a god. Don't live too high in the clouds. You have to prove your existence every day down to earth and by material and simple evidence. And now last iteration, number five, the setup wizard, I call it return of the UI. I could have said back to the future, excuse me for this bad wordplay, but in fact, what I want to say is that we came back to a browser interface, a setup wizard of our website. This was finally the way to exist and to be understood more clearly. Because in the first iteration, we keep people in the browser for setup, as I said, and we simply ask them to choose which service they want to connect to their Slack workspace. You can see that we added some new services like connecting a Gmail account, for example. Then if you want to connect, let's say your Facebook page, you get to pick the right Facebook page and after this page, which we don't see, you then choose the channel you want to connect. In fact, it's really a step-by-step wizard and you have no toolbar, no possibility to going outside the process. In fact, it's a tunnel. And this tunnel leads you to the conclusion that seamlessly the channel of your choice is now connected to the service of your choice. And we only send users back to Slack once things are completely set up. Final results, my favorite chart. You can see on the chart the cohorts of active teams using MailChimp every week since the beginning with the numbers of iteration. You can see on the right part that with the iteration number five, we obtained a growth as important as in our early days. The slope is very steady and very good for us. In fact, we succeeded to simplify the tunnel works and users react in a very positive way. I have to say that the result in monetization follows the same curve. So we are arriving to the end. I won't give you a definitive conclusion about onboarding because as you can see in this slide, we still have people estimating that the onboarding is still complicated. My real conclusion, it's that we still have to work and to iterate on onboarding again and again. It's never finished. But I hope that you will have discovered some of the mistakes you could avoid in the future and discover some good practices to make the life of your users easier during onboarding. Thank you for your attention. Merci. I won't take any questions. If you have some questions, just come to me and I will answer with pleasure. Thank you.
[07:16:07] Speaker 7: Thank you again so much, Anthony. Another round of applause. Thank you. And we wanted to extend a huge thank you to all of our external speakers who came and spoke at SPEC today. We had six talks that were given by people who had relatively short notice. We closed the CFP about a month ago. So we really appreciate your willingness to share all of this important information that other people can really use when they're thinking about building their own onboarding. So the day is not totally over. We have a reception now, and we hope you'll stick around, take the time to chat with more Slack staff who are coming on deck to talk to you. We've got more of our platform engineers here, our platform PMs, and one another. There are a lot of you who are building really cool things, and we have been really excited to learn from you today. We hope that you'll get to have similar conversations. Last piece is we're really excited to hear your feedback about today. In a couple of days, you'll be getting an email from us asking you for what you thought about the event. We know that we still have a lot to learn about how to do this better, and we are always interested in making next year an even bigger, even more interesting day for you. So please share your feedback with us, whether it's in person or through that email, and we hope to see you at the reception. Thank you.
[07:17:17] Speaker 14: You think you hurt me, but I promise I was letting you.
[07:17:49] Speaker 1: They say we're all one. We're all one.
We’re Ready to Help
Call or Book a Meeting Now