mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Switch to v2 of RAnders00's recent-messages API, so we support showing
old sub messages and stuff
This commit is contained in:
parent
a4cba22bcb
commit
8b3867fa7d
4 changed files with 183 additions and 39 deletions
|
@ -44,6 +44,46 @@ IrcMessageHandler &IrcMessageHandler::getInstance()
|
|||
return instance;
|
||||
}
|
||||
|
||||
std::vector<MessagePtr> IrcMessageHandler::parseMessage(
|
||||
Channel *channel, Communi::IrcMessage *message)
|
||||
{
|
||||
std::vector<MessagePtr> builtMessages;
|
||||
|
||||
auto command = message->command();
|
||||
|
||||
if (command == "PRIVMSG")
|
||||
{
|
||||
return this->parsePrivMessage(
|
||||
channel, static_cast<Communi::IrcPrivateMessage *>(message));
|
||||
}
|
||||
else if (command == "USERNOTICE")
|
||||
{
|
||||
return this->parseUserNoticeMessage(channel, message);
|
||||
}
|
||||
else if (command == "NOTICE")
|
||||
{
|
||||
return this->parseNoticeMessage(
|
||||
static_cast<Communi::IrcNoticeMessage *>(message));
|
||||
}
|
||||
|
||||
return builtMessages;
|
||||
}
|
||||
|
||||
std::vector<MessagePtr> IrcMessageHandler::parsePrivMessage(
|
||||
Channel *channel, Communi::IrcPrivateMessage *message)
|
||||
{
|
||||
log("Parse priv msg");
|
||||
std::vector<MessagePtr> builtMessages;
|
||||
MessageParseArgs args;
|
||||
TwitchMessageBuilder builder(channel, message, args, message->content(),
|
||||
message->isAction());
|
||||
if (!builder.isIgnored())
|
||||
{
|
||||
builtMessages.emplace_back(builder.build());
|
||||
}
|
||||
return builtMessages;
|
||||
}
|
||||
|
||||
void IrcMessageHandler::handlePrivMessage(Communi::IrcPrivateMessage *message,
|
||||
TwitchServer &server)
|
||||
{
|
||||
|
@ -302,6 +342,56 @@ void IrcMessageHandler::handleWhisperMessage(Communi::IrcMessage *message)
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<MessagePtr> IrcMessageHandler::parseUserNoticeMessage(
|
||||
Channel *channel, Communi::IrcMessage *message)
|
||||
{
|
||||
std::vector<MessagePtr> builtMessages;
|
||||
|
||||
auto data = message->toData();
|
||||
|
||||
auto tags = message->tags();
|
||||
auto parameters = message->parameters();
|
||||
|
||||
auto target = parameters[0];
|
||||
QString msgType = tags.value("msg-id", "").toString();
|
||||
QString content;
|
||||
if (parameters.size() >= 2)
|
||||
{
|
||||
content = parameters[1];
|
||||
}
|
||||
|
||||
if (msgType == "sub" || msgType == "resub" || msgType == "subgift")
|
||||
{
|
||||
// Sub-specific message. I think it's only allowed for "resub" messages
|
||||
// atm
|
||||
if (!content.isEmpty())
|
||||
{
|
||||
MessageParseArgs args;
|
||||
args.trimSubscriberUsername = true;
|
||||
|
||||
TwitchMessageBuilder builder(channel, message, args, content,
|
||||
false);
|
||||
builder->flags.set(MessageFlag::Subscription);
|
||||
builder->flags.unset(MessageFlag::Highlighted);
|
||||
builtMessages.emplace_back(builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
auto it = tags.find("system-msg");
|
||||
|
||||
if (it != tags.end())
|
||||
{
|
||||
auto b = MessageBuilder(systemMessage,
|
||||
parseTagString(it.value().toString()));
|
||||
|
||||
b->flags.set(MessageFlag::Subscription);
|
||||
auto newMessage = b.release();
|
||||
builtMessages.emplace_back(newMessage);
|
||||
}
|
||||
|
||||
return builtMessages;
|
||||
}
|
||||
|
||||
void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message,
|
||||
TwitchServer &server)
|
||||
{
|
||||
|
@ -381,35 +471,49 @@ void IrcMessageHandler::handleModeMessage(Communi::IrcMessage *message)
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<MessagePtr> IrcMessageHandler::parseNoticeMessage(
|
||||
Communi::IrcNoticeMessage *message)
|
||||
{
|
||||
std::vector<MessagePtr> builtMessages;
|
||||
|
||||
builtMessages.emplace_back(makeSystemMessage(message->content()));
|
||||
|
||||
return builtMessages;
|
||||
}
|
||||
|
||||
void IrcMessageHandler::handleNoticeMessage(Communi::IrcNoticeMessage *message)
|
||||
{
|
||||
auto app = getApp();
|
||||
MessagePtr msg = makeSystemMessage(message->content());
|
||||
auto builtMessages = this->parseNoticeMessage(message);
|
||||
|
||||
QString channelName;
|
||||
if (!trimChannelName(message->target(), channelName))
|
||||
for (auto msg : builtMessages)
|
||||
{
|
||||
// Notice wasn't targeted at a single channel, send to all twitch
|
||||
// channels
|
||||
app->twitch.server->forEachChannelAndSpecialChannels(
|
||||
[msg](const auto &c) {
|
||||
c->addMessage(msg); //
|
||||
});
|
||||
QString channelName;
|
||||
if (!trimChannelName(message->target(), channelName))
|
||||
{
|
||||
// Notice wasn't targeted at a single channel, send to all twitch
|
||||
// channels
|
||||
app->twitch.server->forEachChannelAndSpecialChannels(
|
||||
[msg](const auto &c) {
|
||||
c->addMessage(msg); //
|
||||
});
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
auto channel = app->twitch.server->getChannelOrEmpty(channelName);
|
||||
|
||||
if (channel->isEmpty())
|
||||
{
|
||||
log("[IrcManager:handleNoticeMessage] Channel {} not found in "
|
||||
"channel "
|
||||
"manager ",
|
||||
channelName);
|
||||
return;
|
||||
}
|
||||
|
||||
channel->addMessage(msg);
|
||||
}
|
||||
|
||||
auto channel = app->twitch.server->getChannelOrEmpty(channelName);
|
||||
|
||||
if (channel->isEmpty())
|
||||
{
|
||||
log("[IrcManager:handleNoticeMessage] Channel {} not found in channel "
|
||||
"manager ",
|
||||
channelName);
|
||||
return;
|
||||
}
|
||||
|
||||
channel->addMessage(msg);
|
||||
}
|
||||
|
||||
void IrcMessageHandler::handleWriteConnectionNoticeMessage(
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <IrcMessage>
|
||||
#include "messages/Message.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class TwitchServer;
|
||||
class Channel;
|
||||
|
||||
class IrcMessageHandler
|
||||
{
|
||||
|
@ -13,6 +15,13 @@ class IrcMessageHandler
|
|||
public:
|
||||
static IrcMessageHandler &getInstance();
|
||||
|
||||
// parseMessage parses a single IRC message into 0+ Chatterino messages
|
||||
std::vector<MessagePtr> parseMessage(Channel *channel,
|
||||
Communi::IrcMessage *message);
|
||||
|
||||
// parsePrivMessage arses a single IRC PRIVMSG into 0-1 Chatterino messages
|
||||
std::vector<MessagePtr> parsePrivMessage(
|
||||
Channel *channel, Communi::IrcPrivateMessage *message);
|
||||
void handlePrivMessage(Communi::IrcPrivateMessage *message,
|
||||
TwitchServer &server);
|
||||
|
||||
|
@ -20,10 +29,22 @@ public:
|
|||
void handleClearChatMessage(Communi::IrcMessage *message);
|
||||
void handleUserStateMessage(Communi::IrcMessage *message);
|
||||
void handleWhisperMessage(Communi::IrcMessage *message);
|
||||
|
||||
// parseUserNoticeMessage parses a single IRC USERNOTICE message into 0+
|
||||
// chatterino messages
|
||||
std::vector<MessagePtr> parseUserNoticeMessage(
|
||||
Channel *channel, Communi::IrcMessage *message);
|
||||
void handleUserNoticeMessage(Communi::IrcMessage *message,
|
||||
TwitchServer &server);
|
||||
|
||||
void handleModeMessage(Communi::IrcMessage *message);
|
||||
|
||||
// parseNoticeMessage parses a single IRC NOTICE message into 0+ chatterino
|
||||
// messages
|
||||
std::vector<MessagePtr> parseNoticeMessage(
|
||||
Communi::IrcNoticeMessage *message);
|
||||
void handleNoticeMessage(Communi::IrcNoticeMessage *message);
|
||||
|
||||
void handleWriteConnectionNoticeMessage(Communi::IrcNoticeMessage *message);
|
||||
|
||||
void handleJoinMessage(Communi::IrcMessage *message);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "messages/Message.hpp"
|
||||
#include "providers/bttv/BttvEmotes.hpp"
|
||||
#include "providers/bttv/LoadBttvChannelEmote.hpp"
|
||||
#include "providers/twitch/IrcMessageHandler.hpp"
|
||||
#include "providers/twitch/PubsubClient.hpp"
|
||||
#include "providers/twitch/TwitchCommon.hpp"
|
||||
#include "providers/twitch/TwitchMessageBuilder.hpp"
|
||||
|
@ -29,10 +30,12 @@
|
|||
|
||||
namespace chatterino {
|
||||
namespace {
|
||||
// parseRecentMessages takes a json object and returns a vector of
|
||||
// Communi IrcMessages
|
||||
auto parseRecentMessages(const QJsonObject &jsonRoot, ChannelPtr channel)
|
||||
{
|
||||
QJsonArray jsonMessages = jsonRoot.value("messages").toArray();
|
||||
std::vector<MessagePtr> messages;
|
||||
std::vector<Communi::IrcMessage *> messages;
|
||||
|
||||
if (jsonMessages.empty())
|
||||
return messages;
|
||||
|
@ -40,18 +43,8 @@ namespace {
|
|||
for (const auto jsonMessage : jsonMessages)
|
||||
{
|
||||
auto content = jsonMessage.toString().toUtf8();
|
||||
// passing nullptr as the channel makes the message invalid but we
|
||||
// don't check for that anyways
|
||||
auto message = Communi::IrcMessage::fromData(content, nullptr);
|
||||
auto privMsg = dynamic_cast<Communi::IrcPrivateMessage *>(message);
|
||||
assert(privMsg);
|
||||
|
||||
MessageParseArgs args;
|
||||
TwitchMessageBuilder builder(channel.get(), privMsg, args);
|
||||
builder.message().flags.set(MessageFlag::RecentMessage);
|
||||
|
||||
if (!builder.isIgnored())
|
||||
messages.push_back(builder.build());
|
||||
messages.emplace_back(
|
||||
Communi::IrcMessage::fromData(content, nullptr));
|
||||
}
|
||||
|
||||
return messages;
|
||||
|
@ -611,8 +604,8 @@ Outcome TwitchChannel::parseLiveStatus(const rapidjson::Document &document)
|
|||
|
||||
void TwitchChannel::loadRecentMessages()
|
||||
{
|
||||
static QString genericURL =
|
||||
"https://recent-messages.robotty.de/v1/recent-messages/%1";
|
||||
static QString genericURL = "https://recent-messages.robotty.de/api/v2/"
|
||||
"recent-messages/%1?clearchatToNotice=true";
|
||||
|
||||
NetworkRequest request(genericURL.arg(this->getName()));
|
||||
request.setCaller(QThread::currentThread());
|
||||
|
@ -626,7 +619,21 @@ void TwitchChannel::loadRecentMessages()
|
|||
|
||||
auto messages = parseRecentMessages(result.parseJson(), shared);
|
||||
|
||||
shared->addMessagesAtStart(messages);
|
||||
auto &handler = IrcMessageHandler::getInstance();
|
||||
|
||||
std::vector<MessagePtr> allBuiltMessages;
|
||||
|
||||
for (auto message : messages)
|
||||
{
|
||||
for (auto builtMessage :
|
||||
handler.parseMessage(shared.get(), message))
|
||||
{
|
||||
builtMessage->flags.set(MessageFlag::RecentMessage);
|
||||
allBuiltMessages.emplace_back(builtMessage);
|
||||
}
|
||||
}
|
||||
|
||||
shared->addMessagesAtStart(allBuiltMessages);
|
||||
|
||||
return Success;
|
||||
});
|
||||
|
|
|
@ -109,12 +109,24 @@ MessagePtr TwitchMessageBuilder::build()
|
|||
|
||||
this->appendChannelName();
|
||||
|
||||
if (this->tags.contains("rm-deleted"))
|
||||
{
|
||||
this->message().flags.set(MessageFlag::Disabled);
|
||||
}
|
||||
|
||||
// timestamp
|
||||
bool isPastMsg = this->tags.contains("historical");
|
||||
if (isPastMsg)
|
||||
{
|
||||
// This may be architecture dependent(datatype)
|
||||
qint64 ts = this->tags.value("tmi-sent-ts").toLongLong();
|
||||
bool customReceived = false;
|
||||
qint64 ts =
|
||||
this->tags.value("rm-received-ts").toLongLong(&customReceived);
|
||||
if (!customReceived)
|
||||
{
|
||||
ts = this->tags.value("tmi-sent-ts").toLongLong();
|
||||
}
|
||||
|
||||
QDateTime dateTime = QDateTime::fromMSecsSinceEpoch(ts);
|
||||
this->emplace<TimestampElement>(dateTime.time());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue