TelepathyQt4: MessagePart Struct Reference

| Home · All Classes · All Namespaces · Modules · Functions · Files

# MessagePart Struct Reference
[Mapping types]

`#include <TelepathyQt4/Types>`

List of all members.

## Public Member Functions

- MessagePart ()
- MessagePart (const QMap< QString, QDBusVariant > &a)
- MessagePart & operator= (const QMap< QString, QDBusVariant > &a)

## Detailed Description

Mapping type generated from the specification. Convertible with QMap<QString, QDBusVariant>, but needed to have a discrete type in the Qt4 type system.

Part of a message's content. In practice, this mapping never appears in isolation - messages are represented by a list of <tp:type>Message_Part</tp:type> mappings.

An example of how a message might look, in a Python-like syntax:

     [
       {
         '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,
       },
     ]

The first part of the message contains "headers" which refer to the entire message.
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, but clients MUST recover from this error by ignoring these keys in the second and subsequent parts.
<tp: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. </tp:rationale>
Well-known keys for the message as a whole, and the corresponding value types, include:

message-token (s)

  An opaque, globally-unique identifier for the entire message. This MAY be treated as if it were a MIME Message-ID, e.g. for the mid: and cid: URI schemes. If omitted, there is no suitable token.

message-sent (x - <tp:type>Unix_Timestamp64</tp:type>)

  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 - <tp:type>Unix_Timestamp64</tp:type>)

  The time the message was received locally. SHOULD always be present.

message-sender (u - <tp:type>Contact_Handle</tp:type>)

  The contact who sent the message. If 0 or omitted, the contact who sent the message could not be determined.

message-type (u - <tp:type>Channel_Text_Message_Type</tp:type>)

  The type of message; if omitted, Channel_Text_Message_Type_Normal MUST be assumed. MAY be omitted for normal chat messages.

pending-message-id (u - <tp:type>Message_ID</tp:type>)

  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 - <tp:type>DBus_Interface</tp:type>)

  This message is specific to the given interface, which is neither Text nor Messages. 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 matches the Scrollback flag in <tp:type>Channel_Text_Message_Flags</tp:type>). 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. This matches the Rescued flag in <tp:type>Channel_Text_Message_Flags</tp:type>; it does not make sense on outgoing messages, and SHOULD NOT appear there.

The second and subsequent parts contain the message's content, including plain text, formatted text and/or attached files.
It is an error for a connection manager to put keys referring to the message body in the first Message_Part; clients MUST recover from this error by ignoring these keys in first part.
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.
<tp: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). </tp:rationale>
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.
<tp: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. </tp:rationale>
Well-known keys for the second and subsequent parts, and the corresponding value types, include:

identifier (s)

  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 ReceivedMessage 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.

lang (s)

  The natural language of this part, identified by a RFC 3066 language tag.

  <tp:rationale> XMPP allows alternative-selection by language as well as by content-type. </tp:rationale>

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.

  <tp:rationale> There's no point in providing the size if you're already providing all the content. </tp:rationale>

needs-retrieval (b)

  If false or omitted, the connection manager already holds this part in memory. If present and true, this part will be retrieved on demand (like MIME's message/external-body), so clients should expect retrieval to take time; if this specification is later extended to provide a streaming version of GetPendingMessageContent, clients should use it for parts with this flag.

truncated (b)

  The content available via the 'content' key or GetPendingMessageContent 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 - <tp:type>DBus_Interface</tp:type>)
  This part is specific to the given interface, which is neither Text nor Messages. 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.)

Delivery reports are also represented as messages, of type Channel_Text_Message_Type_Delivery_Report, with the Non_Text_Content flag in the Text interface.
Whenever a message of type Channel_Text_Message_Type_Delivery_Report is signalled for a delivery error report, Channel.Type.Text.SendError SHOULD also be emitted; whenever Channel.Type.Text.SendError is emitted by a channel which supports this interface, a message of type Channel_Text_Message_Type_Delivery_Report MUST also be emitted.
The corresponding message in the Messages interface MUST contain "headers" for the delivery report, as specified below, in its first Message_Part.

message-sender (u - Contact_Handle as defined above)

  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 above)

  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 - Sent_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.

  <tp: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. </tp:rationale>

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, as defined by the Messages interface. 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).

  <tp: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. </tp:rationale>

  Unlike in the Messages interface, content not visible in the value for this key cannot be retrieved by another means, so the connection manager SHOULD be more aggressive about including (possibly truncated) message content in the 'content' key.

  <tp:rationale> The Messages interface needs to allow all content to be retrieved, but in this interface, the content we provide is merely a hint; so some is better than none, and it doesn't seem worth providing an API as complex as Messages' GetPendingMessageContent for the echoed message. </tp:rationale>

The second and subsequent Message_Part dictionaries, if present, are a human-readable report from the IM service.
Clients MUST NOT attempt to send delivery reports using the SendMessage method in the Messages API, and connection managers MUST NOT allow this to be done. If support for sending delivery reports is later added, it will be part of this interface.
Some example delivery reports in a Python-like syntax (in which arrays are indicated by [a, b] and dictionaries by {k1: v1, k2: v2}) follow.

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
       ]

## Constructor & Destructor Documentation

MessagePart | ( |  | ) | `[inline]`

MessagePart | ( | const QMap< QString, QDBusVariant > & | a | ) | `[inline]`

## Member Function Documentation

MessagePart& operator= | ( | const QMap< QString, QDBusVariant > & | a | ) | `[inline]`