Chan.T.Text — Telepathy D-Bus Interface Specification

# Interface Channel.Type.Text

Interface Index (Compact) | Summary | Description | Methods | Signals | Properties | Types

### Methods

AcknowledgePendingMessages | (au: IDs) | → | nothing |
SendMessage | (aa{sv}: Message, u: Flags) | → | s: Token |

### Signals

MessageSent | (aa{sv}: Content, u: Flags, s: Message_Token) |
PendingMessagesRemoved | (au: Message_IDs) |
MessageReceived | (aa{sv}: Message) |

### Properties

SupportedContentTypes | as | Read only | Immutable |
MessageTypes | au (Channel_Text_Message_Type_List) | Read only | Immutable |
MessagePartSupportFlags | u (Message_Part_Support_Flags) | Read only | Immutable |
PendingMessages | aaa{sv} (Message_Part_List_List) | Read only |  |
DeliveryReportingSupport | u (Delivery_Reporting_Support_Flags) | Read only | Immutable |

### Types

Message_ID | Simple Type | u |
Message_Header_Key | Simple Type | s |
Message_Body_Key | Simple Type | s |
Delivery_Report_Header_Key | Simple Type | s |
Protocol_Message_Token | Simple Type | s |
Protocol_Content_Identifier | Simple Type | s |
Channel_Text_Send_Error | Enum | u |
Channel_Text_Message_Type | Enum | u |
Delivery_Status | Enum | u |
Message_Part_Support_Flags | Flags | u |
Message_Sending_Flags | Flags | u |
Delivery_Reporting_Support_Flags | Flags | u |
Message_Part | Mapping | a{sv} |

Changed in 0.24.0. This interface used to have a bunch of clunky Telepathy.Properties. They have been removed in favour of D-Bus properties on the Room1, Subject1 and RoomConfig1 interfaces.
Changed in 0.99.1. Deprecated methods and types have removed from this interface. Additionally, this interface has been merged with the old, now-removed, Messages interface as it was a requirement since version 0.21.5.
Objects implementing this interface must also implement:

- im.telepathy.v1.Channel

### Description

A channel type for sending and receiving messages. This channel type is primarily used for textual messages, but can also be used for more general messages, including:

- messages with attachments (like MIME multipart/mixed)
- groups of alternatives (like MIME multipart/alternative)
- delivery reports, adding support for protocols where the message content is not echoed back to the sender on failure and for receiving positive acknowledgements, as well as ensuring that incoming delivery reports are not lost if no client is handling the channel yet;
- any extra types of message we need in future

Incoming messages, outgoing messages, and delivery reports are all represented as lists of Message_Part structures, with a format reminiscent of e-mail.

When a message is received, an identifier is assigned and a MessageReceived signal emitted, and the message is placed in a pending queue represented by the PendingMessages property. When the Handler for a channel has handled the message by showing it to the user (or equivalent), it should acknowledge the receipt of that message using the AcknowledgePendingMessages method, and the message will then be removed from the pending queue. Numeric identifiers for received messages may be reused over the lifetime of the channel. Only the Handler for a channel should acknowledge messages; Observers (such as loggers) and Approvers for the channel may listen for incoming messages, and send messages of their own, but SHOULD NOT acknowledge messages.

##### Rationale:

If observers were allowed to acknowledge messages, then messages might have been acknowledged before the handler even got to see the channel, and hence could not be shown to the user.

Sending messages can be requested using the SendMessage method, which will return successfully when the message has been submitted for sending, or return an error with no signal emission if there is an immediate failure. If a message is submitted for sending but delivery of the message later fails, this is indicated by a delivery report, which is received in the same way as an incoming message. Outgoing messages are announced to other clients which may be interested in the channel by the MessageSent signal.

Simple one-to-one chats (such as streams of private messages in XMPP or IRC) should be represented by a Text channel whose TargetHandleType is Contact. The expected way to request such a channel is to set the ChannelType, TargetHandleType, and either TargetHandle or TargetID in a call to EnsureChannel.

Named chat rooms whose identity can be saved and used again later (IRC channels, Jabber MUCs) are expected to be represented by Text channels with TargetHandleType = Room and the Group1 interface. In protocols where a chatroom can be used as a continuation of one or more one-to-one chats, these channels should also have the Conference1 interface.

Unnamed, transient chat rooms which cannot be rejoined by their unique identifier (e.g. a conversation on MSN which has, or once had, three or more participants) are expected to be represented by Text channels with TargetHandleType = None (and hence TargetHandle = 0), Group1 interface, and optionally the Conference1 interface.

On protocols like MSN where a conversation with a user is actually just a nameless chat room starting with exactly two members, to which more members can be invited, the initial one-to-one conversation SHOULD be represented with TargetHandleType = Contact. If a third participant joins or is invited, this SHOULD be represented by signalling a new Conference1 channel with the one-to-one channel in its InitialChannels, migrating the underlying protocol object from the one-to-one channel to the Conference channel, and creating a new protocol-level conversation if the one-to-one channel is re-used. See the Conference interface for more details.

##### Rationale:

This keeps the presentation of all one-to-one conversations uniform, and makes it easier to hand over a conversation from a 1-1-specific UI to a more elaborate multi-user UI; while it does require UIs to understand Conference to follow the upgrade, UIs that will deal with XMPP need to understand Conference anyway.

