Messaging Interface

Messaging Interface

Target release



Epic



Document status

Draft Specification

Document owner

@Shailesh Kochhar

Contact

Shailesh Kochhar, Pramod Verma









Overview

Different kinds of collaboration possible

  • Real-time, syncronous

  • Threaded conversations, asyncronous

  • Q&A, asyncronous

This doc covers the functional interface which must be implemented by messaging services to allow its real-time synchronous collaboration capability to be exposed within Sunbird.

The functional interface will provide an implementation of the Sunbird abstractions which enable sending and receiving of messages.

Architecture

Sunbird provides plugin points for installing

  1. a messaging interface for clients

  2. a messaging service adapter which can connect with a messaging service backend.

The Sunbird client (web/mobile) will install a client plugin allowing it to connect to the messaging backend via the messaging interface exposed by the Sunbird server. 

Architecture for Messaging Service Integration
Architecture for Messaging Service Integration

Entities

The messaging interface provides an abstraction over messaging services to enable one-or-more messaging providers to plug-in to Sunbird. The interface provides the means to manipulate and manage:



  • Participants: each participant in a group messaging session is associated with an account. Consider three types of accounts: user, guest and bot

  • Identity: each user account will be associated with a Sunbird identity, it can also be associated with other third-party identities

  • Rooms: equivalent of a group chat. Multiple accounts can participate in a room

  • Sessions: are associated with devices which the participant uses. Multiple sessions may be initiated from a single device

  • Events: are an abstraction over forms of content. A message is one event type.

  • Devices: provide a means for offline management of encryption keys. A device is not always a physical entity, a browser is also a device

Participant management

For a participant to send/receive messages, she/he/it must be registered with the messaging service. Registered participants must authenticate to interact with the service and perform operations.

Register: POST /msg/client/v1/register?medium=<medium>?type=<type>

Register a user account with profile details using the messaging backend chosen by the instance administrator.

  • This API may be used to register two types of user accounts (see Registering Bots for details on registering bot accounts)

  •  

    • A guest account which has limited access to messaging APIs. This may not be supported by all backends

    • A user account which does not have limitations

  • Once the registration is successful, the server must issue the client an authenticatedUserToken which must be used in subsequent API calls from this device

  • The server will attempt to generate an account with the provided username, however, if the username is not available, the server will return a corresponding error.

  • The selected username must conform to the constraints specified below, if it does not meet the constraints, the server will return a corresponding error.

Request

Parameter

Type

Description

Parameter

Type

Description

Query Parameters

medium

String

The medium through which the user’s identity is to be validated. One of email or sms. Required

type

String

The type of registration. One of guest or user

JSON Body Parameters

username

String

The desired username for the user. The username must be a minimum of six characters and may use any of the following characters [0-9a-zA-Z_ - .]

If it is omitted, the server must generate a username for the account.

deviceId

String

ID of the client device. This is used to register a device for the new account. If it is omitted, the server must generate a deviceId for this device.

firstName

String

The first name of the new user.

lastName

String

The last name of the new user.

address

String

The address being used to register the user which will be attached to this account. Required

If medium is email, this should be an email address. If medium is sms, this should be a phone number in international format

sessionId

Int

The ID of the validation session which sent a token to the address. Required (see validationCode API)

validationCode

String

A valid code received by the user. Required (see validationCode API)

Example

POST /msg/client/v1/register?medium=sms&type=user
Content-type: application/json
{
“username”: “chacha_chaudhary”,
“password”: “a_very_weak_password”,
“deviceId”: “f071ade8716bcc24”,
“firstName”: “Chacha”,
“lastName”: “Chaudhary”,
“address”: “+919999000111”,
“sessionId”: 4176451,
“validationCode”: “SB-418912”,
}

Response: Status 200

Indicates that a new account has been created for the user

{
“username”: “chacha_chaudhary”,
“userAddress”: “chacha_chaudhary@org.sunbird.msg.slack”,
“deviceId”: “f071ade8716bcc24”,
“authenticatedUserToken”: “brainworksfasterthanacomputer”
}

Response: Status 400

Indicates that there was an error in the request which made it invalid. This may be one of the following error codes

  • ERR_USERNAME_UNAVAILABLE: The username provided is already being used

  • ERR_USERNAME_INVALID: The username provided is not a valid username

  • ERR_ADDRESS_INVALID: The address provided is not in a valid format for the medium

  • ERR_CODE_INVALID: The validationCode provided is not valid for the address

  • ERR_CODE_EXPIRED: The validationCode provided has expired

