diff --git a/src/controller.cpp b/src/controller.cpp index 23285ffae..1cf79322d 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -42,7 +42,15 @@ #include "trayicon_sni.h" #endif +#ifdef HAVE_KUNIFIEDPUSH +#include +#include +#include +#include +#endif + using namespace Quotient; +using namespace Qt::StringLiterals; Controller::Controller(QObject *parent) : QObject(parent) @@ -99,6 +107,57 @@ Controller::Controller(QObject *parent) } oldAccountCount = m_accountRegistry.size(); }); + +#ifdef HAVE_KUNIFIEDPUSH + auto connector = new KUnifiedPush::Connector(QStringLiteral("org.kde.neochat")); + connect(connector, &KUnifiedPush::Connector::endpointChanged, this, &Controller::setupPushNotifications); + + connector->registerClient(i18n("Receiving push notifications")); +#endif +} + +QCoro::Task Controller::setupPushNotifications(QString endpoint) +{ +#ifdef HAVE_KUNIFIEDPUSH + while (!activeConnection()) { + co_await qCoro(this, &Controller::activeConnectionChanged); + } + + QUrl gatewayEndpoint(endpoint); + gatewayEndpoint.setPath(QStringLiteral("/_matrix/push/v1/notify")); + + QNetworkRequest checkGateway(gatewayEndpoint); + auto reply = co_await NetworkAccessManager::instance()->get(checkGateway); + + // We want to check if this UnifiedPush server has a Matrix gateway + // This is because Matrix does not natively support UnifiedPush + const QJsonObject replyJson = QJsonDocument::fromJson(reply->readAll()).object(); + + if (replyJson["unifiedpush"_L1]["gateway"_L1].toString() == QStringLiteral("matrix")) { + // FIXME: Currently hardcoded for ntfy URLs + // We need to pass the ntfy topic as the pushkey. Is there a more generic way to handle this? + const QUrl endpointUrl(endpoint); + + // Pop the slash off of the path + const QString pushkey = endpointUrl.path().removeFirst(); + + Controller::instance().activeConnection()->callApi( + pushkey, + QStringLiteral("http"), + QStringLiteral("org.kde.neochat"), + QStringLiteral("NeoChat"), + Controller::instance().activeConnection()->deviceId(), + QString(), // FIXME: what is profileTag? + QStringLiteral("en"), + PostPusherJob::PusherData{QUrl::fromUserInput(gatewayEndpoint.toString()), QStringLiteral(" ")}); + + qInfo() << "Registered for push notifications"; + } else { + qWarning() << "There's no gateway, not setting up push notifications."; + } +#else + co_return; +#endif } Controller &Controller::instance() diff --git a/src/controller.h b/src/controller.h index 107daf8e4..40fedede2 100644 --- a/src/controller.h +++ b/src/controller.h @@ -11,6 +11,7 @@ #include #include #include +#include class NeoChatRoom; class TrayIcon; @@ -124,6 +125,10 @@ public: private: explicit Controller(QObject *parent = nullptr); + // note: this is intentionally a copied QString because + // the reference could be destroyed before the task is finished + QCoro::Task setupPushNotifications(QString endpoint); + QPointer m_connection; TrayIcon *m_trayIcon = nullptr;