If a channel of type Text is closed while it has pending messages, the connection manager MUST allow this, but SHOULD open a new channel to deliver those messages, signalling it as a new channel with the NewChannels signal. The new channel should resemble the old channel, but have Requested = FALSE regardless of its previous value; the InitiatorHandle and InitiatorID should correspond to the sender of one of the pending messages.

##### Rationale:

In effect, this turns this situation, in which a client is likely to lose messages:

- UI window is closed
- message arrives
- text channel emits Received
- UI calls Close on text channel before it has seen the Received signal
- text channel emits Closed and closes

into something nearly equivalent to this situation, which is fine:

- UI window is closed
- UI calls Close on text channel
- text channel emits Closed and closes
- message arrives
- new text channel is created, connection emits NewChannels
- (the same or a different) UI handles it

Requested must be set to FALSE so the replacement channel will be handled by something.

In practice, connection managers usually implement this by keeping the same internal object that represented the old channel, adjusting its properties, signalling that it was closed, then immediately re-signalling it as a new channel.

As a result, Text channels SHOULD implement Channel.Interface.Destroyable1.

##### Rationale:

This "respawning" behaviour becomes problematic if there is no suitable handler for Text channels, or if a particular message repeatedly crashes the Text channel handler; a channel dispatcher can't just Close() the channel in these situations, because it will come back.

In these situations, the channel dispatcher needs a last-resort way to destroy the channel and stop it respawning. It could either acknowledge the messages itself, or use the Destroyable interface; the Destroyable interface has the advantage that it's not channel-type-dependent, so the channel dispatcher only has to understand one extra interface, however many channel types eventually need a distinction between Close and Destroy.

Opaquely-named rejoinable chatrooms (such as Skype rooms) are represented using the properties in the Room1 interface. Instructions and examples of how to request such channels are given in said interface's description.

Although this specification supports formatted (rich-text) messages with unformatted alternatives, implementations SHOULD NOT attempt to send formatted messages until the Telepathy specification has also been extended to cover capability discovery for message formatting.

##### Rationale:

We intend to expose all rich-text messages as XHTML-IM, but on some protocols, formatting is an extremely limited subset of that format (e.g. there are protocols where foreground/background colours, font and size can be set, but only for entire messages). Until we can tell UIs what controls to offer to the user, it's unfriendly to offer the user controls that may have no effect.

# Methods

(Permalink)

## AcknowledgePendingMessages (au: IDs) → nothing

### Parameters

- IDs — au (Message_ID_List)
The IDs of the messages to acknowledge

Inform the channel that you have handled messages by displaying them to the user (or equivalent), so they can be removed from the pending queue.

### Possible Errors

- Invalid Argument
A given message ID was not found, so no action was taken

(Permalink)

## SendMessage (aa{sv}: Message, u: Flags) → s: Token

### Parameters

- Message — aa{sv} (Message_Part_List)
The message content, including any attachments or alternatives. This MUST NOT include the following headers, or any others that do not make sense for a client to specify: `message-sender`, `message-sender-id`, `message-sent`, `message-received`, `pending-message-id`.
- Flags — u (Message_Sending_Flags)
Flags affecting how the message is sent. The channel MAY ignore some or all flags, depending on DeliveryReportingSupport; the flags that were handled by the CM are provided in MessageSent.

### Returns

- Token — s (Protocol_Message_Token)
An opaque token used to match any incoming delivery or failure reports against this message, or an empty string if the message is not readily identifiable.

Submit a message to the server for sending. If this method returns successfully, the message has been submitted to the server and the MessageSent signal is emitted.

This method MUST return before the MessageSent signal is emitted.

##### Rationale:

This means that the process sending the message is the first to see the Protocol_Message_Token, and can relate the message to the corresponding MessageSent signal by comparing message tokens (if supported by the protocol).

If this method fails, message submission to the server has failed and no signal on this interface (or the Text interface) is emitted.

If this method succeeds, message submission to the server has succeeded, but the message has not necessarily reached its intended recipient. If a delivery failure is detected later, this is signalled by receiving a message whose `message-type` header maps to Delivery_Report. Similarly, if delivery is detected to have been successful (which is not possible in all protocols), a successful delivery report will be signalled.

### Possible Errors

- Invalid Argument
The requested message is malformed and cannot be sent.
- Not Available
Raised when the requested functionality is temporarily unavailable.
- Permission Denied
The user is not permitted to perform the requested operation.
- Network Error
Raised when there is an error reading from or writing to the network.

# Signals

(Permalink)

## MessageSent (aa{sv}: Content, u: Flags, s: Message_Token)

### Parameters

- Content — aa{sv} (Message_Part_List)

The message content (see Message_Part for full details). If the message that was passed to SendMessage has a formatted text part that the connection manager recognises, but no `text/plain` alternative, the CM MUST use the formatted text part to generate a `text/plain` alternative which is also included in this signal argument.

The connection manager SHOULD include the `message-sender`, `message-sender-id` and `message-sent` headers in the representation of the message that is signalled here. If the channel has channel-specific handles, the `message-sender` and `message-sender-id` SHOULD reflect the sender that other contacts will see.

