QXmppMucManagerV2 Class

XEP-0045: Multi-User Chat manager. More...

Header: #include <QXmppMucManagerV2.h>
Since: QXmpp 1.13
Inherits: QXmppClientExtension and QXmppMessageHandler

Public Functions

QXmppMucManagerV2()
(since QXmpp 1.16) QXmppTask<QXmpp::Result<QXmppMucRoomV2>> createRoom(QString serviceJid, QString nickname, std::optional<QString> roomName = std::nullopt)
(since QXmpp 1.16) QXmppTask<QXmpp::SendResult> declineInvitation(const QString &roomJid, QXmpp::Muc::Decline decline)
std::optional<QXmppMucRoomV2> findRoom(const QString &jid)
QXmppTask<QXmpp::Result<QXmppMucRoomV2>> joinRoom(const QString &jid, const QString &nickname)
QXmppTask<QXmpp::Result<QXmppMucRoomV2>> joinRoom(const QString &jid, const QString &nickname, std::optional<QXmpp::Muc::HistoryOptions> history, const QString &password = {})
(since QXmpp 1.16) QBindable<QStringList> mucServices() const
(since QXmpp 1.16) QBindable<bool> mucServicesLoaded() const
(since QXmpp 1.16) QXmppTask<QXmpp::Result<QString>> requestUniqueRoomName(QString serviceJid)
(since QXmpp 1.16) std::chrono::milliseconds selfPingSilenceThreshold() const
(since QXmpp 1.16) QXmppTask<QXmpp::SendResult> sendDirectInvitation(const QString &to, QXmpp::Muc::DirectInvitation invitation, QXmppMessage message = {})
(since QXmpp 1.16) void setSelfPingSilenceThreshold(std::chrono::milliseconds threshold)

Reimplemented Public Functions

virtual QStringList discoveryFeatures() const override

Signals

(since QXmpp 1.16) void directInvitationReceived(const QXmpp::Muc::DirectInvitation &invitation, const QString &from, const QXmppMessage &message)
(since QXmpp 1.16) void invitationDeclined(const QString &roomJid, const QXmpp::Muc::Decline &decline)
(since QXmpp 1.16) void invitationReceived(const QString &roomJid, const QXmpp::Muc::Invite &invite, const QString &password)
void messageReceived(const QString &roomJid, const QXmppMessage &message)
(since QXmpp 1.17) void messageRetracted(const QString &roomJid, const QXmppMessageRetraction &retraction)
void participantJoined(const QString &roomJid, const QXmppMucParticipant &participant)
void participantLeft(const QString &roomJid, const QXmppMucParticipant &participant, QXmpp::Muc::LeaveReason reason)
void removedFromRoom(const QString &roomJid, QXmpp::Muc::LeaveReason reason, const std::optional<QXmpp::Muc::Destroy> &destroy)
void roomHistoryReceived(const QString &roomJid, const QList<QXmppMessage> &messages)
(since QXmpp 1.16) void voiceRequestReceived(const QString &roomJid, const QXmppMucVoiceRequest &request)

Detailed Description

Setup

QXmppMucManagerV2 requires QXmppDiscoveryManager to be registered with the client:

auto *muc   = new QXmppMucManagerV2;
auto *disco = new QXmppDiscoveryManager;
client.addExtension(muc);
client.addExtension(disco);

For bookmark management, see QXmppPepBookmarkManager.

Joining a room

Call joinRoom() to join a room. The returned task resolves once all initial occupant presences have been received, so the participant list is already populated when the task finishes.

muc->joinRoom(u"room@conference.example.org"_s, u"alice"_s).then(this, [](auto result) {
    if (auto *room = std::get_if<QXmppMucRoomV2>(&result)) {
        qDebug() << "Joined as" << room->nickname().value();
    }
});

After joining, retrieve the room handle at any time via room():

auto r = muc->room(u"room@conference.example.org"_s);
if (r.isValid()) {
    // use r
}

Sending messages

auto r = muc->room(u"room@conference.example.org"_s);
QXmppMessage msg;
msg.setBody(u"Hello, room!"_s);
r.sendMessage(std::move(msg)).then(this, [](auto result) {
    // handle result
});

Creating a room

createRoom() creates a new reserved (locked) room. The task resolves once the server confirms room creation and the configuration form has been fetched. Configure the room via setRoomConfig() to unlock it, or cancel with cancelRoomCreation().

muc->createRoom(u"newroom@conference.example.org"_s, u"alice"_s).then(this, [](auto result) {
    if (auto *room = std::get_if<QXmppMucRoomV2>(&result)) {
        auto config = room->roomConfig().value().value_or(QXmppMucRoomConfig{});
        config.setName(u"My New Room"_s);
        room->setRoomConfig(config);
    }
});

Moderation and affiliation management

Use setRole() to change a participant's role (e.g. kick or grant/revoke voice) and setAffiliation() to change a user's persistent affiliation (e.g. ban or grant membership). Use requestAffiliationList() to retrieve the full list of users with a given affiliation.

// Kick a participant
r.setRole(participant, QXmpp::Muc::Role::None, u"Misbehaving"_s);

