On this page

Create message drafts

MessageDraft represents an unpublished message. Use it to:

Display message elements (mentions, references, links) in your UI by adding a message draft change listener.

Message drafts consist of MessageElement objects, which can be either instances of PlainText or Link.

PlainText are simple strings, while Link elements are used for user mentions, channel references, and URLs. They contain a text and a reference to the linked element regardless if it's a user, a channel, or a URL.

Each Link implements a MentionTarget interface, which defines the type of mention. Available targets include:

  • MentionTarget.User(val userId: String)
  • MentionTarget.Channel(val channelId: String)
  • MentionTarget.Url(val url: String)
Store draft messages locally

Chat SDK does not persist drafts. Implement your own local storage to save drafts across channel switches.

Create a draft message

createMessageDraft() creates a message draft (MessageDraft object) that can consist of:

Method signature

This method has the following signature:

1channel.createMessageDraft(
2 userSuggestionSource: UserSuggestionSource = UserSuggestionSource.CHANNEL,
3 isTypingIndicatorTriggered: Boolean = true,
4 userLimit: Int = 10,
5 channelLimit: Int = 10
6):

Input

* required
ParameterDescription
userSuggestionSource
Type: UserSuggestionSource.CHANNEL or UserSuggestionSource.GLOBAL
Default:
UserSuggestionSource.CHANNEL
This parameter refers to the Mentions feature. Data source from which you want to retrieve users. You can choose either the list of channel members (.CHANNEL) or users on the app's Admin Portal keyset (.GLOBAL).
isTypingIndicatorTriggered
Type: Boolean
Default:
true
This parameter refers to the Typing Indicator feature. Defines if the typing indicator should be enabled when writing the message.
userLimit
Type: Int
Default:
10
This parameter refers to the Mentions feature. Maximum number of usernames (name field from the User object) you can mention in one message. The default value is 10, the min is 1, and max is 100.
channelLimit
Type: Int
Default:
10
This parameter refers to the References feature. Maximum number of channel names (name field from the Channel object) you can reference in one message. The default value is 10, the min is 1, and max is 100.

Output

TypeDescription
MessageDraftImpl
Created MessageDraft object with the content of the message, all links, referenced channels, mentioned users and their names.

Sample code

Create a draft message containing just plain text.

1val messageDraft = channel.createMessageDraft(isTypingIndicatorTriggered = channel.type != ChannelType.PUBLIC)

Add message draft change listener

Add a MessageDraftChangeListener to receive draft content changes and suggestions for mentions, channel references, and links.

Method signature

This method has the following signature:

1messageDraft.addChangeListener(listener: MessageDraftChangeListener)
2
3// interface to implement
4fun interface MessageDraftChangeListener {
5 fun onChange(messageElements: List<MessageElement>, suggestedMentions: PNFuture<List<SuggestedMention>>)
6}

Input

ParameterDescription
listenerThe listener that receives the most current message elements and suggestions list.
MessageDraftChangeListener
ParameterDescription
onChange(messageElements: List<MessageElement>, suggestedMentions: PNFuture<List<SuggestedMention>>)
Type: function
  • messageElements: List<MessageElement> - this parameter is a list of MessageElement objects, representing the current state of the message draft. This could contain a mix of plain text and links, channel references, or user mentions.
  • suggestedMentions: PNFuture<List<SuggestedMention>> - this parameter is a PNFuture containing a list of SuggestedMention objects. These are potential suggestions for message elements based on the current text in the draft.
SuggestedMention

A SuggestedMention represents a potential mention suggestion received from MessageDraftChangeListener.

ParameterDescription
offset
Type: Int
The position from the start of the message draft where the message elements starts. It's counted from the beginning of the message (including spaces), with 0 as the first character.
replaceFrom
Type: String
The original text at the given offset in the message draft text.
replaceWith
Type: String
The suggested replacement for the replaceFrom text.
target
Type: MentionTarget
The message element type. Available types include:

  • MentionTarget.User(val userId: String)
  • MentionTarget.Channel(val channelId: String)
  • MentionTarget.Url(val url: String)

Output

This method doesn't return any data.

Sample code

Add the listener to your message draft.

1// create a message draft
2val messageDraft = channel.createMessageDraft(isTypingIndicatorTriggered = channel.type != ChannelType.PUBLIC)
3
4// add the listener
5val listener = { elements: List<MessageElement>, suggestedMentions: PNFuture<List<SuggestedMention>> ->
6 updateUI(elements) // updateUI is your own function for updating UI
7 suggestedMentions.async { result ->
8 result.onSuccess { updateSuggestions(it) } // updateSuggestions is your own function for displaying suggestions
9 }
10 }
11messageDraft.addChangeListener(listener)