If the connection manager can predict that the message will be altered during transmission, this argument SHOULD reflect what other contacts will receive, rather than being a copy of the argument to SendMessage (if the message is truncated, formatting or alternatives are dropped, etc., then the edited version SHOULD appear in this signal).

- Flags — u (Message_Sending_Flags)

Flags affecting how the message was sent. The flags might be a subset of those passed to SendMessage if the caller requested unsupported flags.

- Message_Token — s (Protocol_Message_Token)
An opaque token used to match any incoming delivery or failure reports against this message, or an empty string if the message is not readily identifiable.

Signals that a message has been submitted for sending.

This SHOULD be emitted as soon as the CM determines it's theoretically possible to send the message (e.g. the parameters are supported and correct).

##### Rationale:

This signal allows a process that is not the caller of SendMessage to log sent messages.

(Permalink)

## PendingMessagesRemoved (au: Message_IDs)

### Parameters

- Message_IDs — au (Message_ID_List)
The messages that have been removed from the pending message list.

The messages with the given IDs have been removed from the PendingMessages list. Clients SHOULD NOT attempt to acknowledge those messages.

##### Rationale:

This completes change notification for the PendingMessages property (previously, there was change notification when pending messages were added, but not when they were removed).
(Permalink)

## MessageReceived (aa{sv}: Message)

### Parameters

- Message — aa{sv} (Message_Part_List)

The message content, including any attachments or alternatives. If the incoming message contains formatted text without a plain text alternative, the connection manager MUST generate a `text/plain` alternative from the formatted text, and include it in this message (both here, and in the PendingMessages property).

Signals that a message has been received and added to the pending messages queue.

# Properties

Accessed using the org.freedesktop.DBus.Properties interface.
(Permalink)

## SupportedContentTypes — as

Read only
This property is immutable which means that it can never change once the channel has been created. Immutable properties SHOULD appear in the channel detail list of NewChannels signals.

A list of MIME types supported by this channel, with more preferred MIME types appearing earlier in the list. The list MAY include "*/*" to indicate that attachments with arbitrary MIME types can be sent. This list MUST NOT be empty, since all implementations MUST accept messages containing a single "text/plain" part.

Items in this list MUST be normalized to lower-case.

Some examples of how this property interacts with the MessagePartSupportFlags:

A simple IM implementation: only plain text messages are allowed
  SupportedContentTypes = ['text/plain'], MessagePartSupportFlags = 0
Formatted text with a plain text alternative is allowed (see the HTML interface draft)
  SupportedContentTypes = ['text/html', 'text/plain'], MessagePartSupportFlags = 0
JPEG or PNG images may be sent, but without any attached text
  SupportedContentTypes = ['text/plain', 'image/jpeg', 'image/png'], MessagePartSupportFlags = 0
Unformatted text to which an optional JPEG or PNG image may be attached
  SupportedContentTypes = ['text/plain', 'image/jpeg', 'image/png'], MessagePartSupportFlags = One_Attachment
Formatted text to which arbitrarily many images may be attached
  SupportedContentTypes = ['text/html', 'text/plain', 'image/jpeg', 'image/png', 'image/x-ms-bmp'], MessagePartSupportFlags = One_Attachment | Multiple_Attachments
A full SIP implementation: arbitrary MIME messages are allowed
  SupportedContentTypes = ['*/*'], MessagePartSupportFlags = One_Attachment | Multiple_Attachments

(Permalink)

## MessageTypes — au (Channel_Text_Message_Type_List)

Read only
This property is immutable which means that it can never change once the channel has been created. Immutable properties SHOULD appear in the channel detail list of NewChannels signals.
Added in 0.21.5.

A list of message types which may be sent on this channel.

(Permalink)

## MessagePartSupportFlags — u (Message_Part_Support_Flags)

Read only
This property is immutable which means that it can never change once the channel has been created. Immutable properties SHOULD appear in the channel detail list of NewChannels signals.
Flags indicating the level of support for message parts on this channel.
(Permalink)

## PendingMessages — aaa{sv} (Message_Part_List_List)

Read only

A list of incoming messages that have neither been acknowledged nor rejected. Its items can be removed using AcknowledgePendingMessages.

Change notification is via MessageReceived and PendingMessagesRemoved.

(Permalink)

## DeliveryReportingSupport — u (Delivery_Reporting_Support_Flags)

Read only
This property is immutable which means that it can never change once the channel has been created. Immutable properties SHOULD appear in the channel detail list of NewChannels signals.
A bitfield indicating features supported by this channel.

# Types

Simple Type (Permalink)

## Message_ID — u

A unique-per-channel identifier for an incoming message. These SHOULD be allocated in a way that minimizes collisions (in particular, message IDs SHOULD NOT be re-used until all of the 32-bit integer space has already been used).
Simple Type (Permalink)

## Message_Header_Key — s

Added in 0.19.8.
Changed in 0.21.5. Removed `protocol-token`—which had never been implemented—and respecified `message-token` not to have unimplementable uniqueness guarantees.

Well-known keys for the first Message_Part of a message, which contains metadata about the message as a whole, along with the corresponding value types. Some keys make sense for both incoming and outgoing messages, while others are only meaningful for one or the other.

