This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
This interface extends the
Incoming messages, outgoing messages, and delivery reports are all
represented as lists of
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.
If this interface is present, clients that support it SHOULD
listen for the
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.
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 Messages 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
A list of message types which may be sent on this channel.
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.
See
Part of a message's content. In practice, this mapping never
appears in isolation: incoming messages are represented by a list of
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
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.
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.
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 message-sender
in the
header.
Reference-counting handles in clients becomes problematic if the channel proxy cannot know whether particular map values are handles or not.
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 are also represented as messages with the
message-type header mapping to
For backwards- and forwards-compatibility, whenever a delivery
error report is signalled—that is, with delivery-status
mapping to
The result of attempting to send delivery reports using
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 ]
[{ # 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 ]
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', } ]
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 ]
Well-known keys for the first
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.
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-sender
. If omitted, clients MUST
fall back to looking at message-sender
.message {token = a}; message {token = b, supersedes = a}; message {token = c, supersedes = a};
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.
message {token = x} gets lost; message {token = y, supersedes = x}; message {token = z, supersedes = x};
Well-known keys for the second and subsequent
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.
The MIME type of this part. See the documentation
for
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.
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], }, ... ]
Well-known keys for the first
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.
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).
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.
A protocol-specific identifier for a blob of content, as used for
the identifier key in a
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.
Submit a message to the server for sending.
If this method returns successfully, the message has been submitted
to the server and the
This method MUST return before the MessageSent signal is emitted.
This means that the process sending the message is the first
to see the
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
message-sender
, message-sender-id
,
message-sent
, message-received
,
pending-message-id
.
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.
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.
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.
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.
Signals that a message has been submitted for sending. This
MUST be emitted exactly once per emission of the
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).
This signal allows a process that is not the caller of SendMessage to log sent messages.
The message content (see
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 affecting how the message was sent. The flags might be a subset of those passed to SendMessage if the caller requested unsupported flags.
A list of incoming messages that have neither been acknowledged nor
rejected. This list is a more detailed version of the one returned
by
Change notification is via
The content of the requested parts. The keys in this mapping
are positions in the array of message parts; the values are
either of type 's' or 'ay' (UTF-8 text string, or byte array),
following the same rules as for the value of the 'content' key in
the
If the one of the requested part numbers was greater than zero but referred to a part that had no content (i.e. it had no 'content-type' key or no 'content' key), it is simply omitted from this mapping; this is not considered to be an error condition.
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
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
Read
if the message was read before being deleted.
Read
reports if Message_Sending_Flag_Report_Read
is specified when sending.
Deleted
reports if Message_Sending_Flag_Report_Deleted
is specified when sending.