Copyright © 2005-2009 Collabora Limited Copyright © 2005-2009 Nokia Corporation Copyright © 2006 INdT

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.

The Messages interface is now mandatory This interface used to have a bunch of clunky Telepathy.Properties. They have been removed in favour of D-Bus properties on the Room2, Subject2 and RoomConfig1 interfaces. 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). New APIs should use an array of Message_Part instead. A struct (message ID, timestamp in seconds since 1970-01-01 00:00 UTC, sender's handle, message type, flags, text) representing a pending text message, as returned by ListPendingMessages. The arguments of the Received signal also match this struct's signature. 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. A given message ID was not found, so no action was taken Consulting MessageTypes is preferred. An array of integer message types (ChannelTextMessageType) Return an array indicating which types of message may be sent on this channel. Consulting PendingMessages is preferred. If true, behave as if AcknowledgePendingMessages had also been called. Setting this to true is NOT RECOMMENDED for clients that have some sort of persistent message storage - clients SHOULD only acknowledge messages after they have actually stored them, which is impossible if this flag is true. An array of structs representing the pending queue. Each contains:
  • a numeric identifier
  • a Unix timestamp indicating when the message was received
  • the contact handle for the contact who sent the message
  • the message type, taken from ChannelTextMessageType
  • the bitwise-OR of the message flags from ChannelTextMessageFlags
  • the text of the message
List the messages currently in the pending queue, and optionally remove then all.
In practice, this signal was not emitted, and does not have useful semantics. This signal is emitted to indicate that an incoming message was not able to be stored and forwarded by the connection manager due to lack of memory. The MessageReceived signal is more informative. A numeric identifier for acknowledging the message A Unix timestamp indicating when the message was received The handle of the contact who sent the message The type of the message (normal, action, notice, etc.) A bitwise OR of the message flags The text of the message Signals that a message with the given id, timestamp, sender, type and text has been received on this channel. Applications that catch this signal and reliably inform the user of the message should acknowledge that they have dealt with the message with the AcknowledgePendingMessages method. The SendMessage method is more flexible. An integer indicating the type of the message The message to send

Request that a message be sent on this channel. When the message has been submitted for delivery, this method will return and the Sent signal will be emitted. If the message cannot be submitted for delivery, the method returns an error and no signal is emitted.

This method SHOULD return before the Sent signal is emitted.

When a Text channel implements the Messages interface, that "SHOULD" becomes a "MUST".

An unknown error occurred The requested contact was offline The requested contact is not valid The user does not have permission to speak on this channel The outgoing message was too long and was rejected by the server The channel doesn't support sending text messages to the requested contact Delivery reporting is now provided by the Messages interface. The error that occurred The Unix timestamp indicating when the message was sent The message type The text of the message

Signals that an outgoing message has failed to send. The error will be one of the values from ChannelTextSendError.

This signal should only be emitted for messages for which Sent has already been emitted and Send has already returned success.

older spec versions claimed that SendError was emitted instead of Sent, rather than in addition to Sent. However, the 0.17.3+ semantics were what we'd always actually implemented.
The MessageSent signal is more informative. Unix timestamp indicating when the message was sent The message type (normal, action, notice, etc) from ChannelTextMessageType The text of the message. If the message was, or will be, altered during transmission, this argument SHOULD reflect what other contacts will receive rather than being a copy of the argument to Send.

Signals that a message has been submitted for sending.

The type of message. An ordinary chat message. Unknown types SHOULD be treated like this. 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". A one-off or automated message not necessarily expecting a reply An automatically-generated reply message. A delivery report. This message type MUST NOT appear unless the channel supports the Messages interface; see Message_Part for the format that delivery reports must take. The Messages interface has an extensible data structure including separate booleans for most of these flags. The incoming message was truncated to a shorter length by the server or the connection manager.

The incoming message contained non-text content which cannot be represented by this interface, but has been signalled in the Messages interface.

Connection managers SHOULD only set this flag if the non-text content appears to be relatively significant (exactly how significant is up to the implementor). The intention is that if this flag is set, clients using this interface SHOULD inform the user that part of the message was not understood.

The incoming message was part of a replay of message history.

In XMPP multi-user chat, a few past messages are replayed when you join a chatroom. A sufficiently capable IRC connection manager could also set this flag on historical messages when connected to a proxy like bip or irssi-proxy. The existence of this flag allows loggers and UIs to use better heuristics when eliminating duplicates (a simple implementation made possible by this flag would be to avoid logging scrollback at all).

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 (the channel in which the message now appears) to open.

This means that a logger (which should already have seen the message in the previous channel) is able to recognise and ignore these replayed messages.

A channel type for sending and receiving messages. This channel type is primarily used for textual messages, but can also be used for formatted text, text with "attachments", or binary messages on some protocols.

Most of the methods and signals on this interface are deprecated, since they only support plain-text messages with limited metadata. See the mandatory Messages interface for the modern equivalents.

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.

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.

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 Group 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 Conference 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), Group interface, and optionally the Conference 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 Conference 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.

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.

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

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 Room2 interface. Instructions and examples of how to request such channels are given in said interface's description.