Channels

Last updated 2 months ago

A Channel acts as a delivery target for Messages. A Channel also associates certain users to it called participants. A participant for a given channel has special semantics in certain contexts, for example, by default only a participant can send messages to a Channel (with ACLs this behavior can be overriden). Fetching a list of participants for a channel is also a common use-case for most of the applications. A channel is uniquely identified by an identifier and can be overriden by the creator of the channel. The standard restrictions for an identifier apply as usual:

  1. The identifier can use alphanumeric characters.

  2. The identifier can use from a set of symbols (- _ @ $ #)

  3. The first character can only be alphanumeric, @ or #

  4. The identifier must be between 8 and 72 characters

This is the regex: [a-zA-Z0-9@#][a-zA-Z0-9-_@$#]*

Reserved Channels

While these APIs and features are planned for a future release, certain channel ids are employed for specific purposes and are reserved:

  1. .broadcast Channel used for an application wide broadcast.

  2. .control Channel used for control messages to co-ordinate front-end clients.

The Channel Model

The model of a Channel looks as below:

{
"channelId": "f8cc57d8-af38-4313-85e8-cbe62a2ebf23",
"defaultRuleSet": "io.mitter.ruleset.chats.DirectMessage",
"participation": [
{
"participantId": "0b604184-7abd-453c-b258-7e4425b31e7f",
"participationStatus": "Active"
},
{
"participantId": "87d1ab9b-40e8-4017-a4f1-2deae7e05d74",
"participationStatus": "Active"
}
],
"systemChannel": false,
"audit": {
"createdAt": 144656562,
"updatedAt": 144666852
}
}

A quick overview of the relevant fields:

  1. The channelId contains the unique identifier for the channel.

  2. The defaultRuleSet specifies the default rule set that is applied to the Channel. A ruleset constraints the operations that can be performed on the Channel. Refer to the section on Rulesets in this page for more details.

  3. The participation is a list of ChannelParticipation objects which contain the user identifier of the participant and the status of the participant. Refer to the Participation section in the page for more details.

  4. The systemChannel defines whether this is a system channel or not. While one can create system channels, this is ideally used for messages that are for communication between machine/software components and are not enlisted when fetching a list of channels (unless explicitly requested for).

  5. The audit field contains createdAt (creation time) and updatedAt (last update time) timestamps. These cannot be overridden in POST calls and will be ignored if sent.

Rulesets

A ruleset defines the constraints on a Channel in terms of messaging, participation etc. mitter.io frontend SDKs also use the ruleset identifier for directing behavior (or in some cases the default behavior) on these Channels. As of now, Channels can only select from a set list of rulesets and the ability to define and set custom rulesets is planned for the near future.

The rulesets provided out of the box are:

  1. io.mitter.ruleset.chats.DirectMessage

  2. io.mitter.ruleset.chats.GroupChat

  3. io.mitter.ruleset.chats.SystemChannel

  4. io.mitter.ruleset.chats.SingleParticipantChannel

Direct Message

TYPE io.mitter.ruleset.chats.DirectMessage

A direct message channel has the following constraints:

  1. This channel must have exactly two distinct participants at any given point of time.

  2. Participants cannot be added/removed/replaced at any point of time in this channel.

  3. Only the involved participants can send messages to this channel.

  4. Both the participants in this channel must be provided and set at the time of creation

This type of a channel is used to facilitate a communication between two people, as is the use-case of instant messaging applications.

Group Chat

TYPE io.mitter.ruleset.chats.GroupChat

A group chat has the following constraints/provisions:

  1. It can have any number of participants, even zero.

  2. Participants can be added/removed to it at any point of time.

  3. All participants of this Channel can send Messages to this Channel.

  4. This Channel can be deleted, at which point all participations are also revoked.

  5. All participants of this channel can read a Message from this channel.

  6. No User that is not a participant of this channel can send a message or read from this Channel.

System Channel

TYPE io.mitter.ruleset.chats.SystemChannel

This kind of a channel has the following constraints/provisions:

  1. At the time of creation, exactly one participant must be provided.

  2. The application-level user .system is automatically added to this channel.

  3. Neither of the two participants can be deleted/replaced.

  4. The user (other than .system) may or may not have access to the messages from the channel (to use to send upstream-only messages).

This is used generally for control-type messages to be pushed to users from a central co-ordination system. Messages on this channel are not intended to be read by humans, i.e. they are not intended to be in a human readable format.

Single Participant Channel

TYPE io.mitter.ruleset.chats.SingleParticipantChannel

This channel has the following constraints/provisions:

  1. At the time of creation exactly one user can be provided.

  2. This user cannot be removed/replaced.

  3. No new participants can be added to this channel.

This channel is also not intended to contain human readable messages. This channel is intended to be used by different endpoints (devices) used by the same user to co-ordinate information amongst each other.

Participation

A participation defines an association of a user with a channel. A participation also contains a status of the participation that may take upon one of the three values Active, ReadOnly and Disabled. This status while mainly intended for application developers to build the logic on, mitter.io centrally uses it to establish the following semantics:

  1. When fetching a list of participants, by default only Active participants are returned.

  2. Messages sent to a channel are delivered only to Active and ReadOnly participants.

  3. When using your own ACLs, a Disabled or a ReadOnly participant is essentially the same as any other participant, and it acts purely as a way to narrow down your ACL rules by participation classes. This is an effect of mitter not assigning any default ACLs when you are using your custom rules.

Participants to a channel can be added/removed after channel creation if the ruleset permits that operation.

Channel API Reference

The APIs around channels can be categorized as:

  1. Operations on Channels

  2. Operations on Channel participation

Operations on Channel

Creating a Channel

To create a channel, make a POST request. By default, any authenticated user can create a Channel. This behavior can be overriden using ACLs.

POST /v1/channels
{
"defaultRuleSet": "io.mitter.chats.GroupChannel",
"participation": [
{
"participantId": "0b604184-7abd-453c-b258-7e4425b31e7f",
"participationStatus": "Active"
}
]
}

Note that the audit field, if sent, will be ignored.

On successful creation, the server returns the identifier of the Channel.

200 OK
{
"identifier": "c36cc2eb-f500-4a85-a8e6-2090cd68254c"
}

Deleting a Channel

To delete a Channel, make a DELETE call. By default only .system can delete channels. In the future the defaults will be enforced by the ruleset. This behavior can also be modified using ACLs.

DELETE /v1/channels/c36cc2eb-f500-4a85-a8e6-2090cd68254c

On successful deletion the server returns a 204

204 No Content

Get a Channel

To get a channel, make a GET call.

GET /v1/channels/c36cc2eb-f500-4a85-a8e6-2090cd68254c

The server returns the channel object.

{
"channelId": "c36cc2eb-f500-4a85-a8e6-2090cd68254c",
"defaultRuleSet": "io.mitter.chats.GroupChat",
"participation": [],
"systemChannel": false
}

Do note that the GET call DOES NOT populate the participants of a channel. It always returns an empty array.

Timeline events

Adding a timeline event to a channel

To add a timeline event to a channel, make a POST call

POST /v1/channels/f8cc57d8-af38-4313-85e8-cbe62a2ebf23/timeline
{
"type": "mitter.mtet.ReadTime",
"eventTimeMs": 1506968364492
"subject": "a6097f2f-b5cf-4afc-b246-019da17c281b"
}

Unlike the timeline event operations for messages, timeline events on channels do not support adding timeline events to multiple channels in a single request. In the URI only one channel id can be specified.

On successful execution, the server returns a 204

204 No Content

Getting Timeline Events for a Channel

To get timeline events for a message, make a GET call

GET /v1/channels/f8cc57d8-af38-4313-85e8-cbe62a2ebf23/timeline

This returns a list of ChannelTimelineEvent objects

200 OK
​[
{
"channelId": "a609f",
"timelineEvent": { ... }
},
{
"channelId": a609f",
"timelineEvent": { ... }
},
{
"channelId": "dbef",
"timelineEvent": { .. }
}
]

If you want to fetch events of only a certain type, a timeline event filter can be passed to the GET call.

GET /v1/channels/f8cc57d8-af38-4313-85e8-cbe62a2ebf23/timeline
?eventTypeFilter=my.channelEvent

Timeline Events one set cannot be deleted even if custom types are used.

Participation APIs

Add a Participant to a Channel

To add a participant to a channel, make a POST call. By default, any authenticated user can add themselves to a channel and .system can add any user as a participant to any channel. This behavior can be modified using ACLs.

POST /v1/channels/c36cc2eb-f500-4a85-a8e6-2090cd68254c/participants
{
"participantId": "aab1a003-7648-4900-926a-94fda15649b6",
"participationStatus": "Active"
}

On successful execution, the server returns a 204

204 No Content

Remove a Participant from a Channel

To remove a participant from a channel, make a DELETE call. By default, any authenticated User can remove themselves as a participant from a Channel and .system can remove any user.

DELETE /v1/channels/c36cc2eb-f500-4a85-a8e6-2090cd68254c/participants/aab1a003-7648-4900-926a-94fda15649b6

The parameter after /participants/ is the user identifier of the participant that is to be removed. On successful execution, the service returns a 204

204 No Content

Get all Participants for a Channel

To get all participants for a Channel, make a GET call. By default any participant for a Channel can fetch the list of participants and .system can do so for any Channel.

GET /v1/channels/c36cc2eb-f500-4a85-a8e6-2090cd68254c/participants

The server returns a list of ChannelParticipation objects:

200 OK
[
{
"channelParticipationId": "11c9b595-d6dc-4a47-97aa-c98b96bc01d0",
"participantId": {
"identifier": "0b604184-7abd-453c-b258-7e4425b31e7f"
},
"participant": {
"userId": "0b604184-7abd-453c-b258-7e4425b31e7f"
},
"participationStatus": "Active",
"channelId": {
"identifier": "c36cc2eb-f500-4a85-a8e6-2090cd68254c"
}
}
]

By default the server returns the entire object of participants. If you want the identifiers, you can set the expandParticipants query paramater:

GET /v1/channels/c36cc2eb-f500-4a85-a8e6-2090cd68254c/participants?expandParticipants=false
200 OK
[
{
"participantId": {
"identifier": "0b604184-7abd-453c-b258-7e4425b31e7f"
},
"participationStatus": "Active"
}
]

Get all Channels the User is a Participant in

To get all the Channels in which a user is a participant, make a GET call. By default any user can fetch their own participating Channels and .system can do so for any User. This behavior can be modified by using ACLs.

GET /v1/users/0b604184-7abd-453c-b258-7e4425b31e7f/channels

On successful execution, the server returns a list of ParticipatedChannel objects.

200 OK
[
{
"participationStatus": "Active",
"channel": {
"channelId": "c36cc2eb-f500-4a85-a8e6-2090cd68254c",
"defaultRuleSet": "io.mitter.chats.GroupChat",
"participation": [],
"systemChannel": false,
"audit": {
"createdAt": 144656562,
"updatedAt": 144666852
}
}
}
]