An Async API Definition For The Slack Real Time Messaging API

April 27, 2018
We are working to document different Websocket APIs we've come across using the AsyncAPI specification. The specification is new, and we are just beginning to understand how it all works, and we are learning a lot from the existing work of the contributors to the AsyncAPI project. They've recently added the ability to document event-driven Websocket APIs, that will differ from other message-based, and even SSE streaming APIs. They all share a number of components but have unique needs which the AsyncAPI teams has moved recently to accommodate as part of the machine-readable specification.To help demonstrate what is possible when you document a Websocket API using AsyncAPI, we wanted to share a definition for the Slack Real Time Messaging API they've published as part of their working examples in the Github repository for the Async API specification.
asyncapi: '1.2.0'
info:
title: Slack Real Time Messaging API
version: '1.0.0'

servers:
- url: https://slack.com/api/rtm.connect
scheme: https
schemeVersion: '1.1'

security:
- token: []

events:
receive:
- $ref: '#/components/messages/hello'
- $ref: '#/components/messages/connectionError'
- $ref: '#/components/messages/accountsChanged'
- $ref: '#/components/messages/botAdded'
- $ref: '#/components/messages/botChanged'
- $ref: '#/components/messages/channelArchive'
- $ref: '#/components/messages/channelCreated'
- $ref: '#/components/messages/channelDeleted'
- $ref: '#/components/messages/channelHistoryChanged'
- $ref: '#/components/messages/channelJoined'
- $ref: '#/components/messages/channelLeft'
- $ref: '#/components/messages/channelMarked'
- $ref: '#/components/messages/channelRename'
- $ref: '#/components/messages/channelUnarchive'
- $ref: '#/components/messages/commandsChanged'
- $ref: '#/components/messages/dndUpdated'
- $ref: '#/components/messages/dndUpdatedUser'
- $ref: '#/components/messages/emailDomainChanged'
- $ref: '#/components/messages/emojiRemoved'
- $ref: '#/components/messages/emojiAdded'
- $ref: '#/components/messages/fileChange'
- $ref: '#/components/messages/fileCommentAdded'
- $ref: '#/components/messages/fileCommentDeleted'
- $ref: '#/components/messages/fileCommentEdited'
- $ref: '#/components/messages/fileCreated'
- $ref: '#/components/messages/fileDeleted'
- $ref: '#/components/messages/filePublic'
- $ref: '#/components/messages/fileShared'
- $ref: '#/components/messages/fileUnshared'
- $ref: '#/components/messages/goodbye'
- $ref: '#/components/messages/groupArchive'
- $ref: '#/components/messages/groupClose'
- $ref: '#/components/messages/groupHistoryChanged'
- $ref: '#/components/messages/groupJoined'
- $ref: '#/components/messages/groupLeft'
- $ref: '#/components/messages/groupMarked'
- $ref: '#/components/messages/groupOpen'
- $ref: '#/components/messages/groupRename'
- $ref: '#/components/messages/groupUnarchive'
- $ref: '#/components/messages/imClose'
- $ref: '#/components/messages/imCreated'
- $ref: '#/components/messages/imMarked'
- $ref: '#/components/messages/imOpen'
- $ref: '#/components/messages/manualPresenceChange'
- $ref: '#/components/messages/memberJoinedChannel'
- $ref: '#/components/messages/message'
send:
- $ref: '#/components/messages/outgoingMessage'

components:
securitySchemes:
token:
type: httpApiKey
name: token
in: query

schemas:
attachment:
type: object
properties:
fallback:
type: string
color:
type: string
pretext:
type: string
author_name:
type: string
author_link:
type: string
format: uri
author_icon:
type: string
format: uri
title:
type: string
title_link:
type: string
format: uri
text:
type: string
fields:
type: array
items:
type: object
properties:
title:
type: string
value:
type: string
short:
type: boolean
image_url:
type: string
format: uri
thumb_url:
type: string
format: uri
footer:
type: string
footer_icon:
type: string
format: uri
ts:
type: number

messages:
hello:
summary: First event received upon connection.
payload:
type: object
properties:
type:
type: string
enum: ['hello']

connectionError:
summary: Event received when a connection error happens.
payload:
type: object
properties:
type:
type: string
enum: ['error']
error:
type: object
properties:
code:
type: number
msg:
type: string

accountsChanged:
summary: The list of accounts a user is signed into has changed.
payload:
type: object
properties:
type:
type: string
enum: ['accounts_changed']

botAdded:
summary: A bot user was added.
payload:
type: object
properties:
type:
type: string
enum: ['bot_added']
bot:
type: object
properties:
id:
type: string
app_id:
type: string
name:
type: string
icons:
type: object
additionalProperties:
type: string

botChanged:
summary: A bot user was changed.
payload:
type: object
properties:
type:
type: string
enum: ['bot_added']
bot:
type: object
properties:
id:
type: string
app_id:
type: string
name:
type: string
icons:
type: object
additionalProperties:
type: string

