Simulators
Guests and Slack Connect
A workspace can hold guests, people with limited access such as a freelancer, and Slack Connect channels shared with another organization’s own workspace. A guest’s own token sees only the guest’s channels and the people in them. In a shared channel, your bot reads the other organization’s members, who each carry their own team. In design_studio:
- Mina Okoro (
UWDC0000037) is a single-channel guest in#proj-harborview-dental. #ext-harborview-dental(CWDC0000051) is shared with Harborview Dental (TEXT0000001).- Kim Ross (
UEXT0000002) is one of Harborview Dental’s contacts.
curl -s -X POST "$RYSTIC_URL/_rystic/scenario" -d '{"name":"design_studio"}' -o /dev/null
curl -s "$RYSTIC_URL/api/conversations.list?types=public_channel,private_channel" -H 'Authorization: Bearer xoxp-guest' -H 'X-Rystic-Actor: UWDC0000037' | jq -c '[.channels[].name]'
# -> ["proj-harborview-dental"]
curl -s "$RYSTIC_URL/api/conversations.history?channel=CWDC0000001" -H 'Authorization: Bearer xoxp-guest' -H 'X-Rystic-Actor: UWDC0000037' | jq -c .
# -> {"error":"channel_not_found","ok":false}
curl -s "$RYSTIC_URL/api/conversations.info?channel=CWDC0000051" -H 'Authorization: Bearer xoxb-local' | jq -c '.channel | {is_ext_shared, shared_team_ids, connected_team_ids, conversation_host_id}'
# -> {"is_ext_shared":true,"shared_team_ids":["TWDC0000001","TEXT0000001"],"connected_team_ids":["TEXT0000001"],"conversation_host_id":"TWDC0000001"}
curl -s "$RYSTIC_URL/api/users.info?user=UEXT0000002" -H 'Authorization: Bearer xoxb-local' | jq -c '.user | {real_name, team_id}'
# -> {"real_name":"Kim Ross","team_id":"TEXT0000001"}
Guests
A guest is a user whose record has is_restricted: true; a single-channel guest also has is_ultra_restricted: true. Act as one with a bound token or X-Rystic-Actor (Identities). A guest’s own token:
- lists only its conversations in
conversations.listandusers.conversations; - gets
channel_not_foundfor any conversation it is not in, a public channel included, fromconversations.history,conversations.replies,conversations.infoandconversations.members; - sees in
users.listonly itself, Slackbot and the people who share a conversation with it, and getsuser_not_visiblefromusers.infoon anyone else; - searches only its conversations’ messages with
search.messagesandsearch.all, and withsearch.filesonly files it uploaded or that were shared into them; - gets
restricted_actionfromconversations.createandconversations.invite. The one exception is a multi-channel guest inviting someone into a private channel it is in, which Slack’s guest roles allow.
Differs from Slack: a guest’s search.all file results hold every file (Search). Slack’s guest roles show a guest only the file history of the channels it can access.
Your bot reads every guest as it reads anyone, is_restricted and is_ultra_restricted included, and every other token keeps its own view. design_studio holds single-channel guests (Greta, Nils and Mina) and multi-channel guests (Theo, Ava, Imani, Sven and Rafael Duarte, UWDC0000038, on the Harborview and Northbank builds).
Slack Connect channels
A shared channel carries these fields:
is_shared,is_ext_sharedandshared_team_ids;is_pending_ext_shared: false;context_team_id, the workspace it is listed in;- in
conversations.infoonly,connected_team_idsandconversation_host_id.conversations.listleavesconnected_team_idsout, as Slack’s guide says it does.
The other organization’s members are in the channel’s conversations.members, never in users.list. users.info returns one who shares a conversation with your token, with their own team_id and profile.team. team.info?team=TEXT0000001 names their workspace.
A message from one of them names their team three times, as team, user_team and source_team. It does so in conversations.history and in its message event, whose envelope still names your workspace (TWDC0000001). A post made as one of them, with X-Rystic-Actor, does the same.
Seeding guests and other teams
- A guest is a
state_userrecord withis_restricted, plusis_ultra_restrictedfor a single-channel guest, and itsstate_membershiprows. - Another organization is a
state_connected_teamrecord (id,name,domain). Its members arestate_userrecords whoseteam_idis that team’s. - A shared channel is a
state_channelrecord carrying the fields above. - A member’s message names their team as
team,user_teamandsource_team.
Not modeled
- Slack Connect administration: invitations, approvals and organization policies (
conversations.inviteSharedand the other shared-invite methods,team.externalTeams.*) are not served. - DMs with external members, a stranger’s
is_strangerand Enterprise Grid’s organization-wide sharing. - A guest’s limits beyond the methods above: posting, reacting or pinning in a conversation it is not in, joining one and opening a DM behave as they would for a member. A workspace preference letting multi-channel guests create private channels is not modeled.
- Measurement: these behaviors follow Slack’s documentation. The measuring workspace holds no guest account and shares no channel with another organization, so no fidelity round has checked them yet.