Warning, file /network/ruqola/src/rocketchatrestapi-qt/connection.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002    SPDX-FileCopyrightText: 2017-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "connection.h"
0008 #include "restapimethod.h"
0009 #include "rocketchatqtrestapi_debug.h"
0010 
0011 #include "downloadfilejob.h"
0012 #include "serverinfojob.h"
0013 #include "settings/privateinfojob.h"
0014 
0015 #include "users/deleteownaccountjob.h"
0016 #include "users/forgotpasswordjob.h"
0017 #include "users/getavatarjob.h"
0018 #include "users/getpresencejob.h"
0019 #include "users/getusernamesuggestionjob.h"
0020 #include "users/removeothertokensjob.h"
0021 #include "users/resetavatarjob.h"
0022 #include "users/userinfojob.h"
0023 #include "users/userspresencejob.h"
0024 
0025 #include "misc/owninfojob.h"
0026 
0027 #include "authentication/loginjob.h"
0028 #include "authentication/logoutjob.h"
0029 
0030 #include "chat/deletemessagejob.h"
0031 #include "chat/followmessagejob.h"
0032 #include "chat/getmentionedmessagesjob.h"
0033 #include "chat/getmessagejob.h"
0034 #include "chat/getpinnedmessagesjob.h"
0035 #include "chat/getsnippetedmessagesjob.h"
0036 #include "chat/getstarredmessagesjob.h"
0037 #include "chat/getthreadmessagesjob.h"
0038 #include "chat/getthreadsjob.h"
0039 #include "chat/ignoreuserjob.h"
0040 #include "chat/pinmessagejob.h"
0041 #include "chat/postmessagejob.h"
0042 #include "chat/reactonmessagejob.h"
0043 #include "chat/reportmessagejob.h"
0044 #include "chat/searchmessagejob.h"
0045 #include "chat/sendmessagejob.h"
0046 #include "chat/starmessagejob.h"
0047 #include "chat/syncthreadmessagesjob.h"
0048 #include "chat/unfollowmessagejob.h"
0049 #include "chat/updatemessagejob.h"
0050 
0051 #include "channels/archivechanneljob.h"
0052 #include "channels/changechannelannouncementjob.h"
0053 #include "channels/changechanneldescriptionjob.h"
0054 #include "channels/changechannelnamejob.h"
0055 #include "channels/changechannelreadonlyjob.h"
0056 #include "channels/changechanneltopicjob.h"
0057 #include "channels/channeladdleaderjob.h"
0058 #include "channels/channeladdmoderatorjob.h"
0059 #include "channels/channeladdownerjob.h"
0060 #include "channels/channelclosejob.h"
0061 #include "channels/channeldeletejob.h"
0062 #include "channels/channelfilesjob.h"
0063 #include "channels/channelgetallusermentionsjob.h"
0064 #include "channels/channelgetcountersjob.h"
0065 #include "channels/channelinfojob.h"
0066 #include "channels/channelinvitejob.h"
0067 #include "channels/channelkickjob.h"
0068 #include "channels/channelmembersjob.h"
0069 #include "channels/channelremoveleaderjob.h"
0070 #include "channels/channelremovemoderatorjob.h"
0071 #include "channels/channelremoveownerjob.h"
0072 #include "channels/createchanneljob.h"
0073 #include "channels/getchannelrolesjob.h"
0074 #include "channels/leavechanneljob.h"
0075 #include "channels/setchanneltypejob.h"
0076 #include "channels/setjoincodechanneljob.h"
0077 
0078 #include "groups/archivegroupsjob.h"
0079 #include "groups/changegroupsannouncementjob.h"
0080 #include "groups/changegroupsdescriptionjob.h"
0081 #include "groups/changegroupsencryptedjob.h"
0082 #include "groups/changegroupsnamejob.h"
0083 #include "groups/changegroupsreadonlyjob.h"
0084 #include "groups/changegroupstopicjob.h"
0085 #include "groups/creategroupsjob.h"
0086 #include "groups/getgrouprolesjob.h"
0087 #include "groups/groupaddleaderjob.h"
0088 #include "groups/groupaddmoderatorjob.h"
0089 #include "groups/groupaddownerjob.h"
0090 #include "groups/groupremoveleaderjob.h"
0091 #include "groups/groupremovemoderatorjob.h"
0092 #include "groups/groupremoveownerjob.h"
0093 #include "groups/groupsdeletejob.h"
0094 #include "groups/groupsinfojob.h"
0095 #include "groups/groupsinvitejob.h"
0096 #include "groups/groupskickjob.h"
0097 #include "groups/leavegroupsjob.h"
0098 #include "groups/setgrouptypejob.h"
0099 
0100 #include "rooms/getdiscussionsjob.h"
0101 #include "rooms/getroomsjob.h"
0102 #include "rooms/roomfavoritejob.h"
0103 #include "rooms/roomstartdiscussionjob.h"
0104 #include "rooms/savenotificationjob.h"
0105 
0106 #include "directmessage/createdmjob.h"
0107 #include "directmessage/opendmjob.h"
0108 
0109 #include "subscriptions/markroomasreadjob.h"
0110 #include "subscriptions/markroomasunreadjob.h"
0111 
0112 #include "permissions/permissionslistalljob.h"
0113 
0114 #include "commands/getcommandsjob.h"
0115 
0116 #include "e2e/fetchmykeysjob.h"
0117 
0118 #include "autotranslate/translatesavesettingsjob.h"
0119 
0120 #include "custom/customuserstatusdeletejob.h"
0121 #include "custom/customuserstatuslistjob.h"
0122 
0123 #include "2fa/user2fadisableemailjob.h"
0124 #include "2fa/user2faenableemailjob.h"
0125 #include "2fa/user2fasendemailcodejob.h"
0126 
0127 #include "misc/statisticsjob.h"
0128 
0129 #include <QNetworkAccessManager>
0130 #include <QNetworkCookie>
0131 #include <QNetworkCookieJar>
0132 #include <QNetworkReply>
0133 #include <QTimer>
0134 
0135 using namespace std::chrono_literals;
0136 using namespace RocketChatRestApi;
0137 
0138 Connection::Connection(QObject *parent)
0139     : QObject(parent)
0140     , mNetworkAccessManager(new QNetworkAccessManager(this))
0141     , mCookieJar(new QNetworkCookieJar(this))
0142     , mRestApiMethod(new RestApiMethod)
0143 {
0144     mNetworkAccessManager->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
0145     mNetworkAccessManager->setCookieJar(mCookieJar);
0146     connect(mNetworkAccessManager, &QNetworkAccessManager::finished, this, &Connection::slotResult);
0147     connect(mNetworkAccessManager, &QNetworkAccessManager::sslErrors, this, &Connection::slotSslErrors);
0148 }
0149 
0150 Connection::~Connection()
0151 {
0152     delete mRestApiMethod;
0153 }
0154 
0155 void Connection::setRestApiLogger(RocketChatRestApi::AbstractLogger *logger)
0156 {
0157     mRuqolaLogger = logger;
0158 }
0159 
0160 void Connection::initializeCookies()
0161 {
0162     QString url = serverUrl();
0163     if (!url.isEmpty()) {
0164         QString host;
0165         QStringList lsthost = url.split(QStringLiteral("//"));
0166         if (lsthost.count() < 2) {
0167             host = url;
0168         } else {
0169             host = lsthost.at(1);
0170         }
0171 
0172         if (!mUserId.isEmpty()) {
0173             QNetworkCookie userIdCookie;
0174             userIdCookie.setDomain(host);
0175             userIdCookie.setName(QByteArrayLiteral("rc_uid"));
0176             userIdCookie.setValue(mUserId.toLocal8Bit());
0177             mCookieJar->insertCookie(userIdCookie);
0178         }
0179 
0180         if (!mAuthToken.isEmpty()) {
0181             QNetworkCookie tokenCookie;
0182             tokenCookie.setDomain(host);
0183             tokenCookie.setName(QByteArrayLiteral("rc_token"));
0184             tokenCookie.setValue(mAuthToken.toLocal8Bit());
0185             mCookieJar->insertCookie(tokenCookie);
0186         }
0187     } else {
0188         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "We can not initialize cookies as server url is empty.";
0189     }
0190 }
0191 
0192 void Connection::setAuthToken(const QString &authToken)
0193 {
0194     const bool isChanged = (mAuthToken != authToken);
0195     mAuthToken = authToken;
0196     if (isChanged) {
0197         if (!mAuthToken.isEmpty()) {
0198             initializeCookies();
0199         }
0200     }
0201 }
0202 
0203 void Connection::setUserId(const QString &userId)
0204 {
0205     const bool isChanged = (mUserId != userId);
0206     mUserId = userId;
0207     if (isChanged) {
0208         if (!mUserId.isEmpty()) {
0209             initializeCookies();
0210         }
0211     }
0212 }
0213 
0214 void Connection::slotResult(QNetworkReply *reply)
0215 {
0216     const auto error = reply->error();
0217     if (error != QNetworkReply::NoError) {
0218         const auto jobClassName = reply->property("jobClassName").value<QByteArray>();
0219         qCWarning(ROCKETCHATQTRESTAPI_LOG) << jobClassName << "error reply: " << reply->errorString();
0220 
0221         if (error == QNetworkReply::NetworkSessionFailedError && !mSessionFailed) {
0222             mSessionFailed = true;
0223             QTimer::singleShot(1ms, this, [this] {
0224                 Q_EMIT networkSessionFailedError();
0225             });
0226         }
0227     }
0228 }
0229 
0230 void Connection::slotSslErrors(QNetworkReply *reply, const QList<QSslError> &error)
0231 {
0232     qCDebug(ROCKETCHATQTRESTAPI_LOG) << " void RestApiRequest::slotSslErrors(QNetworkReply *reply, const QList<QSslError> &error)" << error.count();
0233     reply->ignoreSslErrors(error);
0234 }
0235 
0236 void Connection::setPassword(const QString &password)
0237 {
0238     mPassword = password;
0239 }
0240 
0241 void Connection::setUserName(const QString &userName)
0242 {
0243     mUserName = userName;
0244 }
0245 
0246 QString Connection::serverUrl() const
0247 {
0248     return mRestApiMethod->serverUrl();
0249 }
0250 
0251 void Connection::setServerUrl(const QString &serverUrl)
0252 {
0253     mRestApiMethod->setServerUrl(serverUrl);
0254 }
0255 
0256 QString Connection::authToken() const
0257 {
0258     return mAuthToken;
0259 }
0260 
0261 QString Connection::userId() const
0262 {
0263     return mUserId;
0264 }
0265 
0266 void Connection::login()
0267 {
0268     auto job = new LoginJob(this);
0269     connect(job, &LoginJob::loginDone, this, &Connection::slotLogin);
0270     initializeRestApiJob(job);
0271     job->setPassword(mPassword);
0272     job->setUserName(mUserName);
0273     if (!job->start()) {
0274         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job";
0275     }
0276 }
0277 
0278 void Connection::slotLogin(const QString &authToken, const QString &userId)
0279 {
0280     mAuthToken = authToken;
0281     mUserId = userId;
0282 }
0283 
0284 void Connection::slotLogout()
0285 {
0286     mAuthToken.clear();
0287     mUserId.clear();
0288 }
0289 
0290 void Connection::initializeRestApiJob(RocketChatRestApi::RestApiAbstractJob *job)
0291 {
0292     connect(job, &RocketChatRestApi::RestApiAbstractJob::failed, this, &Connection::failed);
0293 
0294     job->setNetworkAccessManager(mNetworkAccessManager);
0295     job->setRestApiLogger(mRuqolaLogger);
0296     job->setRestApiMethod(mRestApiMethod);
0297     if (job->requireHttpAuthentication()) {
0298         job->setAuthToken(mAuthToken);
0299         job->setUserId(mUserId);
0300     }
0301 }
0302 
0303 void Connection::logout()
0304 {
0305     auto job = new LogoutJob(this);
0306     connect(job, &LogoutJob::logoutDone, this, &Connection::slotLogout);
0307     initializeRestApiJob(job);
0308     if (!job->start()) {
0309         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start LogoutJob job";
0310     }
0311 }
0312 
0313 void Connection::getAvatar(const UserBaseJob::UserInfo &info)
0314 {
0315     auto job = new GetAvatarJob(this);
0316     connect(job, &GetAvatarJob::avatar, this, &Connection::avatar);
0317     connect(job, &GetAvatarJob::redownloadAvatar, this, &Connection::redownloadAvatar);
0318     initializeRestApiJob(job);
0319     job->setUserInfo(info);
0320     if (!job->start()) {
0321         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getAvatar job";
0322     }
0323 }
0324 
0325 void Connection::getPrivateSettings()
0326 {
0327     auto job = new PrivateInfoJob(this);
0328     connect(job, &PrivateInfoJob::privateInfoDone, this, &Connection::privateInfoDone);
0329     initializeRestApiJob(job);
0330     if (!job->start()) {
0331         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getPrivateSettings job";
0332     }
0333 }
0334 
0335 void Connection::getOwnInfo()
0336 {
0337     auto job = new OwnInfoJob(this);
0338     connect(job, &OwnInfoJob::ownInfoDone, this, &Connection::getOwnInfoDone);
0339     initializeRestApiJob(job);
0340     if (!job->start()) {
0341         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getOwnInfo job";
0342     }
0343 }
0344 
0345 void Connection::starMessage(const QString &messageId, bool starred)
0346 {
0347     auto job = new StarMessageJob(this);
0348     initializeRestApiJob(job);
0349     job->setMessageId(messageId);
0350     job->setStarMessage(starred);
0351     if (!job->start()) {
0352         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start starMessage job";
0353     }
0354 }
0355 
0356 DownloadFileJob *Connection::downloadFile(const QUrl &url, const QUrl &localFileUrl, const QByteArray &mimeType, bool requiredAuthentication)
0357 {
0358     auto job = new DownloadFileJob(this);
0359     connect(job, &DownloadFileJob::downloadFileDone, this, &Connection::downloadFileDone);
0360     job->setUrl(url);
0361     job->setMimeType(mimeType);
0362     job->setLocalFileUrl(localFileUrl);
0363     job->setRequiredAuthentication(requiredAuthentication);
0364     initializeRestApiJob(job);
0365     if (!job->start()) {
0366         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start DownloadFileJob job";
0367     }
0368     return job;
0369 }
0370 
0371 void Connection::serverInfo(bool useDeprecatedVersion)
0372 {
0373     auto job = new ServerInfoJob(this);
0374     job->setUseDeprecatedVersion(useDeprecatedVersion);
0375     initializeRestApiJob(job);
0376     connect(job, &ServerInfoJob::serverInfoDone, this, &Connection::serverInfoDone);
0377     connect(job, &ServerInfoJob::serverInfoFailed, this, &Connection::serverInfoFailed);
0378     if (!job->start()) {
0379         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ServerInfoJob job";
0380     }
0381 }
0382 
0383 void Connection::changeChannelTopic(const QString &roomId, const QString &topic)
0384 {
0385     auto job = new ChangeChannelTopicJob(this);
0386     initializeRestApiJob(job);
0387     job->setRoomId(roomId);
0388     job->setTopic(topic);
0389     if (!job->start()) {
0390         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChangeChannelTopicJob job";
0391     }
0392 }
0393 
0394 void Connection::changeGroupsTopic(const QString &roomId, const QString &topic)
0395 {
0396     auto job = new ChangeGroupsTopicJob(this);
0397     initializeRestApiJob(job);
0398     ChannelGroupBaseJob::ChannelGroupInfo info;
0399     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0400     info.identifier = roomId;
0401     job->setChannelGroupInfo(info);
0402     job->setTopic(topic);
0403     if (!job->start()) {
0404         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChangeGroupsTopicJob job";
0405     }
0406 }
0407 
0408 void Connection::changeChannelReadOnly(const QString &roomId, bool b)
0409 {
0410     auto job = new ChangeChannelReadonlyJob(this);
0411     initializeRestApiJob(job);
0412     job->setRoomId(roomId);
0413     job->setReadOnly(b);
0414     if (!job->start()) {
0415         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChangeChannelReadonlyJob job";
0416     }
0417 }
0418 
0419 void Connection::changeGroupsReadOnly(const QString &roomId, bool b)
0420 {
0421     auto job = new ChangeGroupsReadonlyJob(this);
0422     initializeRestApiJob(job);
0423     ChannelGroupBaseJob::ChannelGroupInfo info;
0424     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0425     info.identifier = roomId;
0426     job->setChannelGroupInfo(info);
0427     job->setReadOnly(b);
0428     if (!job->start()) {
0429         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start changeGroupsReadOnly job";
0430     }
0431 }
0432 
0433 void Connection::changeGroupsEncrypted(const QString &roomId, bool b)
0434 {
0435     auto job = new ChangeGroupsEncryptedJob(this);
0436     initializeRestApiJob(job);
0437     ChannelGroupBaseJob::ChannelGroupInfo info;
0438     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0439     info.identifier = roomId;
0440     job->setChannelGroupInfo(info);
0441     job->setEncrypted(b);
0442     if (!job->start()) {
0443         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChangeGroupsEncryptedJob job";
0444     }
0445 }
0446 
0447 void Connection::changeChannelAnnouncement(const QString &roomId, const QString &announcement)
0448 {
0449     auto job = new ChangeChannelAnnouncementJob(this);
0450     initializeRestApiJob(job);
0451     job->setRoomId(roomId);
0452     job->setAnnouncement(announcement);
0453     if (!job->start()) {
0454         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start changeChannelAnnouncement job";
0455     }
0456 }
0457 
0458 void Connection::changeGroupsAnnouncement(const QString &roomId, const QString &announcement)
0459 {
0460     auto job = new ChangeGroupsAnnouncementJob(this);
0461     initializeRestApiJob(job);
0462     ChannelGroupBaseJob::ChannelGroupInfo info;
0463     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0464     info.identifier = roomId;
0465     job->setChannelGroupInfo(info);
0466     job->setAnnouncement(announcement);
0467     if (!job->start()) {
0468         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChangeGroupsAnnouncementJob job";
0469     }
0470 }
0471 
0472 void Connection::changeChannelDescription(const QString &roomId, const QString &description)
0473 {
0474     auto job = new ChangeChannelDescriptionJob(this);
0475     initializeRestApiJob(job);
0476     job->setRoomId(roomId);
0477     job->setDescription(description);
0478     if (!job->start()) {
0479         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start changeChannelDescription job";
0480     }
0481 }
0482 
0483 void Connection::changeGroupsDescription(const QString &roomId, const QString &description)
0484 {
0485     auto job = new ChangeGroupsDescriptionJob(this);
0486     initializeRestApiJob(job);
0487     ChannelGroupBaseJob::ChannelGroupInfo info;
0488     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0489     info.identifier = roomId;
0490     job->setChannelGroupInfo(info);
0491     job->setDescription(description);
0492     if (!job->start()) {
0493         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start changeGroupsDescription job";
0494     }
0495 }
0496 
0497 void Connection::postMessage(const QString &roomId, const QString &text)
0498 {
0499     auto job = new PostMessageJob(this);
0500     connect(job, &PostMessageJob::postMessageDone, this, &Connection::postMessageDone);
0501     initializeRestApiJob(job);
0502     job->setRoomId(roomId);
0503     job->setText(text);
0504     if (!job->start()) {
0505         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start PostMessageJob job";
0506     }
0507 }
0508 
0509 void Connection::deleteMessage(const QString &roomId, const QString &messageId)
0510 {
0511     auto job = new DeleteMessageJob(this);
0512     initializeRestApiJob(job);
0513     job->setRoomId(roomId);
0514     job->setMessageId(messageId);
0515     if (!job->start()) {
0516         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start deleteMessage job";
0517     }
0518 }
0519 
0520 void Connection::slotAddJoinCodeToChannel(const QString &channelId, const QString &password)
0521 {
0522     setJoinCodeChannel(channelId, password);
0523 }
0524 
0525 void Connection::createChannels(const RocketChatRestApi::CreateChannelTeamInfo &info)
0526 {
0527     auto job = new CreateChannelJob(this);
0528     connect(job, &CreateChannelJob::addJoinCodeToChannel, this, &Connection::slotAddJoinCodeToChannel);
0529     initializeRestApiJob(job);
0530     job->setCreateChannelInfo(info);
0531     if (!job->start()) {
0532         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start CreateChannelJob job";
0533     }
0534 }
0535 
0536 void Connection::createGroups(const RocketChatRestApi::CreateChannelTeamInfo &info)
0537 {
0538     auto job = new CreateGroupsJob(this);
0539     initializeRestApiJob(job);
0540     job->setCreateGroupsInfo(info);
0541     if (!job->start()) {
0542         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start CreateGroupsJob job";
0543     }
0544 }
0545 
0546 void Connection::leaveChannel(const QString &roomId)
0547 {
0548     auto job = new LeaveChannelJob(this);
0549     initializeRestApiJob(job);
0550     ChannelGroupBaseJob::ChannelGroupInfo info;
0551     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0552     info.identifier = roomId;
0553     job->setChannelGroupInfo(info);
0554     if (!job->start()) {
0555         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start leaveChannel job";
0556     }
0557 }
0558 
0559 void Connection::leaveGroups(const QString &roomId)
0560 {
0561     auto job = new LeaveGroupsJob(this);
0562     initializeRestApiJob(job);
0563     ChannelGroupBaseJob::ChannelGroupInfo info;
0564     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0565     info.identifier = roomId;
0566     job->setChannelGroupInfo(info);
0567     if (!job->start()) {
0568         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start leaveGroups job";
0569     }
0570 }
0571 
0572 void Connection::archiveChannel(const QString &roomId, bool archive)
0573 {
0574     auto job = new ArchiveChannelJob(this);
0575     initializeRestApiJob(job);
0576     job->setRoomId(roomId);
0577     job->setArchive(archive);
0578     if (!job->start()) {
0579         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ArchiveChannelJob job";
0580     }
0581 }
0582 
0583 void Connection::archiveGroups(const QString &roomId, bool archive)
0584 {
0585     auto job = new ArchiveGroupsJob(this);
0586     initializeRestApiJob(job);
0587     ChannelGroupBaseJob::ChannelGroupInfo info;
0588     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0589     info.identifier = roomId;
0590     job->setChannelGroupInfo(info);
0591     job->setArchive(archive);
0592     if (!job->start()) {
0593         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start archiveGroups job";
0594     }
0595 }
0596 
0597 void Connection::updateMessage(const QString &roomId, const QString &messageId, const QString &text)
0598 {
0599     auto job = new UpdateMessageJob(this);
0600     initializeRestApiJob(job);
0601     job->setRoomId(roomId);
0602     job->setMessageId(messageId);
0603     job->setUpdatedText(text);
0604     connect(job, &UpdateMessageJob::updateMessageFailed, this, &Connection::updateMessageFailed);
0605     if (!job->start()) {
0606         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start updateMessage job";
0607     }
0608 }
0609 
0610 void Connection::reactOnMessage(const QString &messageId, const QString &emoji, bool shouldReact)
0611 {
0612     auto job = new ReactOnMessageJob(this);
0613     initializeRestApiJob(job);
0614     job->setMessageId(messageId);
0615     QString fixedEmoji = emoji;
0616     if (fixedEmoji.startsWith(QLatin1Char(':'))) {
0617         fixedEmoji.remove(0, 1);
0618     }
0619     if (fixedEmoji.endsWith(QLatin1Char(':'))) {
0620         fixedEmoji.chop(1);
0621     }
0622 
0623     job->setEmoji(fixedEmoji);
0624     job->setShouldReact(shouldReact);
0625     if (!job->start()) {
0626         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start reactOnMessage job";
0627     }
0628 }
0629 
0630 void Connection::closeChannel(const QString &roomId, const QString &type)
0631 {
0632     auto job = new ChannelCloseJob(this);
0633     initializeRestApiJob(job);
0634     ChannelGroupBaseJob::ChannelGroupInfo info;
0635     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0636     info.identifier = roomId;
0637     job->setChannelGroupInfo(info);
0638     if (type == QLatin1Char('d')) {
0639         job->setChannelType(ChannelCloseJob::Direct);
0640     } else if (type == QLatin1Char('p')) {
0641         job->setChannelType(ChannelCloseJob::Groups);
0642     } else if (type == QLatin1Char('c')) {
0643         job->setChannelType(ChannelCloseJob::Channel);
0644     }
0645     if (!job->start()) {
0646         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChannelCloseJob job";
0647     }
0648 }
0649 
0650 void Connection::historyChannel(const RocketChatRestApi::ChannelHistoryJob::ChannelHistoryInfo &info)
0651 {
0652     // TODO
0653     auto job = new ChannelHistoryJob(this);
0654     initializeRestApiJob(job);
0655     job->setChannelHistoryInfo(info);
0656     if (!job->start()) {
0657         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start historyChannel job";
0658     }
0659 }
0660 
0661 void Connection::historyChannel(const QString &roomId, const QString &type)
0662 {
0663     auto job = new ChannelHistoryJob(this);
0664     initializeRestApiJob(job);
0665     ChannelGroupBaseJob::ChannelGroupInfo info;
0666     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0667     info.identifier = roomId;
0668     job->setChannelGroupInfo(info);
0669     if (type == QLatin1Char('d')) {
0670         ChannelHistoryJob::ChannelHistoryInfo historyInfo;
0671         historyInfo.channelType = ChannelHistoryJob::Direct;
0672         job->setChannelHistoryInfo(historyInfo);
0673     } else if (type == QLatin1Char('p')) {
0674         ChannelHistoryJob::ChannelHistoryInfo historyInfo;
0675         historyInfo.channelType = ChannelHistoryJob::Groups;
0676         job->setChannelHistoryInfo(historyInfo);
0677     } else if (type == QLatin1Char('c')) {
0678         ChannelHistoryJob::ChannelHistoryInfo historyInfo;
0679         historyInfo.channelType = ChannelHistoryJob::Channel;
0680         job->setChannelHistoryInfo(historyInfo);
0681     }
0682     if (!job->start()) {
0683         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start historyChannel job";
0684     }
0685 }
0686 
0687 void Connection::createDirectMessage(const QStringList &userNames)
0688 {
0689     auto job = new CreateDmJob(this);
0690     initializeRestApiJob(job);
0691     job->setUserNames(userNames);
0692     if (!job->start()) {
0693         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start createDirectMessage job";
0694     }
0695 }
0696 
0697 void Connection::openDirectMessage(const QString &userId)
0698 {
0699     auto job = new OpenDmJob(this);
0700     initializeRestApiJob(job);
0701     job->setDirectUserId(userId);
0702     if (!job->start()) {
0703         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job";
0704     }
0705 }
0706 
0707 void Connection::filesInRoom(const QString &roomId, const QString &type, int offset, int count)
0708 {
0709     auto job = new ChannelFilesJob(this);
0710     connect(job, &ChannelFilesJob::channelFilesDone, this, &Connection::channelFilesDone);
0711     initializeRestApiJob(job);
0712     ChannelGroupBaseJob::ChannelGroupInfo info;
0713     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0714     info.identifier = roomId;
0715     job->setChannelGroupInfo(info);
0716     QueryParameters parameters;
0717     parameters.setCount(count);
0718     parameters.setOffset(offset);
0719     QMap<QString, QueryParameters::SortOrder> map;
0720     map.insert(QStringLiteral("uploadedAt"), QueryParameters::SortOrder::Descendant);
0721     parameters.setSorting(map);
0722     job->setQueryParameters(parameters);
0723 
0724     if (type == QLatin1Char('d')) {
0725         job->setChannelType(ChannelFilesJob::Direct);
0726     } else if (type == QLatin1Char('p')) {
0727         job->setChannelType(ChannelFilesJob::Groups);
0728     } else if (type == QLatin1Char('c')) {
0729         job->setChannelType(ChannelFilesJob::Channel);
0730     }
0731     if (!job->start()) {
0732         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start filesInRoom job";
0733     }
0734 }
0735 
0736 // FIXME
0737 void Connection::membersInRoom(const QString &roomId, const QString &type, int offset, int count)
0738 {
0739     auto job = new ChannelMembersJob(this);
0740     QueryParameters parameters;
0741     parameters.setCount(count);
0742     parameters.setOffset(offset);
0743     job->setQueryParameters(parameters);
0744     connect(job, &ChannelMembersJob::channelMembersDone, this, &Connection::channelMembersDone);
0745     initializeRestApiJob(job);
0746     ChannelGroupBaseJob::ChannelGroupInfo info;
0747     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0748     info.identifier = roomId;
0749     job->setChannelGroupInfo(info);
0750     if (type == QLatin1Char('d')) {
0751         job->setChannelType(ChannelMembersJob::Direct);
0752     } else if (type == QLatin1Char('p')) {
0753         job->setChannelType(ChannelMembersJob::Groups);
0754     } else if (type == QLatin1Char('c')) {
0755         job->setChannelType(ChannelMembersJob::Channel);
0756     }
0757     if (!job->start()) {
0758         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start membersInRoom job";
0759     }
0760 }
0761 
0762 void Connection::addUserInChannel(const QString &roomId, const QString &userId)
0763 {
0764     auto job = new ChannelInviteJob(this);
0765     initializeRestApiJob(job);
0766     ChannelGroupBaseJob::ChannelGroupInfo info;
0767     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0768     info.identifier = roomId;
0769     job->setChannelGroupInfo(info);
0770     job->setInviteUserId(userId);
0771     if (!job->start()) {
0772         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start addUserInChannel job";
0773     }
0774 }
0775 
0776 void Connection::addUserInGroup(const QString &roomId, const QString &userId)
0777 {
0778     auto job = new GroupsInviteJob(this);
0779     initializeRestApiJob(job);
0780     ChannelGroupBaseJob::ChannelGroupInfo info;
0781     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0782     info.identifier = roomId;
0783     job->setChannelGroupInfo(info);
0784 
0785     job->setInviteUserId(userId);
0786     if (!job->start()) {
0787         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start addUserInGroup job";
0788     }
0789 }
0790 
0791 void Connection::searchMessages(const QString &roomId, const QString &pattern, bool useRegularExpression)
0792 {
0793     auto job = new SearchMessageJob(this);
0794     job->setRoomId(roomId);
0795     job->setSearchText(pattern);
0796     job->setUseRegularExpression(useRegularExpression);
0797     initializeRestApiJob(job);
0798     connect(job, &SearchMessageJob::searchMessageDone, this, &Connection::searchMessageDone);
0799     if (!job->start()) {
0800         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start searchMessages job";
0801     }
0802 }
0803 
0804 void Connection::markRoomAsRead(const QString &roomId)
0805 {
0806     auto job = new MarkRoomAsReadJob(this);
0807     job->setRoomId(roomId);
0808     initializeRestApiJob(job);
0809     connect(job, &MarkRoomAsReadJob::markAsReadDone, this, &Connection::markAsReadDone);
0810     if (!job->start()) {
0811         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start markAsRead job";
0812     }
0813 }
0814 
0815 void Connection::markRoomAsUnRead(const QString &roomId)
0816 {
0817     auto job = new MarkRoomAsUnReadJob(this);
0818     job->setObjectId(roomId);
0819     job->setUnReadObject(MarkRoomAsUnReadJob::Room);
0820     initializeRestApiJob(job);
0821     if (!job->start()) {
0822         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start markRoomAsUnRead job";
0823     }
0824 }
0825 
0826 void Connection::markMessageAsUnReadFrom(const QString &messageId)
0827 {
0828     auto job = new MarkRoomAsUnReadJob(this);
0829     job->setObjectId(messageId);
0830     job->setUnReadObject(MarkRoomAsUnReadJob::FromMessage);
0831     initializeRestApiJob(job);
0832     if (!job->start()) {
0833         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start markMessageAsUnReadFrom job";
0834     }
0835 }
0836 
0837 void Connection::getRooms()
0838 {
0839     auto job = new GetRoomsJob(this);
0840     initializeRestApiJob(job);
0841     connect(job, &GetRoomsJob::getRoomsDone, this, &Connection::getRoomsDone);
0842     if (!job->start()) {
0843         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getRooms job";
0844     }
0845 }
0846 
0847 void Connection::markAsFavorite(const QString &roomId, bool favorite)
0848 {
0849     auto job = new RoomFavoriteJob(this);
0850     initializeRestApiJob(job);
0851     job->setFavorite(favorite);
0852     job->setRoomId(roomId);
0853     if (!job->start()) {
0854         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start markAsFavorite job";
0855     }
0856 }
0857 
0858 void Connection::disableNotifications(const QString &roomId, bool value)
0859 {
0860     auto job = new SaveNotificationJob(this);
0861     initializeRestApiJob(job);
0862     job->setRoomId(roomId);
0863     job->setDisableNotifications(value);
0864     if (!job->start()) {
0865         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start disableNotifications job";
0866     }
0867 }
0868 
0869 void Connection::muteGroupMentions(const QString &roomId, bool value)
0870 {
0871     auto job = new SaveNotificationJob(this);
0872     initializeRestApiJob(job);
0873     job->setRoomId(roomId);
0874     job->setMuteGroupMentions(value);
0875     if (!job->start()) {
0876         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start muteGroupMentions job";
0877     }
0878 }
0879 
0880 void Connection::desktopDurationNotifications(const QString &roomId, int value)
0881 {
0882     auto job = new SaveNotificationJob(this);
0883     initializeRestApiJob(job);
0884     job->setRoomId(roomId);
0885     job->setDesktopNotificationDuration(value);
0886     if (!job->start()) {
0887         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start desktopDurationNotifications job";
0888     }
0889 }
0890 
0891 void Connection::hideMentionStatus(const QString &roomId, bool value)
0892 {
0893     auto job = new SaveNotificationJob(this);
0894     initializeRestApiJob(job);
0895     job->setRoomId(roomId);
0896     job->setHideMentionStatus(value);
0897     if (!job->start()) {
0898         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start desktopSoundNotifications job";
0899     }
0900 }
0901 
0902 void Connection::desktopSoundNotifications(const QString &roomId, const QString &value)
0903 {
0904     auto job = new SaveNotificationJob(this);
0905     initializeRestApiJob(job);
0906     job->setRoomId(roomId);
0907     job->setAudioNotificationValue(value);
0908     if (!job->start()) {
0909         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start desktopSoundNotifications job";
0910     }
0911 }
0912 
0913 void Connection::changeGroupName(const QString &roomId, const QString &newName)
0914 {
0915     auto job = new ChangeGroupsNameJob(this);
0916     initializeRestApiJob(job);
0917     ChannelGroupBaseJob::ChannelGroupInfo info;
0918     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0919     info.identifier = roomId;
0920     job->setChannelGroupInfo(info);
0921     job->setName(newName);
0922     if (!job->start()) {
0923         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start changeGroupName job";
0924     }
0925 }
0926 
0927 void Connection::changeChannelName(const QString &roomId, const QString &newName)
0928 {
0929     auto job = new ChangeChannelNameJob(this);
0930     initializeRestApiJob(job);
0931     job->setRoomId(roomId);
0932     job->setName(newName);
0933     if (!job->start()) {
0934         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start changeChannelName job";
0935     }
0936 }
0937 
0938 void Connection::channelInfo(const QString &roomId)
0939 {
0940     auto job = new ChannelInfoJob(this);
0941     initializeRestApiJob(job);
0942     ChannelGroupBaseJob::ChannelGroupInfo info;
0943     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
0944     info.identifier = roomId;
0945     job->setChannelGroupInfo(info);
0946     if (!job->start()) {
0947         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start channelInfo job";
0948     }
0949 }
0950 
0951 void Connection::groupInfo(const QString &roomId)
0952 {
0953     auto job = new GroupsInfoJob(this);
0954     initializeRestApiJob(job);
0955     job->setRoomId(roomId);
0956     if (!job->start()) {
0957         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start groupInfo job";
0958     }
0959 }
0960 
0961 void Connection::hideUnreadStatus(const QString &roomId, bool value)
0962 {
0963     auto job = new SaveNotificationJob(this);
0964     initializeRestApiJob(job);
0965     job->setRoomId(roomId);
0966     job->setHideUnreadStatus(value);
0967     if (!job->start()) {
0968         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start hideUnreadStatus job";
0969     }
0970 }
0971 
0972 void Connection::desktopNotifications(const QString &roomId, const QString &value)
0973 {
0974     auto job = new SaveNotificationJob(this);
0975     initializeRestApiJob(job);
0976     job->setRoomId(roomId);
0977     job->setDesktopNotifications(value);
0978     if (!job->start()) {
0979         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start desktopNotifications job";
0980     }
0981 }
0982 
0983 void Connection::emailNotifications(const QString &roomId, const QString &value)
0984 {
0985     auto job = new SaveNotificationJob(this);
0986     initializeRestApiJob(job);
0987     job->setRoomId(roomId);
0988     job->setEmailNotifications(value);
0989     if (!job->start()) {
0990         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start emailNotifications job";
0991     }
0992 }
0993 
0994 void Connection::mobilePushNotifications(const QString &roomId, const QString &value)
0995 {
0996     auto job = new SaveNotificationJob(this);
0997     initializeRestApiJob(job);
0998     job->setRoomId(roomId);
0999     job->setMobilePushNotifications(value);
1000     if (!job->start()) {
1001         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start mobilePushNotifications job";
1002     }
1003 }
1004 
1005 void Connection::unreadAlert(const QString &roomId, const QString &value)
1006 {
1007     auto job = new SaveNotificationJob(this);
1008     initializeRestApiJob(job);
1009     job->setRoomId(roomId);
1010     job->setUnreadAlert(value);
1011     if (!job->start()) {
1012         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start unreadAlert job";
1013     }
1014 }
1015 
1016 void Connection::setAvatar(const UserInfoJob::UserInfo &info, const SetAvatarJob::SetAvatarInfo &avatarInfo)
1017 {
1018     auto job = new SetAvatarJob(this);
1019     initializeRestApiJob(job);
1020 
1021     job->setAvatarInfo(avatarInfo);
1022     job->setUserInfo(info);
1023     if (!job->start()) {
1024         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start setAvatar job";
1025     }
1026 }
1027 
1028 void Connection::forgotPassword(const QString &email)
1029 {
1030     auto job = new ForgotPasswordJob(this);
1031     initializeRestApiJob(job);
1032     job->setEmail(email);
1033     if (!job->start()) {
1034         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start forgotPassword job";
1035     }
1036 }
1037 
1038 void Connection::userInfo(const QString &identifier, bool userName)
1039 {
1040     auto job = new UserInfoJob(this);
1041     initializeRestApiJob(job);
1042     UserInfoJob::UserInfo info;
1043     info.userIdentifier = identifier;
1044     info.userInfoType = userName ? UserInfoJob::UserInfoType::UserName : UserInfoJob::UserInfoType::UserId;
1045     job->setUserInfo(info);
1046     connect(job, &UserInfoJob::userInfoDone, this, &Connection::userInfoDone);
1047     if (!job->start()) {
1048         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start userInfo job";
1049     }
1050 }
1051 
1052 void Connection::ignoreUser(const QString &roomId, const QString &userId, bool ignore)
1053 {
1054     auto job = new IgnoreUserJob(this);
1055     initializeRestApiJob(job);
1056     job->setIgnoreUserId(userId);
1057     job->setRoomId(roomId);
1058     job->setIgnore(ignore);
1059     connect(job, &IgnoreUserJob::ignoreUserDone, this, &Connection::ignoreUserDone);
1060     if (!job->start()) {
1061         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ignoreUser job";
1062     }
1063 }
1064 
1065 void Connection::userPresence(const QString &userId)
1066 {
1067     auto job = new GetPresenceJob(this);
1068     initializeRestApiJob(job);
1069     UserInfoJob::UserInfo info;
1070     info.userIdentifier = userId;
1071     info.userInfoType = UserInfoJob::UserInfoType::UserId;
1072 
1073     job->setUserInfo(info);
1074     connect(job, &GetPresenceJob::getPresenceDone, this, &Connection::getPresenceDone);
1075     if (!job->start()) {
1076         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start userPresence job";
1077     }
1078 }
1079 
1080 void Connection::reportMessage(const QString &messageId, const QString &message)
1081 {
1082     auto job = new ReportMessageJob(this);
1083     initializeRestApiJob(job);
1084     job->setMessageId(messageId);
1085     job->setReportMessage(message);
1086     if (!job->start()) {
1087         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start reportMessage job";
1088     }
1089 }
1090 
1091 void Connection::setGroupType(const QString &roomId, bool isPrivate)
1092 {
1093     auto job = new SetGroupTypeJob(this);
1094     initializeRestApiJob(job);
1095     ChannelGroupBaseJob::ChannelGroupInfo info;
1096     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1097     info.identifier = roomId;
1098     job->setChannelGroupInfo(info);
1099 
1100     job->setType(isPrivate ? SetGroupTypeJob::Private : SetGroupTypeJob::Public);
1101     if (!job->start()) {
1102         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start setGroupType job";
1103     }
1104 }
1105 
1106 void Connection::setChannelType(const QString &roomId, bool isPrivate)
1107 {
1108     auto job = new SetChannelTypeJob(this);
1109     initializeRestApiJob(job);
1110     ChannelGroupBaseJob::ChannelGroupInfo info;
1111     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1112     info.identifier = roomId;
1113     job->setChannelGroupInfo(info);
1114     job->setType(isPrivate ? SetChannelTypeJob::Private : SetChannelTypeJob::Public);
1115     if (!job->start()) {
1116         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start setChannelType job";
1117     }
1118 }
1119 
1120 void Connection::getGroupRoles(const QString &roomId)
1121 {
1122     auto job = new GetGroupRolesJob(this);
1123     initializeRestApiJob(job);
1124     ChannelGroupBaseJob::ChannelGroupInfo info;
1125     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1126     info.identifier = roomId;
1127     job->setChannelGroupInfo(info);
1128     connect(job, &GetGroupRolesJob::groupRolesDone, this, &Connection::groupRolesDone);
1129     if (!job->start()) {
1130         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getGroupRoles job";
1131     }
1132 }
1133 
1134 void Connection::getChannelRoles(const QString &roomId)
1135 {
1136     auto job = new GetChannelRolesJob(this);
1137     initializeRestApiJob(job);
1138     ChannelGroupBaseJob::ChannelGroupInfo info;
1139     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1140     info.identifier = roomId;
1141     job->setChannelGroupInfo(info);
1142     connect(job, &GetChannelRolesJob::channelRolesDone, this, &Connection::channelRolesDone);
1143     if (!job->start()) {
1144         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start GetChannelRolesJob job";
1145     }
1146 }
1147 
1148 void Connection::getUsernameSuggestion()
1149 {
1150     auto job = new GetUsernameSuggestionJob(this);
1151     initializeRestApiJob(job);
1152     connect(job, &GetUsernameSuggestionJob::getUsernameSuggestionDone, this, &Connection::getUsernameSuggestionDone);
1153     if (!job->start()) {
1154         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getUsernameSuggestion job";
1155     }
1156 }
1157 
1158 void Connection::listAllPermissions()
1159 {
1160     auto job = new PermissionsListAllJob(this);
1161     initializeRestApiJob(job);
1162     connect(job, &PermissionsListAllJob::permissionListAllDone, this, &Connection::permissionListAllDone);
1163     if (!job->start()) {
1164         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ListPermissionsJob job";
1165     }
1166 }
1167 
1168 void Connection::getCommand(const QString &commandName)
1169 {
1170     auto job = new GetCommandsJob(this);
1171     initializeRestApiJob(job);
1172     job->setCommandName(commandName);
1173     connect(job, &GetCommandsJob::getCommandsDone, this, &Connection::getCommandsDone);
1174     if (!job->start()) {
1175         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start GetCommandsJob job";
1176     }
1177 }
1178 
1179 void Connection::runCommand(const RunCommandJob::RunCommandInfo &runCommandInfo)
1180 {
1181     auto job = new RunCommandJob(this);
1182     initializeRestApiJob(job);
1183     job->setRunCommandInfo(runCommandInfo);
1184     connect(job, &RunCommandJob::runCommandDone, this, &Connection::runCommandDone);
1185     if (!job->start()) {
1186         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start RunCommandJob job";
1187     }
1188 }
1189 
1190 void Connection::fetchMyKeys()
1191 {
1192     auto job = new FetchMyKeysJob(this);
1193     initializeRestApiJob(job);
1194     connect(job, &FetchMyKeysJob::fetchMyKeysDone, this, &Connection::fetchMyKeysDone);
1195     if (!job->start()) {
1196         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start fetchmykeys job";
1197     }
1198 }
1199 
1200 void Connection::setJoinCodeChannel(const QString &roomId, const QString &joinCode)
1201 {
1202     auto job = new SetJoinCodeChannelJob(this);
1203     initializeRestApiJob(job);
1204     job->setJoinCode(joinCode);
1205     ChannelGroupBaseJob::ChannelGroupInfo info;
1206     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1207     info.identifier = roomId;
1208     job->setChannelGroupInfo(info);
1209 
1210     connect(job, &SetJoinCodeChannelJob::setJoinCodeDone, this, &Connection::setJoinCodeDone);
1211     if (!job->start()) {
1212         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start setjoincode";
1213     }
1214 }
1215 
1216 void Connection::channelGetAllUserMentions(const QString &roomId, int offset, int count)
1217 {
1218     auto job = new ChannelGetAllUserMentionsJob(this);
1219     initializeRestApiJob(job);
1220     job->setRoomId(roomId);
1221     QueryParameters parameters;
1222     QMap<QString, QueryParameters::SortOrder> map;
1223     map.insert(QStringLiteral("ts"), QueryParameters::SortOrder::Descendant);
1224     parameters.setSorting(map);
1225     parameters.setCount(count);
1226     parameters.setOffset(offset);
1227     job->setQueryParameters(parameters);
1228 
1229     connect(job, &ChannelGetAllUserMentionsJob::channelGetAllUserMentionsDone, this, &Connection::channelGetAllUserMentionsDone);
1230     if (!job->start()) {
1231         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start setChannelJoin";
1232     }
1233 }
1234 
1235 void Connection::channelKick(const QString &roomId, const QString &userId)
1236 {
1237     auto job = new ChannelKickJob(this);
1238     initializeRestApiJob(job);
1239     job->setKickUserId(userId);
1240     ChannelGroupBaseJob::ChannelGroupInfo info;
1241     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1242     info.identifier = roomId;
1243     job->setChannelGroupInfo(info);
1244     connect(job, &ChannelKickJob::kickUserDone, this, &Connection::channelKickUserDone);
1245     if (!job->start()) {
1246         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start channelKick";
1247     }
1248 }
1249 
1250 void Connection::groupKick(const QString &roomId, const QString &userId)
1251 {
1252     auto job = new GroupsKickJob(this);
1253     initializeRestApiJob(job);
1254     job->setKickUserId(userId);
1255     ChannelGroupBaseJob::ChannelGroupInfo info;
1256     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1257     info.identifier = roomId;
1258     job->setChannelGroupInfo(info);
1259 
1260     connect(job, &GroupsKickJob::kickUserDone, this, &Connection::groupKickUserDone);
1261     if (!job->start()) {
1262         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start channelKick";
1263     }
1264 }
1265 
1266 void Connection::groupAddModerator(const QString &roomId, const QString &userId)
1267 {
1268     auto job = new GroupAddModeratorJob(this);
1269     initializeRestApiJob(job);
1270     job->setAddModeratorUserId(userId);
1271     ChannelGroupBaseJob::ChannelGroupInfo info;
1272     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1273     info.identifier = roomId;
1274     job->setChannelGroupInfo(info);
1275     connect(job, &GroupAddModeratorJob::addModeratorDone, this, &Connection::addModeratorDone);
1276     if (!job->start()) {
1277         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start groupAddModerator";
1278     }
1279 }
1280 
1281 void Connection::groupRemoveModerator(const QString &roomId, const QString &userId)
1282 {
1283     auto job = new GroupRemoveModeratorJob(this);
1284     initializeRestApiJob(job);
1285     job->setRemoveUserId(userId);
1286     ChannelGroupBaseJob::ChannelGroupInfo info;
1287     info.identifier = roomId;
1288     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1289     job->setChannelGroupInfo(info);
1290     connect(job, &GroupRemoveModeratorJob::removeModeratorDone, this, &Connection::removeModeratorDone);
1291     if (!job->start()) {
1292         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start groupRemoveModerator";
1293     }
1294 }
1295 
1296 void Connection::groupAddLeader(const QString &roomId, const QString &userId)
1297 {
1298     auto job = new GroupAddLeaderJob(this);
1299     initializeRestApiJob(job);
1300     job->setAddLeaderUserId(userId);
1301     ChannelGroupBaseJob::ChannelGroupInfo info;
1302     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1303     info.identifier = roomId;
1304     job->setChannelGroupInfo(info);
1305     connect(job, &GroupAddLeaderJob::addLeaderDone, this, &Connection::addLeaderDone);
1306     if (!job->start()) {
1307         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start groupAddLeader";
1308     }
1309 }
1310 
1311 void Connection::groupRemoveLeader(const QString &roomId, const QString &userId)
1312 {
1313     auto job = new GroupRemoveLeaderJob(this);
1314     initializeRestApiJob(job);
1315     job->setRemoveUserId(userId);
1316     ChannelGroupBaseJob::ChannelGroupInfo info;
1317     info.identifier = roomId;
1318     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1319     job->setChannelGroupInfo(info);
1320     connect(job, &GroupRemoveLeaderJob::removeLeaderDone, this, &Connection::removeLeaderDone);
1321     if (!job->start()) {
1322         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start groupRemoveLeader";
1323     }
1324 }
1325 
1326 void Connection::groupAddOwner(const QString &roomId, const QString &userId)
1327 {
1328     auto job = new GroupAddOwnerJob(this);
1329     initializeRestApiJob(job);
1330     job->setAddownerUserId(userId);
1331     ChannelGroupBaseJob::ChannelGroupInfo info;
1332     info.identifier = roomId;
1333     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1334     job->setChannelGroupInfo(info);
1335     connect(job, &GroupAddOwnerJob::addOwnerDone, this, &Connection::addOwnerDone);
1336     if (!job->start()) {
1337         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start groupAddOwner";
1338     }
1339 }
1340 
1341 void Connection::groupRemoveOwner(const QString &roomId, const QString &userId)
1342 {
1343     auto job = new GroupRemoveOwnerJob(this);
1344     initializeRestApiJob(job);
1345     job->setRemoveUserId(userId);
1346     ChannelGroupBaseJob::ChannelGroupInfo info;
1347     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1348     info.identifier = roomId;
1349     job->setChannelGroupInfo(info);
1350 
1351     connect(job, &GroupRemoveOwnerJob::groupRemoveOwnerDone, this, &Connection::channelRemoveOwnerDone);
1352     if (!job->start()) {
1353         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start groupRemoveOwner";
1354     }
1355 }
1356 
1357 void Connection::channelAddModerator(const QString &roomId, const QString &userId)
1358 {
1359     auto job = new ChannelAddModeratorJob(this);
1360     initializeRestApiJob(job);
1361     job->setAddModeratorUserId(userId);
1362     ChannelGroupBaseJob::ChannelGroupInfo info;
1363     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1364     info.identifier = roomId;
1365     job->setChannelGroupInfo(info);
1366     connect(job, &ChannelAddModeratorJob::addModeratorDone, this, &Connection::addModeratorDone);
1367     if (!job->start()) {
1368         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start channelAddModerator";
1369     }
1370 }
1371 
1372 void Connection::channelRemoveModerator(const QString &roomId, const QString &userId)
1373 {
1374     auto job = new ChannelRemoveModeratorJob(this);
1375     initializeRestApiJob(job);
1376     job->setRemoveUserId(userId);
1377     ChannelGroupBaseJob::ChannelGroupInfo info;
1378     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1379     info.identifier = roomId;
1380     job->setChannelGroupInfo(info);
1381     connect(job, &ChannelRemoveModeratorJob::removeModeratorDone, this, &Connection::removeModeratorDone);
1382     if (!job->start()) {
1383         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChannelRemoveModeratorJob";
1384     }
1385 }
1386 
1387 void Connection::channelAddLeader(const QString &roomId, const QString &userId)
1388 {
1389     auto job = new ChannelAddLeaderJob(this);
1390     initializeRestApiJob(job);
1391     job->setAddLeaderUserId(userId);
1392     ChannelGroupBaseJob::ChannelGroupInfo info;
1393     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1394     info.identifier = roomId;
1395     job->setChannelGroupInfo(info);
1396     connect(job, &ChannelAddLeaderJob::addLeaderDone, this, &Connection::addLeaderDone);
1397     if (!job->start()) {
1398         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start channelAddLeader";
1399     }
1400 }
1401 
1402 void Connection::channelRemoveLeader(const QString &roomId, const QString &userId)
1403 {
1404     auto job = new ChannelRemoveLeaderJob(this);
1405     initializeRestApiJob(job);
1406     job->setRemoveUserId(userId);
1407     ChannelGroupBaseJob::ChannelGroupInfo info;
1408     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1409     info.identifier = roomId;
1410     job->setChannelGroupInfo(info);
1411     connect(job, &ChannelRemoveLeaderJob::removeLeaderDone, this, &Connection::removeLeaderDone);
1412     if (!job->start()) {
1413         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start channelRemoveLeader";
1414     }
1415 }
1416 
1417 void Connection::channelAddOwner(const QString &roomId, const QString &userId)
1418 {
1419     auto job = new ChannelAddOwnerJob(this);
1420     initializeRestApiJob(job);
1421     job->setAddownerUserId(userId);
1422     ChannelGroupBaseJob::ChannelGroupInfo info;
1423     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1424     info.identifier = roomId;
1425     job->setChannelGroupInfo(info);
1426     connect(job, &ChannelAddOwnerJob::addOwnerDone, this, &Connection::addOwnerDone);
1427     if (!job->start()) {
1428         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChannelAddOwnerJob";
1429     }
1430 }
1431 
1432 void Connection::channelRemoveOwner(const QString &roomId, const QString &userId)
1433 {
1434     auto job = new ChannelRemoveOwnerJob(this);
1435     initializeRestApiJob(job);
1436     job->setRemoveUserId(userId);
1437     ChannelGroupBaseJob::ChannelGroupInfo info;
1438     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1439     info.identifier = roomId;
1440     job->setChannelGroupInfo(info);
1441     connect(job, &ChannelRemoveOwnerJob::channelRemoveOwnerDone, this, &Connection::channelRemoveOwnerDone);
1442     if (!job->start()) {
1443         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChannelRemoveOwnerJob";
1444     }
1445 }
1446 
1447 void Connection::channelDelete(const QString &roomId)
1448 {
1449     auto job = new ChannelDeleteJob(this);
1450     initializeRestApiJob(job);
1451     ChannelGroupBaseJob::ChannelGroupInfo info;
1452     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1453     info.identifier = roomId;
1454     job->setChannelGroupInfo(info);
1455     connect(job, &ChannelDeleteJob::deletechannelDone, this, &Connection::deletechannelDone);
1456     if (!job->start()) {
1457         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChannelDeleteJob";
1458     }
1459 }
1460 
1461 void Connection::groupDelete(const QString &roomId)
1462 {
1463     auto job = new GroupsDeleteJob(this);
1464     initializeRestApiJob(job);
1465     ChannelGroupBaseJob::ChannelGroupInfo info;
1466     info.identifier = roomId;
1467     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1468     job->setChannelGroupInfo(info);
1469     connect(job, &GroupsDeleteJob::deleteGroupsDone, this, &Connection::deleteGroupsDone);
1470     if (!job->start()) {
1471         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start GroupsDeleteJob";
1472     }
1473 }
1474 
1475 void Connection::pinMessage(const QString &messageId, bool pinned)
1476 {
1477     auto job = new PinMessageJob(this);
1478     initializeRestApiJob(job);
1479     job->setMessageId(messageId);
1480     job->setPinMessage(pinned);
1481     connect(job, &PinMessageJob::pinMessageDone, this, &Connection::pinMessageDone);
1482     if (!job->start()) {
1483         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start PinMessageJob";
1484     }
1485 }
1486 
1487 void Connection::followMessage(const QString &messageId)
1488 {
1489     auto job = new FollowMessageJob(this);
1490     initializeRestApiJob(job);
1491     job->setMessageId(messageId);
1492     connect(job, &FollowMessageJob::followMessageDone, this, &Connection::followMessageDone);
1493     if (!job->start()) {
1494         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start FollowMessageJob";
1495     }
1496 }
1497 
1498 void Connection::unFollowMessage(const QString &messageId)
1499 {
1500     auto job = new UnFollowMessageJob(this);
1501     initializeRestApiJob(job);
1502     job->setMessageId(messageId);
1503     connect(job, &UnFollowMessageJob::unFollowMessageDone, this, &Connection::unFollowMessageDone);
1504     if (!job->start()) {
1505         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start unFollowMessageDone";
1506     }
1507 }
1508 
1509 void Connection::createDiscussion(const QString &parentRoomId,
1510                                   const QString &discussionName,
1511                                   const QString &replyMessage,
1512                                   const QString &parentMessageId,
1513                                   const QStringList &users)
1514 {
1515     auto job = new RoomStartDiscussionJob(this);
1516     initializeRestApiJob(job);
1517     job->setParentRoomId(parentRoomId);
1518 
1519     job->setDiscussionName(discussionName);
1520     job->setParentMessageId(parentMessageId);
1521     job->setReplyMessage(replyMessage);
1522     job->setUsers(users);
1523     connect(job, &RoomStartDiscussionJob::startDiscussionDone, this, &Connection::startDiscussionDone);
1524     if (!job->start()) {
1525         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start roomStartDiscussion";
1526     }
1527 }
1528 
1529 void Connection::getDiscussions(const QString &roomId, int offset, int count)
1530 {
1531     auto job = new GetDiscussionsJob(this);
1532     initializeRestApiJob(job);
1533     QueryParameters parameters;
1534     parameters.setCount(count);
1535     parameters.setOffset(offset);
1536     job->setQueryParameters(parameters);
1537     job->setRoomId(roomId);
1538     connect(job, &GetDiscussionsJob::getDiscussionsDone, this, &Connection::getDiscussionsDone);
1539     if (!job->start()) {
1540         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getDiscussions";
1541     }
1542 }
1543 
1544 void Connection::getThreadsList(const QString &roomId, bool onlyUnread, int offset, int count)
1545 {
1546     auto job = new GetThreadsJob(this);
1547     initializeRestApiJob(job);
1548     job->setRoomId(roomId);
1549     QueryParameters parameters;
1550     QMap<QString, QueryParameters::SortOrder> map;
1551     map.insert(QStringLiteral("ts"), QueryParameters::SortOrder::Descendant);
1552     parameters.setSorting(map);
1553     parameters.setCount(count);
1554     parameters.setOffset(offset);
1555     if (onlyUnread) {
1556         job->setSearchType(GetThreadsJob::TheadSearchType::Unread);
1557     }
1558     job->setQueryParameters(parameters);
1559     connect(job, &GetThreadsJob::getThreadsDone, this, [this, onlyUnread](const QJsonObject &obj, const QString &roomId) {
1560         Q_EMIT getThreadsDone(obj, roomId, onlyUnread);
1561     });
1562     if (!job->start()) {
1563         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getThreadsList";
1564     }
1565 }
1566 
1567 void Connection::getMessage(const QString &messageId, const QString &roomId)
1568 {
1569     auto job = new GetMessageJob(this);
1570     initializeRestApiJob(job);
1571     job->setMessageId(messageId);
1572     job->setRoomId(roomId);
1573     connect(job, &GetMessageJob::getMessageDone, this, &Connection::getMessageDone);
1574     if (!job->start()) {
1575         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getMessage";
1576     }
1577 }
1578 
1579 void Connection::getPinnedMessages(const QString &roomId, int offset, int count)
1580 {
1581     auto job = new GetPinnedMessagesJob(this);
1582     initializeRestApiJob(job);
1583     job->setRoomId(roomId);
1584     QueryParameters parameters;
1585     parameters.setCount(count);
1586     parameters.setOffset(offset);
1587     QMap<QString, QueryParameters::SortOrder> map;
1588     map.insert(QStringLiteral("ts"), QueryParameters::SortOrder::Descendant);
1589 
1590     job->setQueryParameters(parameters);
1591     connect(job, &GetPinnedMessagesJob::getPinnedMessagesDone, this, &Connection::getPinnedMessagesDone);
1592     if (!job->start()) {
1593         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getPinnedMessagesList";
1594     }
1595 }
1596 
1597 void Connection::getMentionedMessages(const QString &roomId, int offset, int count)
1598 {
1599     auto job = new GetMentionedMessagesJob(this);
1600     initializeRestApiJob(job);
1601     job->setRoomId(roomId);
1602     QueryParameters parameters;
1603     QMap<QString, QueryParameters::SortOrder> map;
1604     map.insert(QStringLiteral("ts"), QueryParameters::SortOrder::Descendant);
1605     parameters.setSorting(map);
1606     parameters.setCount(count);
1607     parameters.setOffset(offset);
1608     job->setQueryParameters(parameters);
1609 
1610     connect(job, &GetMentionedMessagesJob::getMentionedMessagesDone, this, &Connection::getMentionedMessagesDone);
1611     if (!job->start()) {
1612         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getMentionedMessages";
1613     }
1614 }
1615 
1616 void Connection::getStarredMessages(const QString &roomId, int offset, int count)
1617 {
1618     auto job = new GetStarredMessagesJob(this);
1619     initializeRestApiJob(job);
1620     job->setRoomId(roomId);
1621     QueryParameters parameters;
1622     QMap<QString, QueryParameters::SortOrder> map;
1623     map.insert(QStringLiteral("ts"), QueryParameters::SortOrder::Descendant);
1624     parameters.setSorting(map);
1625     parameters.setCount(count);
1626     parameters.setOffset(offset);
1627     job->setQueryParameters(parameters);
1628 
1629     connect(job, &GetStarredMessagesJob::getStarredMessagesDone, this, &Connection::getStarredMessagesDone);
1630     if (!job->start()) {
1631         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getStarredMessagesList";
1632     }
1633 }
1634 
1635 void Connection::getSnippetedMessages(const QString &roomId, int offset, int count)
1636 {
1637     auto job = new GetSnippetedMessagesJob(this);
1638     initializeRestApiJob(job);
1639     job->setRoomId(roomId);
1640     QueryParameters parameters;
1641     parameters.setCount(count);
1642     parameters.setOffset(offset);
1643 
1644     QMap<QString, QueryParameters::SortOrder> map;
1645     map.insert(QStringLiteral("ts"), QueryParameters::SortOrder::Descendant);
1646     job->setQueryParameters(parameters);
1647     connect(job, &GetSnippetedMessagesJob::getSnippetedMessagesDone, this, &Connection::getSnippetedMessagesDone);
1648     if (!job->start()) {
1649         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getSnippetedMessagesList";
1650     }
1651 }
1652 
1653 void Connection::getThreadMessages(const QString &threadMessageId)
1654 {
1655     auto job = new GetThreadMessagesJob(this);
1656     initializeRestApiJob(job);
1657     job->setThreadMessageId(threadMessageId);
1658     connect(job, &GetThreadMessagesJob::getThreadMessagesDone, this, &Connection::getThreadMessagesDone);
1659     if (!job->start()) {
1660         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getThreadMessages";
1661     }
1662 }
1663 
1664 void Connection::syncThreadMessages(const QString &threadMessageId, const QString &timestamp)
1665 {
1666     auto job = new SyncThreadMessagesJob(this);
1667     initializeRestApiJob(job);
1668     job->setThreadMessageId(threadMessageId);
1669     job->setTimeStamp(timestamp);
1670     connect(job, &SyncThreadMessagesJob::syncThreadMessagesDone, this, &Connection::syncThreadMessagesDone);
1671     if (!job->start()) {
1672         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start syncThreadMessages";
1673     }
1674 }
1675 
1676 void Connection::sendMessage(const QString &roomId, const QString &text, const QString &messageId, const QString &threadMessageId)
1677 {
1678     auto job = new SendMessageJob(this);
1679     initializeRestApiJob(job);
1680     SendMessageJob::SendMessageArguments args;
1681     args.roomId = roomId;
1682     args.message = text;
1683     args.messageId = messageId;
1684     args.threadMessageId = threadMessageId;
1685     job->setSendMessageArguments(std::move(args));
1686     if (!job->start()) {
1687         qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job";
1688     }
1689 }
1690 
1691 void Connection::autoTranslateSaveLanguageSettings(const QString &roomId, const QString &language)
1692 {
1693     auto job = new TranslateSaveSettingsJob(this);
1694     initializeRestApiJob(job);
1695     job->setRoomId(roomId);
1696     job->setType(TranslateSaveSettingsJob::LanguageSetting);
1697     job->setLanguage(language);
1698     connect(job, &TranslateSaveSettingsJob::translateSavesettingsDone, this, &Connection::translateSavesettingsDone);
1699     if (!job->start()) {
1700         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start autoTranslateSaveLanguageSettings";
1701     }
1702 }
1703 
1704 void Connection::autoTranslateSaveAutoTranslateSettings(const QString &roomId, bool autoTranslate)
1705 {
1706     auto job = new TranslateSaveSettingsJob(this);
1707     initializeRestApiJob(job);
1708     job->setRoomId(roomId);
1709     job->setType(TranslateSaveSettingsJob::AutoTranslateSetting);
1710     job->setAutoTranslate(autoTranslate);
1711     connect(job, &TranslateSaveSettingsJob::translateSavesettingsDone, this, &Connection::translateSavesettingsDone);
1712     if (!job->start()) {
1713         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start autoTranslateSaveAutoTranslateSettings";
1714     }
1715 }
1716 
1717 void Connection::setUserStatus(const QString &userId, SetStatusJob::StatusType status, const QString &message)
1718 {
1719     auto job = new SetStatusJob(this);
1720     initializeRestApiJob(job);
1721     job->setStatusUserId(userId);
1722     job->setStatus(status);
1723     job->setStatusMessage(message);
1724     connect(job, &SetStatusJob::setStatusDone, this, &Connection::setStatusDone);
1725     if (!job->start()) {
1726         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start SetStatusJob";
1727     }
1728 }
1729 
1730 void Connection::usersPresence()
1731 {
1732     auto job = new UsersPresenceJob(this);
1733     initializeRestApiJob(job);
1734     connect(job, &UsersPresenceJob::usersPresenceDone, this, &Connection::usersPresenceDone);
1735     if (!job->start()) {
1736         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start usersPresenceJob";
1737     }
1738 }
1739 
1740 void Connection::customUserStatus()
1741 {
1742     auto job = new CustomUserStatusListJob(this);
1743     initializeRestApiJob(job);
1744     connect(job, &CustomUserStatusListJob::customUserStatusDone, this, &Connection::customUserStatusDone);
1745     if (!job->start()) {
1746         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start CustomUserStatusJob";
1747     }
1748 }
1749 
1750 void Connection::usersAutocomplete(const UsersAutocompleteJob::UsersAutocompleterInfo &info)
1751 {
1752     auto job = new UsersAutocompleteJob(this);
1753     job->setUsersCompleterInfo(info);
1754     initializeRestApiJob(job);
1755     connect(job, &UsersAutocompleteJob::usersAutocompleteDone, this, &Connection::usersAutocompleteDone);
1756     if (!job->start()) {
1757         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start UsersAutocompleteJob";
1758     }
1759 }
1760 
1761 void Connection::findOrCreateInvite(const QString &roomId, int maxUses, int numberOfDays)
1762 {
1763     auto job = new FindOrCreateInviteJob(this);
1764     job->setRoomId(roomId);
1765     job->setMaxUses(maxUses);
1766     job->setNumberOfDays(numberOfDays);
1767     initializeRestApiJob(job);
1768     connect(job, &FindOrCreateInviteJob::findOrCreateInviteDone, this, &Connection::findOrCreateInviteDone);
1769     if (!job->start()) {
1770         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start findOrCreateInviteJob";
1771     }
1772 }
1773 
1774 void Connection::sendUserEmailCode(const QString &identifier)
1775 {
1776     auto job = new User2FASendEmailCodeJob(this);
1777     job->setUsernameOrEmail(identifier);
1778     initializeRestApiJob(job);
1779     connect(job, &User2FASendEmailCodeJob::sendEmailCodeDone, this, &Connection::sendEmailCodeDone);
1780     if (!job->start()) {
1781         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start User2FASendEmailCodeJob";
1782     }
1783 }
1784 
1785 void Connection::deleteOwnAccount(const QString &password)
1786 {
1787     auto job = new DeleteOwnAccountJob(this);
1788     job->setPassword(password);
1789     initializeRestApiJob(job);
1790     connect(job, &DeleteOwnAccountJob::deleteOwnAccountDone, this, &Connection::deleteOwnAccountDone);
1791     if (!job->start()) {
1792         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start DeleteOwnAccountJob";
1793     }
1794 }
1795 
1796 void Connection::registerNewUser(const RocketChatRestApi::RegisterUserJob::RegisterUserInfo &userInfo)
1797 {
1798     auto job = new RegisterUserJob(this);
1799     job->setRegisterUserInfo(userInfo);
1800     initializeRestApiJob(job);
1801     connect(job, &RegisterUserJob::registerUserDone, this, &Connection::registerUserDone);
1802     if (!job->start()) {
1803         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start RegisterUserJob";
1804     }
1805 }
1806 
1807 void Connection::enable2FaEmailJob(bool enable)
1808 {
1809     if (enable) {
1810         auto job = new User2FAEnableEmailJob(this);
1811         initializeRestApiJob(job);
1812         connect(job, &User2FAEnableEmailJob::enableEmailDone, this, &Connection::enableEmailDone);
1813         if (!job->start()) {
1814             qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start User2FAEnableEmailJob";
1815         }
1816     } else {
1817         auto job = new User2FADisableEmailJob(this);
1818         initializeRestApiJob(job);
1819         connect(job, &User2FADisableEmailJob::disableEmailDone, this, &Connection::disableEmailDone);
1820         if (!job->start()) {
1821             qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start User2FADisableEmailJob";
1822         }
1823     }
1824 }
1825 
1826 void Connection::updateOwnBasicInfo(const RocketChatRestApi::UsersUpdateOwnBasicInfoJob::UpdateOwnBasicInfo &info)
1827 {
1828     auto job = new UsersUpdateOwnBasicInfoJob(this);
1829     job->setUpdateOwnBasicInfo(info);
1830     initializeRestApiJob(job);
1831     connect(job, &UsersUpdateOwnBasicInfoJob::updateOwnBasicInfoDone, this, &Connection::updateOwnBasicInfoDone);
1832     // Clear all other tokens when password was changed
1833     connect(job, &UsersUpdateOwnBasicInfoJob::passwordChanged, this, &Connection::removeOtherTokens);
1834 
1835     if (!job->start()) {
1836         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start UsersUpdateOwnBasicInfoJob";
1837     }
1838 }
1839 
1840 void Connection::removeOtherTokens()
1841 {
1842     auto job = new RemoveOtherTokensJob(this);
1843     initializeRestApiJob(job);
1844     connect(job, &RemoveOtherTokensJob::removeOtherTokensDone, this, &Connection::removeOtherTokensDone);
1845     if (!job->start()) {
1846         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start RemoveOtherTokensJob";
1847     }
1848 }
1849 
1850 void Connection::cleanChannelHistory(const RocketChatRestApi::RoomsCleanHistoryJob::CleanHistoryInfo &info)
1851 {
1852     auto job = new RoomsCleanHistoryJob(this);
1853     job->setCleanHistoryInfo(info);
1854     initializeRestApiJob(job);
1855     connect(job, &RoomsCleanHistoryJob::cleanHistoryDone, this, &Connection::cleanHistoryDone);
1856     if (!job->start()) {
1857         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChannelCleanHistoryJob";
1858     }
1859 }
1860 
1861 void Connection::getRoomsAdmin(const RocketChatRestApi::AdminRoomsJob::AdminRoomsJobInfo &info)
1862 {
1863     auto job = new AdminRoomsJob(this);
1864     job->setRoomsAdminInfo(info);
1865     initializeRestApiJob(job);
1866     connect(job, &AdminRoomsJob::adminRoomsDone, this, &Connection::roomsAdminDone);
1867     if (!job->start()) {
1868         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start RoomsAdminJob";
1869     }
1870 }
1871 
1872 void Connection::getChannelsCounter(const QString &roomId)
1873 {
1874     auto job = new ChannelGetCountersJob(this);
1875     initializeRestApiJob(job);
1876     ChannelGroupBaseJob::ChannelGroupInfo info;
1877     info.channelGroupInfoType = ChannelGroupBaseJob::ChannelGroupInfoType::Identifier;
1878     info.identifier = roomId;
1879     job->setChannelGroupInfo(info);
1880     connect(job, &ChannelGetCountersJob::channelGetCountersDone, this, &Connection::channelGetCountersDone);
1881     if (!job->start()) {
1882         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChannelGetCountersJob";
1883     }
1884 }
1885 
1886 void Connection::setUserPreferences(const RocketChatRestApi::UsersSetPreferencesJob::UsersSetPreferencesInfo &info)
1887 {
1888     auto job = new UsersSetPreferencesJob(this);
1889     job->setUsersSetPreferencesInfo(info);
1890     initializeRestApiJob(job);
1891     connect(job, &UsersSetPreferencesJob::usersSetPreferencesDone, this, &Connection::usersSetPreferencesDone);
1892     if (!job->start()) {
1893         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start UsersSetPreferencesJob";
1894     }
1895 }
1896 
1897 void Connection::createCustomUserStatus(const CustomUserStatusCreateJob::StatusCreateInfo &statusCreateInfo)
1898 {
1899     auto job = new CustomUserStatusCreateJob(this);
1900     job->setStatusCreateInfo(statusCreateInfo);
1901     initializeRestApiJob(job);
1902     connect(job, &CustomUserStatusCreateJob::createUserStatusDone, this, &Connection::createUserStatusDone);
1903     if (!job->start()) {
1904         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start CustomUserStatusCreateJob";
1905     }
1906 }
1907 
1908 void Connection::deleteCustomUserStatus(const QString &customUserStatusId)
1909 {
1910     auto job = new CustomUserStatusDeleteJob(this);
1911     job->setCustomUserStatusId(customUserStatusId);
1912     initializeRestApiJob(job);
1913     connect(job, &CustomUserStatusDeleteJob::userStatusDeletedDone, this, &Connection::userStatusDeletedDone);
1914     if (!job->start()) {
1915         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start CustomUserStatusDeleteJob";
1916     }
1917 }
1918 
1919 void Connection::updateCustomUserStatus(const CustomUserStatusUpdateJob::StatusUpdateInfo &statusUpdateInfo)
1920 {
1921     auto job = new CustomUserStatusUpdateJob(this);
1922     job->setStatusUpdateInfo(statusUpdateInfo);
1923     initializeRestApiJob(job);
1924     connect(job, &CustomUserStatusUpdateJob::customUserUpdateDone, this, &Connection::customUserUpdateDone);
1925     if (!job->start()) {
1926         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start CustomUserStatusUpdateJob";
1927     }
1928 }
1929 
1930 void Connection::resetAvatar(const UserBaseJob::UserInfo &info)
1931 {
1932     auto job = new ResetAvatarJob(this);
1933     job->setUserInfo(info);
1934     initializeRestApiJob(job);
1935     connect(job, &ResetAvatarJob::resetAvatarDone, this, &Connection::resetAvatarDone);
1936     if (!job->start()) {
1937         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ResetAvatarJob";
1938     }
1939 }
1940 
1941 void Connection::statistics(bool refresh)
1942 {
1943     auto job = new StatisticsJob(this);
1944     job->setRefresh(refresh);
1945     initializeRestApiJob(job);
1946     connect(job, &StatisticsJob::statisticDone, this, &Connection::statisticDone);
1947     if (!job->start()) {
1948         qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start StatisticsJob";
1949     }
1950 }
1951 
1952 #include "moc_connection.cpp"