channelArchive:
summary: A channel was archived.
payload:
type: object
properties:
type:
type: string
enum: ['channel_archive']
channel:
type: string
user:
type: string

channelCreated:
summary: A channel was created.
payload:
type: object
properties:
type:
type: string
enum: ['channel_created']
channel:
type: object
properties:
id:
type: string
name:
type: string
created:
type: number
creator:
type: string

channelDeleted:
summary: A channel was deleted.
payload:
type: object
properties:
type:
type: string
enum: ['channel_deleted']
channel:
type: string

channelHistoryChanged:
summary: Bulk updates were made to a channel's history.
payload:
type: object
properties:
type:
type: string
enum: ['channel_history_changed']
latest:
type: string
ts:
type: string
event_ts:
type: string

channelJoined:
summary: You joined a channel.
payload:
type: object
properties:
type:
type: string
enum: ['channel_joined']
channel:
type: object
properties:
id:
type: string
name:
type: string
created:
type: number
creator:
type: string

channelLeft:
summary: You left a channel.
payload:
type: object
properties:
type:
type: string
enum: ['channel_left']
channel:
type: string

channelMarked:
summary: Your channel read marker was updated.
payload:
type: object
properties:
type:
type: string
enum: ['channel_marked']
channel:
type: string
ts:
type: string

channelRename:
summary: A channel was renamed.
payload:
type: object
properties:
type:
type: string
enum: ['channel_rename']
channel:
type: object
properties:
id:
type: string
name:
type: string
created:
type: number

channelUnarchive:
summary: A channel was unarchived.
payload:
type: object
properties:
type:
type: string
enum: ['channel_unarchive']
channel:
type: string
user:
type: string

commandsChanged:
summary: A slash command has been added or changed.
payload:
type: object
properties:
type:
type: string
enum: ['commands_changed']
event_ts:
type: string

dndUpdated:
summary: Do not Disturb settings changed for the current user.
payload:
type: object
properties:
type:
type: string
enum: ['dnd_updated']
user:
type: string
dnd_status:
type: object
properties:
dnd_enabled:
type: boolean
next_dnd_start_ts:
type: number
next_dnd_end_ts:
type: number
snooze_enabled:
type: boolean
snooze_endtime:
type: number

dndUpdatedUser:
summary: Do not Disturb settings changed for a member.
payload:
type: object
properties:
type:
type: string
enum: ['dnd_updated_user']
user:
type: string
dnd_status:
type: object
properties:
dnd_enabled:
type: boolean
next_dnd_start_ts:
type: number
next_dnd_end_ts:
type: number

emailDomainChanged:
summary: The workspace email domain has changed.
payload:
type: object
properties:
type:
type: string
enum: ['email_domain_changed']
email_domain:
type: string
event_ts:
type: string

emojiRemoved:
summary: A custom emoji has been removed.
payload:
type: object
properties:
type:
type: string
enum: ['emoji_changed']
subtype:
type: string
enum: ['remove']
names:
type: array
items:
type: string
event_ts:
type: string

emojiAdded:
summary: A custom emoji has been added.
payload:
type: object
properties:
type:
type: string
enum: ['emoji_changed']
subtype:
type: string
enum: ['add']
name:
type: string
value:
type: string
format: uri
event_ts:
type: string

fileChange:
summary: A file was changed.
payload:
type: object
properties:
type:
type: string
enum: ['file_change']
file_id:
type: string
file:
type: object
properties:
id:
type: string

fileCommentAdded:
summary: A file comment was added.
payload:
type: object
properties:
type:
type: string
enum: ['file_comment_added']
comment: {}
file_id:
type: string
file:
type: object
properties:
id:
type: string

fileCommentDeleted:
summary: A file comment was deleted.
payload:
type: object
properties:
type:
type: string
enum: ['file_comment_deleted']
comment:
type: string
file_id:
type: string
file:
type: object
properties:
id:
type: string

fileCommentEdited:
summary: A file comment was edited.
payload:
type: object
properties:
type:
type: string
enum: ['file_comment_edited']
comment: {}
file_id:
type: string
file:
type: object
properties:
id:
type: string

fileCreated:
summary: A file was created.
payload:
type: object
properties:
type:
type: string
enum: ['file_created']
file_id:
type: string
file:
type: object
properties:
id:
type: string

fileDeleted:
summary: A file was deleted.
payload:
type: object
properties:
type:
type: string
enum: ['file_deleted']
file_id:
type: string
event_ts:
type: string

filePublic:
summary: A file was made public.
payload:
type: object
properties:
type:
type: string
enum: ['file_public']
file_id:
type: string
file:
type: object
properties:
id:
type: string

fileShared:
summary: A file was shared.
payload:
type: object
properties:
type:
type: string
enum: ['file_shared']
file_id:
type: string
file:
type: object
properties:
id:
type: string

fileUnshared:
summary: A file was unshared.
payload:
type: object
properties:
type:
type: string
enum: ['file_unshared']
file_id:
type: string
file:
type: object
properties:
id:
type: string

