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
a messaging interface for clients
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.
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 |
|---|---|---|
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=userContent-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=smsContent-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=smsContent-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/loginContent-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/loginContent-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/loginContent-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 | |