For a brief introduction to Enterprise Grid, start here.
Working with Enterprise Grid means that no matter what your app does or which APIs it uses, it's more likely to encounter an enterprise-related quirk.
Bot users are more likely than other integration points to require additional work for exemplary performance on Enterprise Grid workspaces.
We recommend reviewing your app's current assumptions, operations, and configuration. Maybe even if you aren't planning to work with Enterprise Grid.
Read on if:
Really, if you're using any aspect of the platform at all and want to support Enterprise Grid — this guide is for you.
Workspaces don't always start out part of an Enterprise. Thanks to mergers, acquisitions, and simple evolution a workspace may become part of an Enterprise Grid.
And just as a user that's part of a workspace becomes part of its workspace's Enterprise Grid, that user who was once a duplicative singleton at Workspace A and Workspace B, with no way to reconcile shared identity, becomes a cross-referenced entity you can recognize consistently across workspaces.
There are two ways to determine whether the workspace you're working with is part of an Enterprise.
The easiest way to determine whether your app is dealing with a workspace that's part of an enterprise organization is by observing enterprise_id
attributes scattered through object types in Web API methods & events.
Look for enterprise_id
in auth.test
, the most conspicuous and eternally useful location it surfaces in.
We recommend using this method after acquiring an OAuth token. You'll want to poll it regularly for all workspaces you service, as workspaces migrate to Enterprise Grid.
An enterprise_id
is constant and unique.
Other places to find enterprise_id
(often paired with enterprise_name
):
team.info
rtm.connect
rtm.start
conversations.info
- appears in shared channelsIf you store data, you'll want to warehouse enterprise_id
. Just as you'd never store information about a user or their data without tying it to a workspace first, it's best to associate Enterprise Grid workspace data with its enterprise_id
.
Use enterprise_id
prodigiously in your queries.
If your app is installed on multiple workspaces within an enterprise organization, you may want to utilize that position effectively by grouping data by enterprise_id
and using the new enterprise user IDs as your primary source of truth.
This way you'll easily cross work streams between more than one workspace without exploding at the speed of light.
If you're working with a custom integration instead of a Slack app, you may have a more difficult time understanding whether you're working with an Enterprise Grid workspace or not.
Though you yourself should know whether the workspace you're part of and building an integration for is on Enterprise Grid, there are fewer programmatic signals to interpret and off-the-shelf code may not know how to handle certain situations like shared channels.
Here's one way of looking at the kind of work involved in supporting Enterprise Grid workspaces.
"If there's a steady paycheck in it, I'll believe anything you say."
API | Support strategies |
---|---|
All Slack apps |
|
RTM |
|
Events API |
|
Web API |
|
Incoming webhooks |
|
Slash commands |
|
Message buttons |
|
The first step is to recognize that you're working with an Enterprise Grid workspace. Then you just need to teach your app a few new tricks:
enterprise_id
in auth.test
and channels.info
. Consider it a strong signal you may encounter shared channels, novel IDs, and different API responses when working with this workspace, and it might be related to another workspace that has or will install your app. You'll want to store it along side other data about its workspaces.users.info
to look up information about user IDs belonging to a different workspace on the Enterprise Grid, ad hoc as needed.If your app or integration is used as part of a shared channel, it will encounter users it is not aware of.
Typically, apps build their "known universe" of users by consuming the users
collection in rtm.start
or by using users.list
. You won't find users from other workspaces in the payloads of these methods.
To find users from another workspace on an Enterprise Grid, use users.info
and query by their "foreign" user ID.
Of course, many apps need only a user's ID and don't need additional information to operate.
Not only will you encounter user IDs belonging to other workspaces, but also the artifacts of their existence and workspace cross-pollination:
If your application is installed by multiple workspaces of an Enterprise Grid and then used in a shared channel, it's possible that your bot will receive multiple RTM events for the same message: one for each of the workspaces you're installed on.
If your bot doesn't de-duplicate the messages by looking at the ts
value of each message, you might interpret each one independently and reply to them, adding noise a conversation.
Look for the source_team
message field to identify the Enterprise workspace the message originates from.
To help you understand the different scenarios in which you'll receive multiple messages, let's imagine the following situation:
Condition | Result |
---|---|
User from Workspace 1 sends message |
|
User from Workspace 2 sends message |
|
User from Workspace 3 sends message |
|
One way to handle duplicate messages is to make one of the workspaces in the shared channel (that your app is installed on) responsible for handling all messages coming from that shared channel.
To do this, you'll need to listen to the channel_joined
event when your bot is added to a shared channel. The metadata included in this event will tell you which workspaces are part of the shared channel.
Of the workspaces in the channel that your app is installed on, you'll want to pick one and save both the channel ID and team ID in your database. From that point on, you can look up the channel ID for every message you need to respond to and determine which workspace's RTM should respond. Alternatively, you can ignore all messages coming from a workspace that is not the same as the workspace your app is installed on. While simpler to implement, it will prevent users on workspaces that haven't installed your app from being able to interact with your bot.
Direct messages work much like channels: private conversations between two or more individuals spanning multiple workspaces within an Enterprise Grid result in RTM API streaming one message for each of your open websocket connections.
Your app can be the target of a direct message from another workspace across the grid. You never know when a user might want to collaborate with your bot.
These messages will also contain a source_team
attribute when perspectively appropriate. The source_team
attribute contains the workspace within the Enterprise Grid that the message originates from.
As with channels, when connected to multiple websocket connections on behalf of workspaces in the Enterprise Grid, you can receive redundant message deliveries. They will have the same ts
value.
Congratulations! If you're using the Events API, you do not have to worry about duplicate messages from shared channels. We'll only send one event regardless of how many workspaces within the organization your app is installed on.
Look for the authed_teams
node that arrives as part of the "wrapper" around delivered events. It contains a collection of team IDs within an organization that this delivery is on behalf of.
Here's an example payload of a shared channel's message being delivered on behalf of multiple workspaces:
{
"token": "ecto1EZslimer",
"team_id": "T123ABC456",
"api_app_id": "A123ABC456",
"event": {
"type": "message",
"user": "W123ABC456",
"text": "Now _we_ are the real ghostbusters!",
"team": "T123ABC456",
"source_team": "T123ABC456",
"user_team": "T123ABC456",
"user_profile": {
"avatar_hash": "g56821b98743",
"image_72": "https://...png",
"first_name": "Patty",
"real_name": "Patty Tolan",
"name": "patty.tolan"
},
"ts": "1485371714.000002",
"channel": "C123ABC456",
"event_ts": "1485371714.000002"
},
"type": "event_callback",
"authed_users": [
"W3MBP5799"
],
"authed_teams": [
"T3NHPD4J0",
"T3MQV36V7"
]
}
In this example, the application is installed on two workspaces in an Enterprise and is party to a conversation in a shared channel.
The message originates from team T3MQV36V7
and is delivered as a single event for both teams, including T3NHPD4J0
.
In most cases, an Enterprise Grid is formed by combining multiple independent Slack workspaces together. During this period of time where data is migrated and made compatible with Grid's organization structures, Web API calls, RTM API connections, Events API, and other platform interactions may be unavailable, both for users and your applications.
On the Web API, you may encounter the team_added_to_org
error during this time.
Migration time varies depending team-to-team and organization-to-organization. Practice an exponential backoff strategy when encountering errors to help manage these periods by attempting connections at incrementally increasing rates: 1 second to 3 seconds to 10 seconds to 30 seconds to 1 minute, and so on.
To best plan for migrations, subscribe to grid-related app events as part of the Events API. Using these events, your app can pause and resume activity as appropriate.
If your app has disabled the translation layer, use migration.exchange
to receive global user IDs for any of your stored local user IDs.
You'll find user objects on Enterprise Grid workspaces now have an enterprise_user
attribute, containing a hash of additional context about the user in the larger Enterprise Grid organization.
You'll find:
id
- this user's ID, which might start with U
or W
enterprise_id
- the unique ID for this particular Enterprise Grid organizationenterprise_name
- the name of this umbrella organizationis_admin
- a boolean value indicating whether this user administers this Enterpriseis_owner
- a boolean value indicating whether this user is the owner of this Enterpriseteams
- an array of team (workspace) IDs within the containing enterprise organization that this user belongs toWithin an Enterprise Grid, all users have a single, global ID beginning with either the letter W
or U
. Whether it's a U
or W
, the prefix doesn't indicate anything in particular.
We'll automatically convert references to a user's previous, pre-Enterprise-migration ID to their singular Enterprise ID. This allows your app to remain backwards compatible for users you've identified on a workspace before the days of Enterprise Grid.
Users created after a workspace became part of an Enterprise have no pre-Enterprise-migration ID.
Disable the translation layer by navigating to application management for your app and finding the User ID Translation panel.
If you need to update local user IDs you've stored in a database or in other ways, first use migration.exchange
with the relevant user or bot tokens to receive global user IDs in bulk.
As with all Slack apps, installation and ownership of apps is on a workspace-basis. Internal integrations that are locked to a single workspace cannot be installed across an Enterprise Grid.
Find out more in our internal integrations documentation.
Building properly for shared channels or enterprise grid requires experiencing the unique constraints and opportunities yourself.
If you don't already have access to a grid of workspaces, please complete the form below to request a sandbox. We'll get back to you as soon as possible.