File indexing completed on 2024-05-12 05:02:56

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