Remove message draft change listener

Remove a previously added MessageDraftChangeListener.

Method signature

This method has the following signature:

1messageDraft.removeChangeListener(listener: MessageDraftChangeListener)

Input

ParameterDescription
listenerThe listener to remove.

Output

This method doesn't return any data.

Sample code

Remove a listener from your message draft.

1// create a message draft
2val messageDraft = channel.createMessageDraft(isTypingIndicatorTriggered = channel.type != ChannelType.PUBLIC)
3
4// add the listener
5val listener = { elements: List<MessageElement>, suggestedMentions: PNFuture<List<SuggestedMention>> ->
6 updateUI(elements) // updateUI is your own function for updating UI
7 suggestedMentions.async { result ->
8 result.onSuccess { updateSuggestions(it) } // updateSuggestions is your own function for displaying suggestions
9 }
10 }
11messageDraft.addChangeListener(listener)
12
13// remove the listener
14messageDraft.removeChangeListener(listener)

Add message element

addMention() adds a user mention, channel reference or a link specified by a mention target at a given offset.

Method signature

This method has the following signature:

1messageDraft.addMention(
2 offset: Int,
3 length: Int,
4 target: MentionTarget
5)

Input

* required
ParameterDescription
offset *
Type: Int
Default:
n/a
Position of a character in a message where the message element you want to insert starts. It's counted from the beginning of the message (including spaces), with 0 as the first character.
length *
Type: Int
Default:
n/a
Number of characters the message element should occupy in the draft message's text.
target *
Type: MentionTarget
Default:
n/a
Message element type. Available types include:

  • MentionTarget.User(val userId: String)
  • MentionTarget.Channel(val channelId: String)
  • MentionTarget.Url(val url: String)

Output

This method returns no output data.

Sample code

Create the Hello Alex! I have sent you this link on the #offtopic channel. message where Alex is a user mention, link is a URL, and #offtopic is a channel reference.

1// create an empty message draft
2val messageDraft = channel.createMessageDraft(isTypingIndicatorTriggered = channel.type != ChannelType.PUBLIC)
3
4// add a text
5messageDraft.update(text = "Hello Alex!")
6
7// add a user mention to the string 'Alex'
8messageDraft.addMention(offset = 6, length = 4, target = MentionTarget.User(userId = "alex_d"))
9
10// change the text
11messageDraft.update(text = "Hello Alex! I have sent you this link on the #offtopic channel.")
12
13// add a link to the string 'link'
14messageDraft.addMention(offset = 33, length = 4, target = MentionTarget.Url(url = "www.pubnub.com"))
15
show all 17 lines

Remove message element

removeMention() removes a user mention, channel reference, or a link at a given offset.

Method signature

This method has the following signature:

1messageDraft.removeMention(offset: Int)

Input

* required
ParameterDescription
offset *
Type: Int
Default:
n/a
Position of the first character of the message element you want to remove.
Offset value

If you don't provide the position of the first character of the message element to remove, it isn't removed.

Output

This method returns no output data.

Sample code

Remove the URL element from the word link in the Hello Alex! I have sent you this link on the #offtopic channel. message.

1// assume the message reads
2// Hello Alex! I have sent you this link on the #offtopic channel.
3
4// remove the link mention
5messageDraft.removeMention(offset = 33)

Update message text

update() replaces the text of a draft message with new content.

Removing message elements

The SDK preserves message elements when possible. If element text is modified, that element is removed.

Method signature

This method has the following signature:

1messageDraft.update(text: String)

Input

* required
ParameterDescription
text *
Type: string
Default:
n/a
Text of the message that you want to update.

Output

This method returns no output data.

Sample code

Change the message I sent Alex this picture. to I did not send Alex this picture. where Alex is a user mention.

1// the message reads:
2// I sent [Alex] this picture.
3// where [Alex] is a user mention
4messageDraft.update(text = "I did not send Alex this picture.")
5// the message now reads:
6// I did not send [Alex] this picture.
7// the mention is preserved because its text wasn't changed
Mention text changes

Changing mention text removes that mention. For finer control, use Insert message text and Remove message text.

Insert suggested message element

Insert a message element from the MessageDraftChangeListener into the MessageDraft.

Text must match

SuggestedMention.replaceFrom must match the draft text at the specified position, or an exception is thrown.

Method signature

This method has the following signature:

1messageDraft.insertSuggestedMention(
2 mention: SuggestedMention,
3 text: String
4)

Input

