Workaround for t.me/+... links

This commit is contained in:
Sebastian Wolf 2022-05-01 14:04:28 +02:00
parent 81cf5b6852
commit 0e7ae00a67
No known key found for this signature in database
GPG key ID: CEA9522B5F38A90A
4 changed files with 80 additions and 3 deletions

View file

@ -45,6 +45,9 @@ ApplicationWindow
onOpenFileExternally: { onOpenFileExternally: {
Qt.openUrlExternally(filePath); Qt.openUrlExternally(filePath);
} }
onTgUrlFound: {
Functions.handleLink(tgUrl);
}
} }
AppNotification { AppNotification {

View file

@ -387,8 +387,8 @@ function handleTMeLink(link, usedPrefix) {
// Do the necessary stuff to open the chat if successful // Do the necessary stuff to open the chat if successful
// Fail with nice error message if it doesn't work // Fail with nice error message if it doesn't work
} else if (link.indexOf("/+") !== -1) { } else if (link.indexOf("/+") !== -1) {
// Can't handle t.me/+... links, let the user choose the browser instead // Can't handle t.me/+... links directly, try to parse the Telegram page...
Qt.openUrlExternally(link); tdLibWrapper.getPageSource(link);
} else { } else {
Debug.log("Search public chat: ", link.substring(usedPrefix.length)); Debug.log("Search public chat: ", link.substring(usedPrefix.length));
tdLibWrapper.searchPublicChat(link.substring(usedPrefix.length), true); tdLibWrapper.searchPublicChat(link.substring(usedPrefix.length), true);

View file

@ -53,7 +53,7 @@ namespace {
const QString CHAT_LIST_MAIN("chatListMain"); const QString CHAT_LIST_MAIN("chatListMain");
} }
TDLibWrapper::TDLibWrapper(AppSettings *appSettings, MceInterface *mceInterface, QObject *parent) : QObject(parent), joinChatRequested(false) TDLibWrapper::TDLibWrapper(AppSettings *appSettings, MceInterface *mceInterface, QObject *parent) : QObject(parent), manager(new QNetworkAccessManager(this)), joinChatRequested(false)
{ {
LOG("Initializing TD Lib..."); LOG("Initializing TD Lib...");
this->appSettings = appSettings; this->appSettings = appSettings;
@ -1421,6 +1421,21 @@ void TDLibWrapper::getMessageAvailableReactions(qlonglong chatId, qlonglong mess
this->sendRequest(requestObject); this->sendRequest(requestObject);
} }
void TDLibWrapper::getPageSource(const QString &address)
{
QUrl url = QUrl(address);
QNetworkRequest request(url);
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
request.setHeader(QNetworkRequest::UserAgentHeader, "Fernschreiber Bot (Sailfish OS)");
request.setRawHeader(QByteArray("Accept"), QByteArray("text/html,application/xhtml+xml"));
request.setRawHeader(QByteArray("Accept-Charset"), QByteArray("utf-8"));
request.setRawHeader(QByteArray("Connection"), QByteArray("close"));
request.setRawHeader(QByteArray("Cache-Control"), QByteArray("max-age=0"));
QNetworkReply *reply = manager->get(request);
connect(reply, SIGNAL(finished()), this, SLOT(handleGetPageSourceFinished()));
}
void TDLibWrapper::searchEmoji(const QString &queryString) void TDLibWrapper::searchEmoji(const QString &queryString)
{ {
LOG("Searching emoji" << queryString); LOG("Searching emoji" << queryString);
@ -1910,6 +1925,56 @@ void TDLibWrapper::handleSponsoredMessage(qlonglong chatId, const QVariantMap &m
} }
} }
void TDLibWrapper::handleGetPageSourceFinished()
{
LOG("TDLibWrapper::handleGetPageSourceFinished");
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError) {
return;
}
QString requestAddress = reply->request().url().toString();
QVariant contentTypeHeader = reply->header(QNetworkRequest::ContentTypeHeader);
if (!contentTypeHeader.isValid()) {
return;
}
LOG("Page source content type header: " + contentTypeHeader.toString());
if (contentTypeHeader.toString().indexOf("text/html", 0, Qt::CaseInsensitive) == -1) {
LOG(requestAddress + " is not HTML, not searching for TG URL...");
return;
}
QString charset = "UTF-8";
QRegularExpression charsetRegularExpression("charset\\s*\\=[\\s\\\"\\\']*([^\\s\\\"\\\'\\,>]*)");
QRegularExpressionMatchIterator matchIterator = charsetRegularExpression.globalMatch(contentTypeHeader.toString());
QStringList availableCharsets;
while (matchIterator.hasNext()) {
QRegularExpressionMatch nextMatch = matchIterator.next();
QString currentCharset = nextMatch.captured(1).toUpper();
LOG("Available page source charset: " << currentCharset);
availableCharsets.append(currentCharset);
}
if (availableCharsets.size() > 0 && !availableCharsets.contains("UTF-8")) {
// If we haven't received the requested UTF-8, we simply use the last one which we received in the header
charset = availableCharsets.last();
}
LOG("Charset for " << requestAddress << ": " << charset);
QByteArray rawDocument = reply->readAll();
QTextCodec *codec = QTextCodec::codecForName(charset.toUtf8());
if (codec == nullptr){
return;
}
QString resultDocument = codec->toUnicode(rawDocument);
QRegExp urlRegex("href\\=\"(tg\\:[^\"]+)\\\"");
if (urlRegex.indexIn(resultDocument) != -1) {
LOG("TG URL found: " + urlRegex.cap(1));
emit tgUrlFound(urlRegex.cap(1));
}
}
void TDLibWrapper::setInitialParameters() void TDLibWrapper::setInitialParameters()
{ {
LOG("Sending initial parameters to TD Lib"); LOG("Sending initial parameters to TD Lib");

View file

@ -20,6 +20,10 @@
#define TDLIBWRAPPER_H #define TDLIBWRAPPER_H
#include <QCoreApplication> #include <QCoreApplication>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <td/telegram/td_json_client.h> #include <td/telegram/td_json_client.h>
#include "tdlibreceiver.h" #include "tdlibreceiver.h"
#include "dbusadaptor.h" #include "dbusadaptor.h"
@ -232,6 +236,7 @@ public:
Q_INVOKABLE void getActiveSessions(); Q_INVOKABLE void getActiveSessions();
Q_INVOKABLE void terminateSession(const QString &sessionId); Q_INVOKABLE void terminateSession(const QString &sessionId);
Q_INVOKABLE void getMessageAvailableReactions(qlonglong chatId, qlonglong messageId); Q_INVOKABLE void getMessageAvailableReactions(qlonglong chatId, qlonglong messageId);
Q_INVOKABLE void getPageSource(const QString &address);
// Others (candidates for extraction ;)) // Others (candidates for extraction ;))
Q_INVOKABLE void searchEmoji(const QString &queryString); Q_INVOKABLE void searchEmoji(const QString &queryString);
@ -315,6 +320,7 @@ signals:
void sessionsReceived(const QVariantList &sessions); void sessionsReceived(const QVariantList &sessions);
void openFileExternally(const QString &filePath); void openFileExternally(const QString &filePath);
void availableReactionsReceived(qlonglong messageId, const QStringList &reactions); void availableReactionsReceived(qlonglong messageId, const QStringList &reactions);
void tgUrlFound(const QString &tgUrl);
public slots: public slots:
void handleVersionDetected(const QString &version); void handleVersionDetected(const QString &version);
@ -343,6 +349,8 @@ public slots:
void handleUpdatedUserPrivacySettingRules(const QVariantMap &updatedRules); void handleUpdatedUserPrivacySettingRules(const QVariantMap &updatedRules);
void handleSponsoredMessage(qlonglong chatId, const QVariantMap &message); void handleSponsoredMessage(qlonglong chatId, const QVariantMap &message);
void handleGetPageSourceFinished();
private: private:
void setOption(const QString &name, const QString &type, const QVariant &value); void setOption(const QString &name, const QString &type, const QVariant &value);
void setInitialParameters(); void setInitialParameters();
@ -353,6 +361,7 @@ private:
private: private:
void *tdLibClient; void *tdLibClient;
QNetworkAccessManager *manager;
AppSettings *appSettings; AppSettings *appSettings;
MceInterface *mceInterface; MceInterface *mceInterface;
TDLibReceiver *tdLibReceiver; TDLibReceiver *tdLibReceiver;