message-token (s - Protocol_Message_Token)

  An opaque identifier for the message, as used by the underlying protocol. For outgoing messages, this SHOULD be globally unique; for incoming messages, this is not guaranteed to uniquely identify a message, even within the scope of a single channel or contact; the only guarantee made is that two messages with different `message-token` headers are different messages.

  Clients wishing to determine whether a new message with the `scrollback` header matches a previously-logged message with the same `message-token` SHOULD compare the message's sender, contents, `message-sent` or `message-received` timestamp, etc. Note that, in XMPP, the server only supplies a timestamp for scrollback messages, not for messages received while you are in a room; thus, non-scrollback messages will lack a `message-sent` timestamp.

  ##### Rationale:

  In practice, most protocols do not provide globally-unique identifiers for messages. Connection managers, being stateless, do not have the necessary information — namely, IM logs — to generate reliable unique tokens for messages.

  For instance, some XMPP clients (including Gabble) stamp messages they send with unique identifiers, but others number outgoing messages in a conversation from 1 upwards.

message-sent (x - Unix_Timestamp64)
  The time the message was sent (if unavailable, the time it arrived at a central server MAY be used). Omitted if no reasonable approximation is available; SHOULD always be present on outgoing messages.
message-received (x - Unix_Timestamp64)
  The time the message was received locally. SHOULD always be present.
message-sender (u - Contact_Handle)
  The contact who sent the message. If 0 or omitted, the contact who sent the message could not be determined.
message-sender-id (s)
  The identifier of the contact who sent the message. If empty or omitted, the contact who sent the message could not be determined.
sender-nickname (s)
  The nickname chosen by the sender of the message, which can be different for each message in a conversation.
message-type (u - Channel_Text_Message_Type)
  The type of message; if omitted, Channel_Text_Message_Type_Normal MUST be assumed. MAY be omitted for normal chat messages.
supersedes (s – Protocol_Message_Token)
  If present, this message supersedes a previous message, identified by its `message-token` header. The user interface MAY, for example, choose to replace the superseded message with this message, or grey out the superseded message.

  ##### Rationale:

  Skype, for example, allows the user to amend messages they have already sent (to correct typos, etc.).
  Connection Managers SHOULD represent repeatedly edited messages in the following form:

                      message {token = a};
                      message {token = b, supersedes = a};
                      message {token = c, supersedes = a};

  ##### Rationale:

  The alternative form is:

                        message {token = a};
                        message {token = b, supersedes = a};
                        message {token = c, supersedes = b};

  but it is more difficult to implement in UIs/loggers, and it breaks irrecoverably if message b is lost. If a CM is forced to use this form, it should be tested extensively for interoperability with existing clients.
  Clients should deal gracefully if the original message gets lost, but one or more corrections to it get through:

                      message {token = x} gets lost;
                      message {token = y, supersedes = x};
                      message {token = z, supersedes = x};

  ##### Rationale:

  This is the form that CMs will use to mean "I know that this message was edited, but I don't know what it originally said." It is often in the interests of the remote side for message x to be lost (e.g. to hide embarassing mistakes or sensitive information) so it might not be possible to retrieve it (even on protocols with reliable message-delivery guarantees).
original-message-sent (x - Unix_Timestamp64)
  The `message-sent` header of the message that this one supersedes. This key should only be present if `supersedes` is also present. It MAY be used as a hint to help clients locate the original message in its logs. If present, comparing the tuple (original-message-sent, supersedes) with (message-sent, message-token) SHOULD be enough to uniquely identify the original message.
original-message-received (x - Unix_Timestamp64)
  The `message-received` header of the message that this one supersedes. This key should only be present if `supersedes` is also present. It MAY be used as a hint in a similar way to `original-message-sent`.
pending-message-id (u - Message_ID)
  The incoming message ID. This MUST NOT be present on outgoing messages. Clients SHOULD NOT store this key - it is only valid for as long as the message remains unacknowledged.
interface (s - DBus_Interface)
  This message is specific to the given interface, which is not Text. It SHOULD be ignored if that interface is not supported. (Note that an 'interface' key can also appear on the second and subsequent parts, where it indicates that that part (only) should be ignored if unsupported.)
scrollback (b)
  If present and true, the incoming message was part of a replay of message history. This flag does not make sense on outgoing messages and SHOULD NOT appear there.
rescued (b)
  If present and true, the incoming message has been seen in a previous channel during the lifetime of the Connection, but had not been acknowledged when that channel closed, causing an identical channel (in which the message now appears) to open. It does not make sense on outgoing messages, and SHOULD NOT appear there.

Simple Type (Permalink)

## Message_Body_Key — s

Added in 0.19.8.

Well-known keys for the second and subsequent Message_Parts of a message, which contain the message content, along with the corresponding value types.

identifier (s — Protocol_Content_Identifier)
  An opaque identifier for this part. Parts of a message MAY reference other parts by treating this identifier as if it were a MIME Content-ID and using the cid: URI scheme.