* required
ParameterDescription
mention *
Default:
n/a
A user, channel, or URL suggestion obtained from MessageDraftChangeListener.
text *
Type: string
Default:
n/a
The text you want the message element to display.

Output

This method returns no output data.

Sample code

Register a listener and insert a suggested element.

1// create a message draft
2val messageDraft = channel.createMessageDraft(isTypingIndicatorTriggered = channel.type != ChannelType.PUBLIC)
3
4// add the listener
5val listener = { elements: List<MessageElement>, suggestedMentions: PNFuture<List<SuggestedMention>> ->
6 updateUI(elements) // updateUI is your own function for updating UI
7 suggestedMentions.async { result ->
8 result.onSuccess { updateSuggestions(it) } // updateSuggestions is your own function for displaying suggestions
9 }
10 }
11messageDraft.addChangeListener(listener)
12
13// when the user selects a suggestion in the UI:
14messageDraft.insertSuggestedMention(suggestion, suggestion.replaceWith)

Insert message text

insertText() inserts plain text in the draft message at the specified offset.

Removing message elements

Inserting text at an existing message element position removes that element.

Method signature

This method has the following signature:

1messageDraft.insertText(
2 offset: Int,
3 text: String
4)

Input

* required
ParameterDescription
offset *
Type: Int
Default:
n/a
Position of a character in a message where the text you want to insert starts. It's counted from the beginning of the message (including spaces), with 0 as the first character.
text *
Type: string
Default:
n/a
Text that you want to insert.

Output

This method returns no output data.

Sample code

In the message Check this support article https://www.support-article.com/., add the word out between the words Check and this.

1// the message reads:
2// Check this support article https://www.support-article.com/.
3messageDraft.insertText(6, "out ")
4// the message now reads:
5// Check out this support article https://www.support-article.com/.

Remove message text

removeText() removes plain text from the draft message at the specified offset.

Removing message elements

Removing text at an existing message element position removes that element.

Method signature

This method has the following signature:

1messageDraft.removeText(
2 offset: Int,
3 length: Int
4)

Input

* required
ParameterDescription
offset *
Type: Int
Default:
n/a
Position of a character in a message where the text you want to insert starts. It's counted from the beginning of the message (including spaces), with 0 as the first character.
length *
Type: Int
Default:
n/a
How many characters to remove, starting at the given offset.

Output

This method returns no output data.

Sample code

In the message Check out this support article https://www.support-article.com/., remove the word out.

1// the message reads:
2// Check out this support article https://www.support-article.com/..
3messageDraft.remove(5, 4)
4// the message now reads:
5// Check this support article https://www.support-article.com/.

Send a draft message

send() publishes the draft message with all mentioned users, links, and referenced channels. Mentioning users also emits mention events.

Method signature

This method has the following signature:

1messageDraft.send(
2 meta: Map<String, Any>? = null,
3 shouldStore: Boolean = true,
4 usePost: Boolean = false,
5 ttl: Int? = null,
6): PNFuture<PNPublishResult>

Input

* required
ParameterDescription
meta
Type: Map<String, Any>?
Default:
n/a
Additional details of the request.
shouldStore
Type: Boolean
Default:
true
If true, the messages are stored in Message Persistence (PubNub storage).
If shouldStore is not specified, the Message Persistence configuration specified on the Admin Portal keyset is used.
usePost
Type: Boolean
Default:
false
When true, the SDK uses HTTP POST to publish the messages. The message is sent in the BODY of the request instead of the query string when HTTP GET is used. The messages are also compressed to reduce their size.
ttl
Type: Int?
Default:
n/a
Defines if / how long (in hours) the message should be stored in Message Persistence.
  1. If shouldStore = true, and ttl = 0, the message is stored with no expiry time.
  2. If shouldStore = true and ttl = X, the message is stored with an expiry time of X hours unless you have message retention set to Unlimited on your keyset configuration in the Admin Portal.
  3. If shouldStore = false, the ttl parameter is ignored.
  4. If ttl is not specified, then the expiration of the message defaults back to the expiry value for the keyset.

Suppose a user adds elements to the message draft, such as links, quotes, other user mentions, or channel references. In that case, these are not explicitly passed in the send() method but get added to the MessageDraft object through the addMention() and addQuote() methods.

Output

TypeDescription
Promise<{ timetoken: number }>
Returned object that contains the timetoken of the message.

Sample code

Send a draft message containing just plain text.

1// create a draft message
2val messageDraft = channel.createMessageDraft(isTypingIndicatorTriggered = channel.type != ChannelType.PUBLIC)
3
4// add text
5messageDraft.update(text = "Hello!")
6// send the message
7messageDraft.send()
Last updated on