{
“errcode”: “ERR_USERNAME_INVALID”,
“error”: “Username is not allowed to contain the ‘?’ character”
}

Response: Status 429

The request was rate-limited because of too many requests

Register Bot: POST /msg/client/v1/registerBot

Request Code: POST /msg/client/v1/identity/code/request?medium=<medium>

Request that a code be sent to the user to validate their ownership of a identity address using either email or sms medium

Request

Parameter

Type

Description

URL Parameters

medium

String

The medium through which to send the validation token, can either be email or sms

JSON Body Parameters

clientSecret

String

Unique client secret used to identify the attempt to validate the user’s address. The secret can use the following characters [0-9a-zA-Z.=_-] Required

address

String

The address where to send the validation code. Required

If the medium is email, this should be an email address

If the medium is sms, this should be a phone number in international format (including country code)

attemptNumber

Integer

The count of the attempt being made to send the validation code, multiple requests with the same attemptNumber may be ignored. Required

Example

POST /msg/client/v1/identity/code/request?medium=sms
Content-type: application/json
{
“clientSecret”: “this_is_a_very_poor_client_secret”,
“address”: “+919999000111”,
“attemptNumber”: 1
}

Response: Status 200

Indicates that a validation code has been sent, the sessionId will be required when confirming the code

{
“sessionId”: 4176451
}

Response: Status 400

Indicates that there was an error in the request which made it invalid. This may be one of the following error codes

  • ERR_ADDRESS_INVALID: The address provided is not in a valid format

  • ERR_TOO_MANY_ATTEMPTS: The number of attempts has exceeded the maximum allowed by the service. May vary based on the service backend.

{
“errcode”: “ERR_ADDRESS_INVALID”,
“error”: “The address provided is not a valid email”
}

Validate Identity: POST /msg/client/v1/identity/code/validate?medium=<medium>

Validate that a messaging user is the owner of an identity address. This method could be called multiple times for a given username with different mediums. It is up to the service to provide the capability to have multiple identities for the same medium.

Request

Parameter

Type

Description

URL Parameters

medium

String

The medium through which to send the validation token, can either be email or sms

JSON Body Parameters

username

String

The username for the account to connect the identity with. The username is required if this call is made without an authenticatedUserToken in the header

address

String

The address being used to register the user which will be attached to this account. Required

If medium is email, this should be an email address.

If medium is sms, this should be a phone number in international format

sessionId

Int

The ID of the validation session which sent a token to the address. Required (see validationCode API)

validationCode

String

A valid code received by the user. Required (see validationCode API)

Example

POST /msg/client/v1/identity/code/validate?medium=sms
Content-type: application/json
{
“username”: “chacha_chaudhary”,
“address”: “+919999000111”,
“sessionId”: 4176451,
“validationCode”: “SB-418912”,
}

Response: Status 200

Indicates that the address has been linked to the username provided.

{
“status”: “OK”
}

Response: Status 400

Indicates that there was an error in the request which made it invalid. This may be one of the following error codes

  • ERR_ADDRESS_INVALID: The address provided is not in a valid format

  • ERR_CODE_INVALID: The validationCode provided is not valid for the address

  • ERR_CODE_EXPIRED: The validationCode provided has expired

{
“errcode”: “ERR_ADDRESS_INVALID”,
“error”: “The address provided is not a valid email”
}

Login: POST /msg/client/v1/login

Authenticates a user using an authentication method from:

  • Mobile number/OTP

  • OIDC identity

  • Username/one-time use token

The client first makes an empty login request which will return a 401 Unauthorised response and a sessionId in the response body. The client then uses this sessionId in subsequent requests to complete the login sequence.

Once the user has been authenticated, the server should issue the user an authenticatedUserToken which can be used for future authorization needs (eg: when making API calls).

Request

Parameter

Type

Description

JSON Body Parameters

sessionId

Int

The id of the login session initiated. A new sessionId can be generated by sending an empty request. Required

type

Enum

The type of authentication protocol to use.

Required

Can be one of org.sunbird.msg.login.otp, org.sunbird.msg.login.oidc, org.sunbird.msg.login.token

identity

IdentityObject

Identity information for the user who is logging in. Required

identity.medium

Enum

The medium of the identity which is being passed. Required

Can be one of org.sunbird.msg.id.email, org.sunbird.msg.id.phone, org.sunbird.msg.id.oidc

identity.address

String