// Ban a user
r.setAffiliation(u"user@example.org"_s, QXmpp::Muc::Affiliation::Outcast);

// Fetch the member list
r.requestAffiliationList(QXmpp::Muc::Affiliation::Member).then(this, [](auto result) {
    if (auto *list = std::get_if<QList<QXmpp::Muc::Item>>(&result)) {
        for (const auto &item : *list) {
            qDebug() << item.jid() << item.affiliation();
        }
    }
});

Room configuration

Call requestRoomConfig() to retrieve a typed configuration form. Edit the returned QXmppMucRoomConfig and submit it with setRoomConfig(). Pass watch = true (or call setWatchRoomConfig()) to be notified of configuration changes via the roomConfig() bindable.

r.requestRoomConfig(true).then(this, [r](auto result) mutable {
    if (auto *config = std::get_if<QXmppMucRoomConfig>(&result)) {
        config->setMaxUsers(50);
        r.setRoomConfig(*config);
    }
});

Participants and permissions

participants() returns lightweight handles to all current occupants. selfParticipant() returns your own participant entry, which exposes your current role and affiliation as QBindables.

The capability QBindables (canSendMessages(), canSetRoles(), canConfigureRoom(), …) update automatically whenever the MUC service changes your permissions.

Warning: THIS API IS NOT FINALIZED YET and may still change in incompatible ways before it is released.

Member Function Documentation

QXmppMucManagerV2::QXmppMucManagerV2()

Default constructor.

[since QXmpp 1.16] QXmppTask<QXmpp::Result<QXmppMucRoomV2>> QXmppMucManagerV2::createRoom(QString serviceJid, QString nickname, std::optional<QString> roomName = std::nullopt)

Creates a new reserved (locked) MUC room on serviceJid with the given nickname.