alternative (s)

  If present, this part of the message is an alternative for all other parts with the same value for "alternative". Clients SHOULD only display one of them (this is expected to be used for XHTML messages in a future version of this specification).

  If omitted, this part is not an alternative for any other part.

  Parts of a message MAY reference the group of alternatives as a whole (i.e. a reference to whichever of them is chosen) by treating this identifier as if it were the MIME Content-ID of a multipart/alternative part, and using the cid: URI scheme.

content-type (s)

  The MIME type of this part. See the documentation for MessageReceived and MessageSent for notes on the special status of "text/plain" parts.

  Connection managers MUST NOT signal parts without a 'content-type' key; if a protocol provides no way to determine the MIME type, the connection manager is responsible for guessing it, but MAY fall back to "text/plain" for text and "application/octet-stream" for non-text.

  Clients MUST ignore parts without a 'content-type' key, which are reserved for future expansion.

  When sending messages, clients SHOULD normalize the content-type to lower case, but connection managers SHOULD NOT rely on this. When signalling sent or received messages, connection managers MUST normalize the content-type to lower case.

lang (s)
  The natural language of this part, identified by a RFC 3066 language tag.

  ##### Rationale:

  XMPP allows alternative-selection by language as well as by content-type.
size (u)
  The size in bytes (if needs-retrieval is true, this MAY be an estimated or approximate size). SHOULD be omitted if 'content' is provided.

  ##### Rationale:

  There's no point in providing the size if you're already providing all the content.
thumbnail (b)

  This part is a thumbnail. To represent an image together with its thumbnail in a single message, there should be one part for the full image followed by a part for the thumbnail (following the “more complete versions first” requirement), with the same 'alternative' value. For example:

      [ ... ,
        { 'alternative': 'catphoto',
          'content-type': 'image/jpeg',
          'size': 150000,
          'content': [0xFF, 0xD8, ... 0xFF 0xD9],
        },
        { 'alternative': 'catphoto',
          'content-type': 'image/jpeg'
          'size': 1024,
          'thumbnail': True,
          'content': [0xFF, 0xD8, ... 0xFF 0xD9],
        },
        ...
      ]

