Slack brings the right people, information, and tools together to get work done. Normally, team members can invite one another to Slack via email invitation. Invited users can accept the invitation to activate their account, but if they don’t, then their team members can’t collaborate with them.
To solve this problem we created Email Bridge: with invited users showing up instantly in Slack to start getting notifications via email. They can even respond to Slack messages using email alone.
Today, Email Bridge helps some of our largest enterprise customers to expand and onboard all of their employees quickly and efficiently. With this feature, it’s now possible to add co-workers to appropriate channels and groups before they activate their Slack account. Some customers use apps within Slack to DM their new team members with onboarding information, which also helps them get up to speed more quickly. When invited people do join their workspace, they have all the information and conversations that happened via email immediately available to them in Slack.
In this post we’ll explore the architecture of Email Bridge and how it works, along with lessons learned while shipping the feature.
Slack before Email Bridge
There are two main ways to invite a user to a Slack workspace.
1. Manual invitations: Small companies tend to use manual invitations to add users to the workspace.
Behind the scenes, an invitation is created for the email address with Name, Team to join and user Role (Full Member, Single-Channel Guest or Multi-Channel Guest) along with a list of channels for them to join. We send an email to the address immediately. We also send a reminder email after 24 hours if the invitation is not accepted.
Once the invitation is accepted. We then create a User entity under the Team with the specified Role. We also add the new user to all the specified channels and mark the invitation as accepted.
2. System for Cross-domain Identity Management (SCIM) protocol: Most of our large customers use an identity management system (such as Okta) to automatically add users to the organization.
With this, a new User entity is created with every request and moves the user to a
pre-provisioned state, which essentially means that these users can not be discovered in Slack. Since there is no invitation, no email is sent to the user.
Once the user joins using their Identity provider, we mark the user as active (we remove them from the pre-provisioned state) and make them discoverable in Slack search.
Slack with Email Bridge
For Slack Email Bridge, we built an interoperability layer to exchange emails and Slack messages. This consisted of three modules.
A. Discoverability of invited users
Since we know that the invitation will eventually be accepted, we created a User entity with a flag that indicates that the user has not accepted the invitation.
With this change, any new invitation to join a Slack workspace creates a new user with a type Invited member. We also mark all the users added via the SCIM protocol as Invited members. Since these users are not active, we exclude them from our fair billing calculations. Once the user accepts the invitation, we simply unset the Invited member flag.
For the client side, we added banners and messages under user information to indicate that they are in an invited state.
We made Invited members visible in search and during
<span style="font-weight: 400">@mention</span>, so they can be added to channels and discussions.
B. Email interoperability service
The primary responsibility of this service is to send email notifications to the Invited members, and when they reply to the email, route the message to the appropriate Slack channel.
Since the conversations in Slack can flow quickly, we don’t want to overwhelm users with one email per message. So we wait for a few seconds and batch messages within a single email body. We add a unique
<span style="font-weight: 400">Reply-To</span> address to the email header in the format
<unique-id>@<domain>.slack-mail.com; which is used to trace back the source of the message on reply. We send the email to the user via AWS Simple Email Service (SES).
C. Email reply
Users can reply to each notification message using the Reply call to action button in the email or simply use their email client’s reply button. This will open an email compose window where users can type in their message.
Sent messages are received by
<span style="font-weight: 400"><unique-id>@<domain>.slack-mail.com</span> address via AWS SES, which sends a notification to Slack via webhook using Simple Notification Service (SNS) with a payload to identify the message.
The email service securely validates the authenticity of every incoming email. It also sanitizes the email body and converts it to a Slack message, preserving most of the formatting. The email service then posts a message on behalf of the invited user to the correct channel or thread.
After completion, here is our architecture for invitation and email notification.
Known unknowns — Expanding the feature to support Enterprise Grid
Slack’s Grid user flow has more complex business logic, with different enterprise-level preferences. This required a careful and gradual rollout strategy to ensure we covered all the cases. We spent more than two months releasing the feature to our Free, Standard, and Plus teams, and once we knew that the feature worked well for those teams, we came up with a gradual rollout plan for Grid customers.
Having a gradual rollout plan really helped us to catch bugs early and address them with minimal impact.
Keep instrumentation at the front and center of the discussion
Changing the core user data model had a major impact on our existing instrumentation. We realized this a little late — some of our data pipelines were not aware of the new type of user. Since we changed the definition of what a user is, it impacted internal metrics and dashboards of user count by a large margin.
Having the instrumentation discussions early in the product development cycle is critical to the success of any feature development.
Turning a proof-of-concept into a production feature
When we decided to ship it, instead of holistically re-thinking the user onboarding flow we added
<span style="font-weight: 400">if the user is invited member → do something</span> statements! Though this made our user workflow very complex for a while, it was a choice we made to deliver the feature to early users as soon as possible. Once we reached a stable product development cycle, we did a rewrite with better understanding of features and their side effects.
Sometimes it is necessary to move faster with what works best at the moment. But always make sure to rethink the choices and clean up the technical debts after.
Our customers are excited by Email Bridge, and we’ve gotten feedback that they also want the email reply feature for existing Slack users. We are currently rolling out this feature to all our existing users. With this release, any Slack notification email related to a user mention can be replied to directly from notification emails.
We are also rolling out some exciting new features that will help us deliver relevant Slack messages and team updates to our invited users. These emails will contain the important messages, new members information, and a list of recommended channels to join. And if this work sounds interesting to you, we’re hiring.
Thanks to Saran Arul, Harshad Saykhedkar, Ninad Pundalik, Ross Harmes, Anubhav Aanand, Matthew Haughey, and Matt Wahl for their valuable and constructive suggestions.