goodbye:
summary: The server intends to close the connection soon.
payload:
type: object
properties:
type:
type: string
enum: ['goodbye']

groupArchive:
summary: A private channel was archived.
payload:
type: object
properties:
type:
type: string
enum: ['group_archive']
channel:
type: string

groupClose:
summary: You closed a private channel.
payload:
type: object
properties:
type:
type: string
enum: ['group_close']
user:
type: string
channel:
type: string

groupHistoryChanged:
summary: Bulk updates were made to a private channel's history.
payload:
type: object
properties:
type:
type: string
enum: ['group_history_changed']
latest:
type: string
ts:
type: string
event_ts:
type: string

groupJoined:
summary: You joined a private channel.
payload:
type: object
properties:
type:
type: string
enum: ['group_joined']
channel:
type: object
properties:
id:
type: string
name:
type: string
created:
type: number
creator:
type: string

groupLeft:
summary: You left a private channel.
payload:
type: object
properties:
type:
type: string
enum: ['group_left']
channel:
type: string

groupMarked:
summary: A private channel read marker was updated.
payload:
type: object
properties:
type:
type: string
enum: ['group_marked']
channel:
type: string
ts:
type: string

groupOpen:
summary: You opened a private channel.
payload:
type: object
properties:
type:
type: string
enum: ['group_open']
user:
type: string
channel:
type: string

groupRename:
summary: A private channel was renamed.
payload:
type: object
properties:
type:
type: string
enum: ['group_rename']
channel:
type: object
properties:
id:
type: string
name:
type: string
created:
type: number

groupUnarchive:
summary: A private channel was unarchived.
payload:
type: object
properties:
type:
type: string
enum: ['group_unarchive']
channel:
type: string
user:
type: string

imClose:
summary: You closed a DM.
payload:
type: object
properties:
type:
type: string
enum: ['im_close']
channel:
type: string
user:
type: string

imCreated:
summary: A DM was created.
payload:
type: object
properties:
type:
type: string
enum: ['im_created']
channel:
type: object
properties:
id:
type: string
name:
type: string
created:
type: number
creator:
type: string
user:
type: string

imMarked:
summary: A direct message read marker was updated.
payload:
type: object
properties:
type:
type: string
enum: ['im_marked']
channel:
type: string
ts:
type: string

imOpen:
summary: You opened a DM.
payload:
type: object
properties:
type:
type: string
enum: ['im_open']
channel:
type: string
user:
type: string

manualPresenceChange:
summary: You manually updated your presence.
payload:
type: object
properties:
type:
type: string
enum: ['manual_presence_change']
presence:
type: string

memberJoinedChannel:
summary: A user joined a public or private channel.
payload:
type: object
properties:
type:
type: string
enum: ['member_joined_channel']
user:
type: string
channel:
type: string
channel_type:
type: string
enum:
- C
- G
team:
type: string
inviter:
type: string

memberLeftChannel:
summary: A user left a public or private channel.
payload:
type: object
properties:
type:
type: string
enum: ['member_left_channel']
user:
type: string
channel:
type: string
channel_type:
type: string
enum:
- C
- G
team:
type: string

message:
summary: A message was sent to a channel.
payload:
type: object
properties:
type:
type: string
enum: ['message']
user:
type: string
channel:
type: string
text:
type: string
ts:
type: string
attachments:
type: array
items:
$ref: '#/components/schemas/attachment'
edited:
type: object
properties:
user:
type: string
ts:
type: string

outgoingMessage:
summary: A message was sent to a channel.
payload:
type: object
properties:
id:
type: number
type:
type: string
enum: ['message']
channel:
type: string
text:
type: string

The specification is pretty verbose, but it provides a great example of a robust Websockets API, that we can all reverse engineer and learn about how to properly define Websocket APIs using the specification format. Outlining how to properly define the events, and their corresponding messages, providing a machine-readable definition for a Websocket API.

We have 50 Websocket APIs we've worked to craft AsyncAPI definitions for. We are working to publish them as a single collection of definitions as part of the Streamdata.io API Gallery. Once up, we'll publish a story on the collection, providing other examples of Websocket APIs that have been documented using AsyncAPI. We see AsyncAPI being just as important to the evolution of the API sectors as OpenAPI, but providing an accompanying specification for defining streaming, event, and message-based APIs. If you are in the business of delivering streaming, event-based, or message-based APIs we recommend getting involved and contribute to the community.

Slack real time messaging

There are 0 comments.

Have something to say?

Drop a comment below.

Share - 'An Async API Definition For The Slack Real Time Messaging API' on Google Share - 'An Async API Definition For The Slack Real Time Messaging API' on Facebook Share - 'An Async API Definition For The Slack Real Time Messaging API' on Twitter Share - 'An Async API Definition For The Slack Real Time Messaging API' on Reddit Share - 'An Async API Definition For The Slack Real Time Messaging API' on LinkedIn