The identity address of the user who is logging in. Required when identity.medium is org.sunbird.msg.id.email, org.sunbird.msg.id.phone

identity.uri

String

The identity URI for authenticating the user who is logging in. Required when identity.medium is org.sunbird.msg.id.oidc

token

String

The one-time use token to confirm the user’s identity. Required when type is org.sunbird.msg.login.otp or org.sunbird.msg.login.token

Login with OTP

To login using an OTP, the client sets the type parameter to org.sunbird.msg.login.otp, the identity.medium to org.sunbird.msg.id.phone and identity.address to the recipient’s phone number. The token is the OTP requested using the validate identity endpoint.

Login via token is analogous to login via OTP with the type and medium being set appropriately. The token can be received via any communication channel.

Example

POST /msg/client/v1/login
Content-type: application/json
{
“sessionId”: 9817263
“type”: “org.sunbird.msg.login.otp”,
“identity”: {
“medium”: “org.sunbird.msg.id.phone”,
“address”: “+919999000111”,
},
“token”: “SB-419817”,
}

Login with OIDC

To login using an OIDC Identity Provider (IdP), the client sets the type parameter to org.sunbird.msg.login.oidc, the identity.medium to org.sunbird.msg.id.oidc and identity.uri to the OIDC Authorization Request URI.

If the server allows logging in via the IdP selected, it redirects the client to visit the OIDC Authorization Request URI (via the appropriate HTTP response). The server should encode a callback endpoint into the Authorization Request URI.

The client presents the user with the OAuth2 consent page allowing access to the user’s identity information.

If the user authorises the request, the IdP will redirect the client to the redirect_uri along with an auth code. The redirect_uri should have been set to point to a server endpoint which acts as a confidential OIDC client. The server uses the auth code to request an access token from the IdP and retrieve the user’s identity information. This completes the OIDC login flow.

Once the OIDC login flow is completed on the server, the client makes a subsequent request to the login endpoint with the same sessionId and receives a success response.

  • Initiating the OIDC request

POST /msg/client/v1/login
Content-type: application/json
{
“sessionId”: 9817263
“type”: “org.sunbird.msg.login.oidc”,
“identity”: {
“medium”: “org.sunbird.msg.id.oidc”,
“uri”: “https://demo.open-sunbird.org/auth/realms/sunbird/protocol/openid-connect/auth?client_id=org.sunbird.msg&state=abc&scope=openid&response_type=code
},
}

  • Completing the OIDC request

POST /msg/client/v1/login
Content-type: application/json
{
“sessionId”: 9817263
“type”: “org.sunbird.msg.login.oidc”,
}

Response: Status 200

Indicates that the user has been authenticated

{
“username”: “chacha_chaudhary”,
“userId”: “chacha_chaudhary@org.sunbird.msg.slack”,
“deviceId”: “f071ade8716bcc24”,
“authenticatedUserToken”: “brainworksfasterthanacomputer”
}

Response: Status 401

Indicates that the request is missing authentication credentials

{
“errcode”: “ERR_USER_UNAUTHORIZED”,
“err”: “Not authorized to make this request”,
“sessionId”: 9817263
}

Response: Status 403

Indicates that the authentication has failed.

{
“errcode”: “ERR_USER_AUTHENTICATION_FAILED”,
“err”: “The credentials provided do not match a valid user”
}

Response: Status 400

Indicates that there was an error in the request which made it invalid

Logout: POST /msg/client/v1/logout

This logs out the user from the active session and makes the authenticatedUserToken unuseable for subsequent requests.

Request
Example

{}

Response: Status 200

Indicates that the user has been logged out of this device session

Room (Channel/Group) management

Create a room: POST /msg/client/v1/room/event/create

This endpoint creates a new room where subsequent events and messages can be dispatched. Room creation is itself an event which is the origin of subsequent events in the room. The room contains Sunbird metadata which can be used for discovery.

Rooms have two additional settings which control membership of the room. First is visibility which determines if the room is visible in public listings of the rooms available. The second is joinability which determines if the room can be joined without an invitation.

Request

Parameter

Type

Description

JSON Body Parameters

visibility

Enum

Controls the visibility of the room in room listing APIs. Must be one of unlisted or listed. If visibility is unlisted, then the room will not appear in room lists. If omitted, defaults to unlisted

membershipType

Enum

Controls the ability of users to join the room. Must be one of invite-only, token or open. If membershipType is invite-only, then new users must be added to the room. If membershipType is token, then a user must provide a token to join the room. If omitted, defaults to invite-only

name

String