Messages
Messages are central to the operations of mitter.io
. The design of mitter.io tries to assume as little as it can about Messages in general or the data they contain. The system is designed to be extremely flexible around the type of data a Message can contain. A Message has two important constraints: it requires a sender to be sent, and that it must have a text representation of the data it is sending. This can be an empty string as well but it is not recommend. There are other situational constraints as well, which will be discussed further in this section. A Message as other identifiables
is identified by a unique identifier, which can be overriden. The standard restrictions for an identifier apply as usual:
The identifier can use alphanumeric characters.
The identifier can use from a set of symbols (- _ @ $ #)
The first character can only be alphanumeric, @ or #
The identifier must be between 8 and 72 characters
This is the regex: [a-zA-Z0-9@#][a-zA-Z0-9-_@$#]*
The Message Model
A quick overview of the fields in a Message:
The
messageId
contains the unique identifier of this message.The
messageType
holds the type of this message. A message type defines handling parameters for this message. It is a closed set of values, and must be one ofStandard
,OutOfBand
andNotification
. Currently, onlyStandard
andNotifcation
are supported.The
payloadType
defines the type of data that this message contains. By default mitter.io provides support for certain types of messages. Each type of a message prescribes a format for themessageDatum
field. This value can be anything the developer wishes and can modify it to use custom payloads.The
senderId
field is the identifier of the user who sent this message. This is a mandatory field.The
textPayload
is the text representation of the image that is sent.The
messageData
field contains custom data in a list ofMessageDatum
objects. This field is covered in detail in the upcoming sections.The
timelineEvents
field contains events associated with this message. This field is covered un detal in the upcoming sections.The
audit
field containscreatedAt
(creation time) andupdatedAt
(last update time) timestamps. These cannot be overridden inPOST
calls and will be ignored if sent.
Payload Types
Out of the box mitter.io supports four payload types:
mitter.mt.Text
mitter.mt.ImageMessage
mitter.mt.FileMessage
mitter.mt.EmptyMessage
There is upcoming support for the following payload types:
mitter.mt.FormattedText
mitter.mt.LinkInsetText
You are free to define your own payload types and set it as the value of the payloadType
field, however no such type name can start with io.mitter.
or mitter.
.
Text Message
TYPE mitter.mt.Text
This type represents a simple text message. An example is as below:
The features of a text message are:
It does not contain a value for
messageDatum
. However, if the developer sets it, mitter.io will persist it and forward it on most delivery methods. Certain delivery mechanisms will ignore the message data field so it is recommend to not set this field.This message is handled almost completely unprocessed before delivering messages.
COMING SOON In the upcoming releases, we will be adding support for
deconstructed messages
, which are messages heavily stripped from their JSON structure and aggresively compressed to reduce the overall byte size when delivering over messaging mechanisms like FCM. This mechanism will not support themessageDatum
field.
Image Message
TYPE mitter.mt.ImageMessage
The ImageMessage
is handled much differently when sending messages, the link
field is not directly populated (if the image is to be stored and handled by mitter.io itself). Refer to the section Image and binary payloads later in this section.
The overall contract of this message is:
It must contain EXACTLY one MessageDatum of type
text/uri-list
.The corresponding
data
field must contain alink
which is the URI of the hosted image. This URI contains a placeholder$repr
which would be one of the specified representations.The representations available for the image must be provided as an array of strings, with each element denoting a representation of the image.
Do note that the developer does not have to manually make the multiple representations available. mitter.io automatically handles resizing and recompressing the image and making multiple representations available for you automatically. This is covered more in the upcoming sections.
File Message
TYPE mitter.mt.FileMessage
Starting with v0.4, mitter.io now supports file messages as well. This is exactly the same as sending an Image message with the only difference that file messages do not have any representations and no post processing is performed on any of the uploaded files. When uploading a file message do note that the request must contain EXACTLY one multi-part request. If it contains more than one or no binary parts, the entire request is rejected.
Formatted Message coming soon
TYPE mitter.mtet.FormattedText
This is a message type that can handle text that is formatted. The initial versions will not support complete rich-text support, but mostly a subset of the markdown specification. Do note that all details regarding this message type are currently tentative. An example payload of this type would look like:
There is also a tenatative plan to support deconstructed
messages for Formatted Messages as well.
Timeline Events
Timeline events are events that are associated with activity related to a message. They generally record the time of user action on a message. There are four timeline event types that are provided by mitter.io:
mitter.mtet.SentTime
The time at which the message was sent. This timestamp is populated with the timestamp on the client device.mitter.mtet.ReceivedTime
The time at which the message was received by the server. Thesubject
of this timeline event is always.system
.mitter.mtet.DeliveredTime
The time at which the message was delivered to a user. Thesubject
of this event is the receiving user.mitter.mtet.ReadTime
The time at which the message was read by a user. Thesubject
of this event is the receiving user.
A Message can have multiple timeline events of the same type. Furthermore, the event type does not have to be one of the above values and can be set to any custom value. However, types cannot start with io.mitter.
or mitter.
.
Message API Reference
Sending a Message
To send a Message, make a POST
request. By default a message can be sent to a channel by any participant with the same user as the sender. This behavior can be overriden by using ACLs. .system
can send a message to any channel on behalf of any user.
Do note that if you send the audit
fields, they will be ignored.
On success, the server returns back a Message
object itself. This is important because certain messages (like Image Message) undergo processing and modify the message object as is available from mitter.io past this request succeeding. A response to this message would look like:
As noted earlier, a Text Message undergoes minimal processing so this object is the exact same as what was sent to it, with the exception that it contains the generated message identifier.
NOTE Sending a Message has an additional constraint which requires that there must be EXACTLY one timeline event of type mitter.mtet.SentTime
present in the Message body. The example above includes this case.
Getting Messages from a Channel
Messages can be fetched from a Channel in a paginated manner using a GET query. By default all participants of a channel can fetch messages in the Channel which they have read access to (by default all Messages in a Channel are readable by all participants). This behavior is highly configurable and can be overriden by using ACLs.
For any given request, at most one of before
or after
can be set. The limit
can be set to any positive value lesser than 25. To make the first request, make a GET
request without any of this parameters:
The request above will return the last 10 messages of the server.
The Messages are returned in a sorted manner depending on which parameter was set. If before
was set, the messages are sorted such that newer messages appear last in the list. If after
was set, newer messages appear first in the list. When neither is provided, before
semantics are applied. Following the request above, you can fetch any messages before this using:
and to get any new incoming messages in the channel:
If there are no Messages returned, it means there are no Messages for the given criteria. When making a before
call, you can stop making any further calls. This method will never return any new messages. For an after
call, this is the URI you keep on polling for newer messages till one arrives.
This method however is rarely used for fetching Messages. All of our SDKs use push-based delivery mechanisms like FCM for Message delivery. The HTTP methods are primarily used for syncing messages on a client device.
For more information of receiving messages through those delivery channels refer to the Delivery Endpoints section of this reference document.
Deleting Messages from a Channel
To delete a Message from a Channel, make a DELETE
call. By default all Users can delete Messages that they have sent. Any deletion of a Message does not delete any delivered entities from any recipients end-device. .system
can delete any Message for any User on any Channel.
On successful execution, the server returns a 204
Sending Binary and Image messages
mitter.io allows you to upload image and file messages by supporting multipart requests. The multipart request (for images as well as files) should contain two parts:
name=
io.mitter.wire.requestbody
of typeapplication/json
. This contains the message request body, i.e. a JSON of the image model that is sent.Exactly one part which contains the image binary. The type must be either
image/jpeg
,image/png
orimage/gif
. Thename
of this part is ignored.
An example of such a request is as follows:
All other constraints that apply to a message still apply to the request JSON i.e. a timeline event of type mitter.mtet.SentTime
must be set.
Image Message Processing
When an image is uploaded, mitter.io performs the following processing:
Converts the image into two additional formats:
standard
andthumbnail
.The
thumbnail
representation is used to display a thumbnail image, mostly in messge bubbles on a UI.The
standard
is a reduced-size, compressed image that can be used to display the enlarged format, probably when the user clicks on the displayed thumbnail.Additionally a represetnation called
base
is created which contains the image AS-IS, but the support for this is subject to revocation.
An uploaded image is immediately transformed and stored in an intermediate storage on the mitter.io servers. In the background, the image is uploaded to a CDN. It might take any amount of time for the image to be made available in the CDN. Till the image is available in the CDN, any request to the returned link
in the image message returns a 200 OK
with the image data in the payload. Once it is uploaded to the CDN, the service returns a 301 PERMANENTLY MOVED
with the link from the CDN.
Timeline events
Adding a timeline event to a message
To add a timeline event to a message, make a POST call
This call supports setting timeline events for multiple messages in one go. This is generally useful when a user reads multiple received messages at the same time. For this, pass the message ids in a CSV format:
On successful execution, the server returns a 204
Getting Timeline Events for a Message
To get timeline events for a message, make a GET
call
This returns a list of MessageTimelineEvent
objects
If you want to fetch events of only a certain type, a timeline event filter can be passed to the GET
call.
Timeline Events one set cannot be deleted even if custom types are used.
Last updated