needs-retrieval (b)
  If false or omitted, the connection manager already holds this part in memory. If present and true, this part must be retrieved on demand (like MIME's `message/external-body`) by a mechanism to be defined later.

  ##### Rationale:

  The mechanism was meant to be the now-deprecated GetPendingMessageContent, but that didn't work out. It's worth leaving the header in in preparation for a future mechanism.
truncated (b)
  The content available via the 'content' key has been truncated by the server or connection manager (equivalent to Channel_Text_Message_Flag_Truncated in the Text interface).
content (s or ay)
  The part's content, if it is available and sufficiently small to include here (implies that 'needs-retrieval' is false or omitted). Otherwise, omitted. If the part is human-readable text or HTML, the value for this key MUST be a UTF-8 string (D-Bus signature 's'). If the part is not text, the value MUST be a byte-array (D-Bus signature 'ay'). If the part is a text-based format that is not the main body of the message (e.g. an iCalendar or an attached XML document), the value SHOULD be a UTF-8 string, transcoding from another charset to UTF-8 if necessary, but MAY be a byte-array (of unspecified character set) if transcoding fails or the source charset is not known.
interface (s - DBus_Interface)
  This part is specific to the given interface, which is not Text. It SHOULD be ignored if that interface is not supported. (Note that an 'interface' key can also appear on the first part, where it indicates that the entire message should be ignored if unsupported.)

Simple Type (Permalink)

## Delivery_Report_Header_Key — s

Added in 0.19.8.

Well-known keys for the first Message_Part of a delivery report, along with the corresponding value types. Some of these are special-cases of headers defined by Message_Header_Key.

message-sender (u - Contact_Handle, as defined by Message_Header_Key)
  MUST be the intended recipient of the original message, if available (zero or omitted if the intended recipient is unavailable or is not a contact, e.g. a chatroom), even if the delivery report actually came from an intermediate server.
message-type (u - Channel_Text_Message_Type, as defined by Message_Header_Key)
  MUST be Channel_Text_Message_Type_Delivery_Report.
delivery-status (u - Delivery_Status)
  The status of the message. All delivery reports MUST contain this key in the first Message_Part.
delivery-token (s - Protocol_Message_Token)

  An identifier for the message to which this delivery report refers. MUST NOT be an empty string. Omitted if not available.

  Clients may match this against the token produced by the SendMessage method and MessageSent signal. A status report with no token could match any sent message, and a sent message with an empty token could match any status report. If multiple sent messages match, clients SHOULD use some reasonable heuristic.

  ##### Rationale:

  In an ideal world, we could unambiguously match reports against messages; however, deployed protocols are not ideal, and not all reports and messages can be matched.
delivery-error (u - Channel_Text_Send_Error)
  The reason for the failure. MUST be omitted if this was a successful delivery; SHOULD be omitted if it would be Channel_Text_Send_Error_Unknown.
delivery-dbus-error (s - DBus_Error_Name)
  The reason for the failure, specified as a (possibly implementation-specific) D-Bus error. MUST be omitted if this was a successful delivery. If set, the 'delivery-error' key SHOULD be set to the closest available value.
delivery-error-message (s)
  Debugging information on why the message could not be delivered. MUST be omitted if this was a successful delivery; MAY always be omitted.
delivery-echo (aa{sv} - Message_Part[])

  The message content which can be omitted if no content is available. Content MAY have been truncated, message parts MAY have been removed, and message parts MAY have had their content removed (i.e. the message part metadata is present, but the 'content' key is not).

  ##### Rationale:

  Some protocols, like XMPP, echo the failing message back to the sender. This is sometimes the only way to match it against the sent message, so we include it here.

Simple Type (Permalink)

## Protocol_Message_Token — s

An opaque token used to identify messages in the underlying. protocol. As a special case, the empty string indicates that there is no particular identification for a message.

CM implementations SHOULD use an identifier expected to be unique, such as a UUID, for outgoing messages (if possible).

Some protocols can only track a limited number of messages in a small message-ID space (SMS messages are identified by a single byte), and some implementations send non-unique identifiers (some XMPP clients use very simple message IDs, such as an incrementing integer that resets to 1 at the beginning of each connection). As a result, clients MUST NOT assume that protocol tokens will not be re-used.

In particular, clients SHOULD use a heuristic to assign delivery reports to messages, such as matching on message content or timestamp (if available), or assuming that the delivery report refers to the most recent message with that ID.

Simple Type (Permalink)

## Protocol_Content_Identifier — s

A protocol-specific identifier for a blob of content, as used for the `identifier` key in a Message_Part. The same identifier MAY be re-used if the same content, byte-for-byte, appears as a part of several messages.

##### Rationale:

On XMPP, these identifiers might be Content-IDs for custom smileys implemented using XEP-0232 Bits of Binary; the same smiley might well appear in multiple messages.

Enum (Permalink)

## Channel_Text_Send_Error — u

- Unknown (0)
An unknown error occurred
- Offline (1)
The requested contact was offline
- Invalid_Contact (2)
The requested contact is not valid
- Permission_Denied (3)
The user does not have permission to speak on this channel
- Too_Long (4)
The outgoing message was too long and was rejected by the server
- Not_Implemented (5)
The channel doesn't support sending text messages to the requested contact

Enum (Permalink)

## Channel_Text_Message_Type — u

The type of message.

- Normal (0)
An ordinary chat message. Unknown types SHOULD be treated like this.
- Action (1)
An action which might be presented to the user as "* <sender> <action>", such as an IRC CTCP ACTION (typically selected by the "/me" command). For example, the text of the message might be "drinks more coffee".
- Notice (2)
A one-off or automated message not necessarily expecting a reply
- Auto_Reply (3)
An automatically-generated reply message.
- Delivery_Report (4)
A delivery report. See Message_Part for the format that delivery reports must take.

Enum (Permalink)

## Delivery_Status — u

The status of a message as indicated by a delivery report.

If this enum is extended in future specifications, this should only be to add new, non-overlapping conditions (i.e. all failures should still be signalled as either Temporarily_Failed or Permanently_Failed). If additional detail is required (e.g. distinguishing between the various types of permanent failure) this will be done using additional Delivery_Report_Header_Keys.

- Unknown (0)
The message's disposition is unknown. Clients SHOULD consider all messages to have status Delivery_Status_Unknown unless otherwise specified; connection managers SHOULD NOT signal this delivery status explicitly.
- Delivered (1)
The message has been delivered to the intended recipient.
- Temporarily_Failed (2)
Delivery of the message has failed. Clients SHOULD notify the user, but MAY automatically try sending another copy of the message.

##### Rationale:

Similar to errors with type="wait" in XMPP; analogous to 4xx errors in SMTP.
- Permanently_Failed (3)
Delivery of the message has failed. Clients SHOULD NOT try again unless by specific user action. If the user does not modify the message or alter configuration before re-sending, this error is likely to happen again.

##### Rationale:

Similar to errors with type="cancel", type="modify" or type="auth" in XMPP; analogous to 5xx errors in SMTP.
- Accepted (4)
An intermediate server has accepted the message but the message has not been yet delivered to the ultimate recipient. The connection manager might send a Failed report or Delivered report later.

##### Rationale:

Similar to "202 Accepted" success code in SIP; analogous to 251 and 252 responses in SMTP.
- Read (5)
Added in 0.19.9.
The message has been read by the intended recipient.
- Deleted (6)
Added in 0.19.9.
The message has been deleted by the intended recipient. This MAY be signalled on its own if the message is deleted without being read, or after `Read` if the message was read before being deleted.

Flags (Permalink)

## Message_Part_Support_Flags — u

Flags indicating the level of support for message parts on this channel. They are designed such that setting more flags always implies that the channel has more capabilities.

If no flags are set, this indicates that messages may contain a single message part whose content-type is any of the types from SupportedContentTypes, possibly with some alternatives.

There is no flag indicating support for alternatives. This is because the SendMessage implementation can always accept messages containing alternatives, even if the underlying protocol does not, by deleting all alternatives except the first (most preferred) that is supported.

##### Rationale:

Each of the flags so far implies the previous flag, so we could have used a simple enumeration here; however, we've defined the message-part support indicator as a flag set for future expansion.

See SupportedContentTypes for some examples.

- One_Attachment (1)
SendMessage will accept messages containing a textual message body, plus a single attachment of any type listed in the SupportedContentTypes property. It does not make sense for this flag to be set if Message_Part_Support_Flag_Data_Only is not also set (because the connection manager can trivially provide an empty text part if necessary).
- Multiple_Attachments (2)
SendMessage will accept messages containing a textual message body, plus an arbitrary number of attachments of any type listed in the SupportedContentTypes property. It does not make sense for this flag to be set if Message_Part_Support_Flag_One_Attachment is not also set.

Flags (Permalink)

## Message_Sending_Flags — u

Flags altering the way a message is sent. The "most usual" action should always be to have these flags unset. Some indication of which flags are supported is provided by the DeliveryReportingSupport property.

- Report_Delivery (1)

Provide a successful delivery report if possible, even if this is not the default for this protocol. Ignored if delivery reports are not possible on this protocol.

##### Rationale:

In some protocols, like XMPP, it is not conventional to request or send positive delivery notifications.

Delivery failure reports SHOULD always be sent, but if this flag is present, the connection manager MAY also try harder to obtain failed delivery reports or allow them to be matched to outgoing messages.

- Report_Read (2)
Added in 0.19.9.

Provide a delivery report when the message is read by the recipient, even if this is not the default for this protocol. Ignored if read reports are not possible on this protocol.

- Report_Deleted (4)
Added in 0.19.9.

Provide a delivery report when the message is deleted by the recipient, even if this is not the default for this protocol. Ignored if such reports are not possible on this protocol.

Flags (Permalink)

## Delivery_Reporting_Support_Flags — u

Flags indicating the level of support for delivery reporting on this channel, as found on the DeliveryReportingSupport property. Any future flags added to this set will conform to the convention that the presence of an extra flag implies that more operations will succeed. Note that CMs may always provide more reports than are requested in the Message_Sending_Flags passed to SendMessage.

##### Rationale:

If senders want delivery reports, they should ask for them. If they don't want delivery reports, they can just ignore them, so there's no need to have capability discovery for what will happen if a delivery report isn't requested.

- Receive_Failures (1)
Clients MAY expect to receive negative delivery reports if Message_Sending_Flag_Report_Delivery is specified when sending.
- Receive_Successes (2)
Clients MAY expect to receive positive delivery reports if Message_Sending_Flag_Report_Delivery is specified when sending.
- Receive_Read (4)
Added in 0.19.9.
Clients MAY expect to receive Delivery_Status `Read` reports if Message_Sending_Flag_Report_Read is specified when sending.
- Receive_Deleted (8)
Added in 0.19.9.
Clients MAY expect to receive Delivery_Status `Deleted` reports if Message_Sending_Flag_Report_Deleted is specified when sending.

Mapping (Permalink)

## Message_Part — a{sv}

Part of a message's content. In practice, this mapping never appears in isolation: incoming messages are represented by a list of Message_Part mappings in the MessageReceived signal, and outgoing messages are passed to SendMessage as a list of these mappings.

The first part of the message contains "headers", which refer to the entire message. The second and subsequent parts contain the message's content, including plain text, formatted text and/or attached files. Well-known keys for the header and body parts are defined by the Message_Header_Key and Message_Body_Key types, respectively. It is an error for a connection manager to put keys referring to the message as a whole in the second or subsequent Message_Part, or keys intended for body parts in the first Message_Part; clients MUST recover from this error by ignoring these mis-placed keys.

##### Rationale:

Instead of representing messages as aa{sv} where the first dictionary is special (a dictionary of headers), we could have used a signature like (a{sv}aa{sv}) to separate out the headers and the body parts.

However, this would make access to the messages more awkward. In Python, the syntax for access to a header field would remain `message[0]['message-type']`, but access to a body field in the second body part would change from `message[2]['content'] to message[1][1]['content']`. In GLib, the message would change from being a `GPtrArray(GHashTable)` to being a `GValueArray(GHashTable, GPtrArray(GHashTable))` which is rather inconvenient to dereference.

In any group of parts with the same non-empty value for the `alternative` key (which represent alternative versions of the same content), more faithful versions of the intended message MUST come before less faithful versions (note that this order is the opposite of MIME `multipart/alternative` parts). Clients SHOULD display the first alternative that they understand.

##### Rationale:

Specifying the preference order means that if the underlying protocol doesn't support alternatives, the CM can safely delete everything apart from the first supported alternative when sending messages.

The order is the reverse of MIME because MIME's rationale for placing the "plainest" part first (legibility in pre-MIME UAs) does not apply to us, and placing the most preferred part first simplifies display (a client can iterate the message in order, display the first alternative that it understands, and skip displaying all subsequent parts with the same "alternative" key).

Clients SHOULD present all parts that are not redundant alternatives in the order they appear in this array, possibly excluding parts that are referenced by another displayed part. It is implementation-specific how the parts are presented to the user.

##### Rationale:

This allows CMs to assume that all parts are actually shown to the user, even if they are not explicitly referenced - we do not yet recommend formatted text, and there is no way for plain text to reference an attachment since it has no concept of markup or references. This also forces clients to do something sensible with messages that consist entirely of "attachments", with no "body" at all.

For instance, when displaying the above example, a client that understands the HTML part should display the JPEG image once, between the two lines "Here is a photo of my cat:" and "Isn't it cute?"; it may additionally present the image in some way for a second time, after "Isn't it cute?", or may choose not to.

A client that does not understand HTML, displaying the same message, should display the plain-text part, followed by the JPEG image.

Connection managers, clients and extensions to this specification SHOULD NOT include Handles as values in a Message_Part, except for `message-sender` in the header.

##### Rationale:

Reference-counting handles in clients becomes problematic if the channel proxy cannot know whether particular map values are handles or not.

#### Example messages

A rich-text message, with an embedded image, might be represented as:

    [
      {
        'message-token': '9de9546a-3400-4419-a505-3ea270cb834c',
        'message-sender': 42,
        'message-sent': 1210067943,
        'message-received': 1210067947,
        'message-type': 0,              # = Channel_Text_Message_Type_Normal
        'pending-message-id': 437,
      },
      { 'alternative': 'main',
        'content-type': 'text/html',
        'content': 'Here is a photo of my cat:<br />' +
                   '<img src="cid:catphoto" alt="lol!" />' +
                   '<br />Isn't it cute?',
      },
      { 'alternative': 'main',
        'content-type': 'text/plain',
        'content': 'Here is a photo of my cat:\n[IMG: lol!]\nIsn't it cute?',
      },
      { 'identifier': 'catphoto',
        'content-type': 'image/jpeg',
        'size': 101000,
        'needs-retrieval': True,
      },
    ]

telepathy-ring, Nokia's GSM connection manager, represents vCards sent via SMS as:

    [
      {
        'message-token': '9de9546a-3400-4419-a505-3ea270cb834c',
        'message-sender': 42,
        'message-sent': 1210067943,
        'message-received': 1210067947,
        'message-type': 0,              # = Channel_Text_Message_Type_Normal
        'pending-message-id': 437,
      },
      { 'content-type': 'text/x-vcard',
        'content': [ 0x66, 0x69, 0x71, ...], # vCard data as an array of bytes
      },
    ]

### Delivery reports

Delivery reports are also represented as messages with the `message-type` header mapping to Channel_Text_Message_Type Delivery_Report. Delivery reports SHOULD contain the `message-sender` header, mapping to the intended recipient of the original message, if possible; other headers specific to delivery reports are defined by the Delivery_Report_Header_Key type. The second and subsequent parts, if present, are a human-readable report from the IM service.

The result of attempting to send delivery reports using SendMessage is currently undefined.

#### Example delivery reports

A minimal delivery report indicating permanent failure of the sent message whose token was `b9a991bd-8845-4d7f-a704-215186f43bb4` for an unknown reason

      [{
      # header
      'message-sender': 123,
      'message-type': Channel_Text_Message_Type_Delivery_Report,
      'delivery-status': Delivery_Status_Permanently_Failed,
      'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
      }
      # no body
      ]

A delivery report where the failed message is echoed back to the sender rather than being referenced by ID, and the failure reason is that this protocol cannot send messages to offline contacts such as the contact with handle 123

      [{ # header
      'message-sender': 123,
      'message-type': Channel_Text_Message_Type_Delivery_Report,
      'delivery-status': Delivery_Status_Temporarily_Failed,
      'delivery-error': Channel_Text_Send_Error_Offline,
      'delivery-echo':
          [{ # header of original message
          'message-sender': 1,
          'message-sent': 1210067943,
          },
          { # body of original message
          'content-type': 'text/plain',
          'content': 'Hello, world!',
          }]
        ],

      # no body
      ]

A maximally complex delivery report: the server reports a bilingual human-readable failure message because the user sent a message "Hello, world!" with token `b9a991bd-8845-4d7f-a704-215186f43bb4` to a contact with handle 123, but that handle represents a contact who does not actually exist

      [{ # header
      'message-sender': 123,
      'message-type': Channel_Text_Message_Type_Delivery_Report,
      'delivery-status': Delivery_Status_Permanently_Failed,
      'delivery-error': Channel_Text_Send_Error_Invalid_Contact,
      'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
      'delivery-echo':
          [{ # header of original message
          'message-sender': 1,
          'message-sent': 1210067943,
          },
          { # body of original message
          'content-type': 'text/plain',
          'content': 'Hello, world!',
          }]
        ],
      },
      { # message from server (alternative in English)
      'alternative': '404',
      'content-type': 'text/plain',
      'lang': 'en',
      'content': 'I have no contact with that name',
      },
      { # message from server (alternative in German)
      'alternative': '404'.
      'content-type': 'text/plain',
      'lang': 'de',
      'content', 'Ich habe keinen Kontakt mit diesem Namen',
      }
      ]

A minimal delivery report indicating successful delivery of the sent message whose token was `b9a991bd-8845-4d7f-a704-215186f43bb4`

      [{
      # header
      'message-sender': 123,
      'message-type': Channel_Text_Message_Type_Delivery_Report,
      'delivery-status': Delivery_Status_Delivered,
      'delivery-token': 'b9a991bd-8845-4d7f-a704-215186f43bb4',
      }
      # no body
      ]

- Key — s
A key, which SHOULD be one of the well-known keys specified by Message_Header_Key, Message_Body_Key or Delivery_Report_Header_Key if possible.
- Value — v
The value corresponding to the given key, which SHOULD be one of the specified types for well-known keys.