If roomName is set, the room is created at roomName@serviceJid. If roomName is unset, createRoom() asks the service for a unique localpart via XEP-0307 (muc#unique); if that query fails for any reason (service does not support XEP-0307, IQ error, …), it falls back to a client-generated UUID localpart so creation still succeeds against any compliant MUC service.

The room is created in a locked state; no other users can join until the owner submits the configuration form via QXmppMucRoomV2::setRoomConfig(). The task resolves once the server has confirmed room creation (XEP-0045 status code 201) and the configuration form has been fetched. If the local state machine detects that the room is already tracked, the task fails immediately.

This function was introduced in QXmpp 1.16.

[since QXmpp 1.16] QXmppTask<QXmpp::SendResult> QXmppMucManagerV2::declineInvitation(const QString &roomJid, QXmpp::Muc::Decline decline)

Declines a mediated invitation by sending decline as a message to roomJid.

Can be called before joining the room. Set decline.to() to the inviter's JID.

This function was introduced in QXmpp 1.16.

[signal, since QXmpp 1.16] void QXmppMucManagerV2::directInvitationReceived(const QXmpp::Muc::DirectInvitation &invitation, const QString &from, const QXmppMessage &message)

Emitted when a XEP-0249: Direct MUC Invitations invitation is received.

The from is the full JID of the user who sent the invitation, and message is the full message stanza it was received in.

This function was introduced in QXmpp 1.16.

[override virtual] QStringList QXmppMucManagerV2::discoveryFeatures() const

Reimplements: QXmppClientExtension::discoveryFeatures() const.

Supported service discovery features.

std::optional<QXmppMucRoomV2> QXmppMucManagerV2::findRoom(const QString &jid)

Returns a handle for the tracked room at jid, or std::nullopt if the manager has no state for this JID.

Inactive rooms (left but still referenced by a caller handle) are revived transparently so that leave → findRoom observes the same underlying state.

[signal, since QXmpp 1.16] void QXmppMucManagerV2::invitationDeclined(const QString &roomJid, const QXmpp::Muc::Decline &decline)

Emitted when the room at roomJid reports that an invitee declined an invitation via decline.

This function was introduced in QXmpp 1.16.

[signal, since QXmpp 1.16] void QXmppMucManagerV2::invitationReceived(const QString &roomJid, const QXmpp::Muc::Invite &invite, const QString &password)

Emitted when a mediated invite is received from the room at roomJid, protected by the given password (if any).

The user is not yet in the room at this point. Call joinRoom() to accept or declineInvitation() to decline.

This function was introduced in QXmpp 1.16.

QXmppTask<QXmpp::Result<QXmppMucRoomV2>> QXmppMucManagerV2::joinRoom(const QString &jid, const QString &nickname)

Joins the MUC room at jid with the given nickname.

Sends an initial presence to the room and waits for all occupant presences that the MUC service sends back. The returned task resolves once the server sends the self-presence with status code 110, meaning the participant list is already fully populated when the task finishes.

If a join for the same room is already in progress the task fails immediately. If the room is already joined the existing room handle is returned as a success.

jid is the bare JID of the room (e.g. room\@conference.example.org). nickname is the desired nickname — must not be empty.

QXmppTask<QXmpp::Result<QXmppMucRoomV2>> QXmppMucManagerV2::joinRoom(const QString &jid, const QString &nickname, std::optional<QXmpp::Muc::HistoryOptions> history, const QString &password = {})

Joins the room with optional history request parameters and an optional password for password-protected rooms (XEP-0045: Multi-User Chat §7.2.5).

This is an overloaded function.

[signal] void QXmppMucManagerV2::messageReceived(const QString &roomJid, const QXmppMessage &message)

Emitted when a groupchat message is received in the joined room at roomJid.

[signal, since QXmpp 1.17] void QXmppMucManagerV2::messageRetracted(const QString &roomJid, const QXmppMessageRetraction &retraction)

Emitted when a message in the joined room at roomJid is retracted via XEP-0424: Message Retraction or XEP-0425: Moderated Message Retraction.

The retracted message is identified by retraction.retractedId() (the message's XEP-0359: stanza id). For moderated retractions, retraction.moderation() carries the moderator and reason. Spoofed moderated retractions (claiming moderation but not sent by the room itself) never trigger this signal.

The retraction message is also delivered through messageReceived() (with its QXmppMessage::retraction() set), so clients that need the raw stanza still receive it.

This function was introduced in QXmpp 1.17.

[since QXmpp 1.16] QBindable<QStringList> QXmppMucManagerV2::mucServices() const

Returns the JIDs of discovered MUC services on the server.

The list is populated automatically after connecting and updated reactively.

This function was introduced in QXmpp 1.16.

[since QXmpp 1.16] QBindable<bool> QXmppMucManagerV2::mucServicesLoaded() const

Returns whether MUC service discovery has completed.

This function was introduced in QXmpp 1.16.

[signal] void QXmppMucManagerV2::participantJoined(const QString &roomJid, const QXmppMucParticipant &participant)

Emitted when participant joins the room at roomJid.

[signal] void QXmppMucManagerV2::participantLeft(const QString &roomJid, const QXmppMucParticipant &participant, QXmpp::Muc::LeaveReason reason)

Emitted when participant leaves the room at roomJid for the given reason.

[signal] void QXmppMucManagerV2::removedFromRoom(const QString &roomJid, QXmpp::Muc::LeaveReason reason, const std::optional<QXmpp::Muc::Destroy> &destroy)

Emitted when we are forcibly removed from the room at roomJid (kicked, banned, etc.) for the given reason.

The room state is still accessible during this signal's emission. After all handlers return, the room state is cleaned up. The destroy parameter contains room destruction info if the reason is RoomDestroyed.

[since QXmpp 1.16] QXmppTask<QXmpp::Result<QString>> QXmppMucManagerV2::requestUniqueRoomName(QString serviceJid)

Requests a unique room localpart from the MUC serviceJid (XEP-0307: Unique Room Names for Multi-User Chat).

Returns the full room JID (localpart@serviceJid) which can be passed to createRoom(). Fails if the service does not support XEP-0307: Unique Room Names for Multi-User Chat or returns an empty name.

This function was introduced in QXmpp 1.16.

[signal] void QXmppMucManagerV2::roomHistoryReceived(const QString &roomJid, const QList<QXmppMessage> &messages)

Emitted with the messages received for the room at roomJid during joining.

[since QXmpp 1.16] std::chrono::milliseconds QXmppMucManagerV2::selfPingSilenceThreshold() const

Returns the XEP-0410: MUC Self-Ping silence threshold.

After a room has been silent for this duration, the manager sends a self-ping to verify that the client is still joined. A zero value disables self-pinging entirely.

This function was introduced in QXmpp 1.16.

See also setSelfPingSilenceThreshold().

[since QXmpp 1.16] QXmppTask<QXmpp::SendResult> QXmppMucManagerV2::sendDirectInvitation(const QString &to, QXmpp::Muc::DirectInvitation invitation, QXmppMessage message = {})

Sends a direct invitation (XEP-0249) to to.

Direct invitations are sent peer-to-peer and are not routed through the room. The optional message parameter can be used to set custom extensions on the message stanza; the to, type, and invitation fields will be overwritten.

This function was introduced in QXmpp 1.16.

[since QXmpp 1.16] void QXmppMucManagerV2::setSelfPingSilenceThreshold(std::chrono::milliseconds threshold)

Sets the XEP-0410: MUC Self-Ping silence threshold.

After threshold of silence on a joined room, the manager sends an XEP-0199: XMPP Ping to the user's own occupant JID and interprets the response to detect silent server-side eviction ("ghosting"). Defaults to 5 minutes. Pass a zero duration to disable self-pinging entirely.

Ghosted rooms are surfaced via removedFromRoom() with LeaveReason::ConnectionLost.

This function was introduced in QXmpp 1.16.

See also selfPingSilenceThreshold().

[signal, since QXmpp 1.16] void QXmppMucManagerV2::voiceRequestReceived(const QString &roomJid, const QXmppMucVoiceRequest &request)

Emitted when a voice request is received in the joined moderated room at roomJid.

This signal is only emitted for moderators. The moderator can approve or deny the request by calling QXmppMucRoomV2::answerVoiceRequest().

This function was introduced in QXmpp 1.16.