feat(eventsub): implement (shared-chat) timeout (#5995)
This commit is contained in:
+1
-1
@@ -30,7 +30,7 @@
|
||||
- Bugfix: Fixed the input font not immediately updating when zooming in/out. (#5960)
|
||||
- Bugfix: Fixed color input thinking blue is also red. (#5982)
|
||||
- Dev: Subscriptions to PubSub channel points redemption topics now use no auth token, making it continue to work during PubSub shutdown. (#5947)
|
||||
- Dev: Add initial experimental EventSub support. (#5837, #5895, #5897, #5904, #5910, #5903, #5915, #5916, #5930, #5935, #5932, #5943, #5952, #5953, #5968, #5973, #5974, #5980, #5981, #5985, #5990, #5992, #5993, #5996)
|
||||
- Dev: Add initial experimental EventSub support. (#5837, #5895, #5897, #5904, #5910, #5903, #5915, #5916, #5930, #5935, #5932, #5943, #5952, #5953, #5968, #5973, #5974, #5980, #5981, #5985, #5990, #5992, #5993, #5996, #5995)
|
||||
- Dev: Remove unneeded platform specifier for toasts. (#5914)
|
||||
- Dev: Highlight checks now use non-capturing groups for the boundaries. (#5784)
|
||||
- Dev: Removed unused PubSub whisper code. (#5898)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <boost/json.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
namespace chatterino::eventsub::lib::payload::channel_moderate::v2 {
|
||||
@@ -197,15 +198,14 @@ struct SharedChatUnban : public Unban {
|
||||
struct Timeout {
|
||||
static constexpr std::string_view TAG = "timeout";
|
||||
|
||||
std::string userID;
|
||||
std::string userLogin;
|
||||
std::string userName;
|
||||
// TODO: Verify that we handle null here
|
||||
std::string reason;
|
||||
// TODO: This should be a timestamp?
|
||||
std::string expiresAt;
|
||||
String userID;
|
||||
String userLogin;
|
||||
String userName;
|
||||
String reason;
|
||||
/// json_tag=AsISO8601
|
||||
std::chrono::system_clock::time_point expiresAt;
|
||||
};
|
||||
struct SharedChatTimeout : public Ban {
|
||||
struct SharedChatTimeout : public Timeout {
|
||||
static constexpr std::string_view TAG = "shared_chat_timeout";
|
||||
};
|
||||
|
||||
@@ -220,7 +220,7 @@ struct Untimeout {
|
||||
std::string userLogin;
|
||||
std::string userName;
|
||||
};
|
||||
struct SharedChatUntimeout : public Ban {
|
||||
struct SharedChatUntimeout : public Untimeout {
|
||||
static constexpr std::string_view TAG = "shared_chat_untimeout";
|
||||
};
|
||||
|
||||
|
||||
@@ -477,7 +477,7 @@ boost::json::result_for<Timeout, boost::json::value>::type tag_invoke(
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
|
||||
auto userID = boost::json::try_value_to<std::string>(*jvuserID);
|
||||
auto userID = boost::json::try_value_to<String>(*jvuserID);
|
||||
|
||||
if (userID.has_error())
|
||||
{
|
||||
@@ -490,7 +490,7 @@ boost::json::result_for<Timeout, boost::json::value>::type tag_invoke(
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
|
||||
auto userLogin = boost::json::try_value_to<std::string>(*jvuserLogin);
|
||||
auto userLogin = boost::json::try_value_to<String>(*jvuserLogin);
|
||||
|
||||
if (userLogin.has_error())
|
||||
{
|
||||
@@ -503,7 +503,7 @@ boost::json::result_for<Timeout, boost::json::value>::type tag_invoke(
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
|
||||
auto userName = boost::json::try_value_to<std::string>(*jvuserName);
|
||||
auto userName = boost::json::try_value_to<String>(*jvuserName);
|
||||
|
||||
if (userName.has_error())
|
||||
{
|
||||
@@ -516,20 +516,24 @@ boost::json::result_for<Timeout, boost::json::value>::type tag_invoke(
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
|
||||
auto reason = boost::json::try_value_to<std::string>(*jvreason);
|
||||
auto reason = boost::json::try_value_to<String>(*jvreason);
|
||||
|
||||
if (reason.has_error())
|
||||
{
|
||||
return reason.error();
|
||||
}
|
||||
|
||||
static_assert(std::is_trivially_copyable_v<std::remove_reference_t<
|
||||
decltype(std::declval<Timeout>().expiresAt)>>);
|
||||
const auto *jvexpiresAt = root.if_contains("expires_at");
|
||||
if (jvexpiresAt == nullptr)
|
||||
{
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
|
||||
auto expiresAt = boost::json::try_value_to<std::string>(*jvexpiresAt);
|
||||
auto expiresAt =
|
||||
boost::json::try_value_to<std::chrono::system_clock::time_point>(
|
||||
*jvexpiresAt, AsISO8601());
|
||||
|
||||
if (expiresAt.has_error())
|
||||
{
|
||||
@@ -541,7 +545,7 @@ boost::json::result_for<Timeout, boost::json::value>::type tag_invoke(
|
||||
.userLogin = std::move(userLogin.value()),
|
||||
.userName = std::move(userName.value()),
|
||||
.reason = std::move(reason.value()),
|
||||
.expiresAt = std::move(expiresAt.value()),
|
||||
.expiresAt = expiresAt.value(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -549,7 +553,7 @@ boost::json::result_for<SharedChatTimeout, boost::json::value>::type tag_invoke(
|
||||
boost::json::try_value_to_tag<SharedChatTimeout> /* tag */,
|
||||
const boost::json::value &jvRoot)
|
||||
{
|
||||
auto base = boost::json::try_value_to<Ban>(jvRoot);
|
||||
auto base = boost::json::try_value_to<Timeout>(jvRoot);
|
||||
if (base.has_error())
|
||||
{
|
||||
return base.error();
|
||||
@@ -618,7 +622,7 @@ boost::json::result_for<SharedChatUntimeout, boost::json::value>::type
|
||||
tag_invoke(boost::json::try_value_to_tag<SharedChatUntimeout> /* tag */,
|
||||
const boost::json::value &jvRoot)
|
||||
{
|
||||
auto base = boost::json::try_value_to<Ban>(jvRoot);
|
||||
auto base = boost::json::try_value_to<Untimeout>(jvRoot);
|
||||
if (base.has_error())
|
||||
{
|
||||
return base.error();
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
#include "Application.hpp"
|
||||
#include "messages/Message.hpp"
|
||||
#include "messages/MessageBuilder.hpp"
|
||||
#include "providers/twitch/eventsub/MessageBuilder.hpp"
|
||||
#include "providers/twitch/TwitchChannel.hpp"
|
||||
#include "singletons/Settings.hpp"
|
||||
#include "singletons/WindowManager.hpp"
|
||||
#include "util/FormatTime.hpp"
|
||||
#include "util/PostToThread.hpp"
|
||||
|
||||
namespace chatterino::eventsub {
|
||||
@@ -27,18 +29,59 @@ void handleModerateMessage(
|
||||
});
|
||||
}
|
||||
|
||||
void addModerateMessage(
|
||||
TwitchChannel *channel, MessagePtr message, const QDateTime &time,
|
||||
const lib::payload::channel_moderate::v2::Ban & /*action*/)
|
||||
void handleModerateMessage(
|
||||
TwitchChannel *chan, const QDateTime &time,
|
||||
const lib::payload::channel_moderate::v2::Event &event,
|
||||
const lib::payload::channel_moderate::v2::Timeout &action)
|
||||
{
|
||||
runInGuiThread([channel, msg{std::move(message)}, time] {
|
||||
channel->addOrReplaceTimeout(msg, time);
|
||||
if (getSettings()->hideModerated)
|
||||
{
|
||||
// XXX: This is expensive. We could use a layout request if the layout
|
||||
// would store the previous message flags.
|
||||
getApp()->getWindows()->forceLayoutChannelViews();
|
||||
}
|
||||
// Not all compilers support QDateTime::toStdSysMilliseconds
|
||||
std::chrono::system_clock::time_point chronoTime{
|
||||
std::chrono::milliseconds{time.toMSecsSinceEpoch()}};
|
||||
|
||||
auto duration =
|
||||
std::chrono::round<std::chrono::seconds>(action.expiresAt - chronoTime);
|
||||
|
||||
EventSubMessageBuilder builder(chan, time);
|
||||
builder->loginName = event.moderatorUserLogin.qt();
|
||||
|
||||
QString text;
|
||||
bool isShared = event.isFromSharedChat();
|
||||
|
||||
builder.appendUser(event.moderatorUserName, event.moderatorUserLogin, text);
|
||||
builder.emplaceSystemTextAndUpdate("timed out", text);
|
||||
builder.appendUser(action.userName, action.userLogin, text);
|
||||
|
||||
builder.emplaceSystemTextAndUpdate("for", text);
|
||||
builder
|
||||
.emplaceSystemTextAndUpdate(
|
||||
formatTime(static_cast<int>(duration.count())), text)
|
||||
->setTrailingSpace(isShared);
|
||||
|
||||
if (isShared)
|
||||
{
|
||||
builder.emplaceSystemTextAndUpdate("in", text);
|
||||
builder.appendUser(*event.sourceBroadcasterUserName,
|
||||
*event.sourceBroadcasterUserLogin, text, false);
|
||||
}
|
||||
|
||||
if (action.reason.view().empty())
|
||||
{
|
||||
builder.emplaceSystemTextAndUpdate(".", text);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.emplaceSystemTextAndUpdate(":", text);
|
||||
builder.emplaceSystemTextAndUpdate(action.reason.qt(), text);
|
||||
}
|
||||
|
||||
builder->messageText = text;
|
||||
builder->searchText = text;
|
||||
builder->timeoutUser = action.userLogin.qt();
|
||||
|
||||
auto msg = builder.release();
|
||||
runInGuiThread([chan, msg] {
|
||||
// TODO: addOrReplaceTimeout (doesn't work with shared chat yet)
|
||||
chan->addMessage(msg, MessageContext::Original);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -22,4 +22,9 @@ void handleModerateMessage(
|
||||
const lib::payload::channel_moderate::v2::Event &event,
|
||||
const lib::payload::channel_moderate::v2::Clear &action);
|
||||
|
||||
void handleModerateMessage(
|
||||
TwitchChannel *chan, const QDateTime &time,
|
||||
const lib::payload::channel_moderate::v2::Event &event,
|
||||
const lib::payload::channel_moderate::v2::Timeout &action);
|
||||
|
||||
} // namespace chatterino::eventsub
|
||||
|
||||
@@ -52,6 +52,11 @@ void addOrReplaceChannelTimeout(const Buf &buffer, MessagePtr message,
|
||||
break;
|
||||
}
|
||||
|
||||
if (s->flags.has(MessageFlag::EventSub))
|
||||
{
|
||||
continue; // TODO: implement stacking for eventsub
|
||||
}
|
||||
|
||||
if (timeoutStackStyle == TimeoutStackStyle::DontStackBeyondUserMessage)
|
||||
{
|
||||
if (s->loginName == message->timeoutUser &&
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
{
|
||||
"input": {
|
||||
"__timestamp": "2025-02-22T17:54:04.523432776Z",
|
||||
"action": "shared_chat_timeout",
|
||||
"automod_terms": null,
|
||||
"ban": null,
|
||||
"broadcaster_user_id": "11148817",
|
||||
"broadcaster_user_login": "pajlada",
|
||||
"broadcaster_user_name": "pajlada",
|
||||
"delete": null,
|
||||
"followers": null,
|
||||
"mod": null,
|
||||
"moderator_user_id": "129546453",
|
||||
"moderator_user_login": "nerixyz",
|
||||
"moderator_user_name": "nerixyz",
|
||||
"raid": null,
|
||||
"shared_chat_ban": null,
|
||||
"shared_chat_delete": null,
|
||||
"shared_chat_timeout": {
|
||||
"expires_at": "2025-02-22T18:04:04.502931622Z",
|
||||
"reason": "",
|
||||
"user_id": "141981764",
|
||||
"user_login": "twitchdev",
|
||||
"user_name": "TwitchDev"
|
||||
},
|
||||
"shared_chat_unban": null,
|
||||
"shared_chat_untimeout": null,
|
||||
"slow": null,
|
||||
"source_broadcaster_user_id": "117166826",
|
||||
"source_broadcaster_user_login": "testaccount_420",
|
||||
"source_broadcaster_user_name": "테스트계정420",
|
||||
"timeout": null,
|
||||
"unban": null,
|
||||
"unban_request": null,
|
||||
"unmod": null,
|
||||
"unraid": null,
|
||||
"untimeout": null,
|
||||
"unvip": null,
|
||||
"vip": null,
|
||||
"warn": null
|
||||
},
|
||||
"output": [
|
||||
{
|
||||
"badgeInfos": {
|
||||
},
|
||||
"badges": [
|
||||
],
|
||||
"channelName": "",
|
||||
"count": 1,
|
||||
"displayName": "",
|
||||
"elements": [
|
||||
{
|
||||
"element": {
|
||||
"color": "System",
|
||||
"flags": "Timestamp",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"17:54"
|
||||
]
|
||||
},
|
||||
"flags": "Timestamp",
|
||||
"format": "",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"time": "17:54:04",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TimestampElement"
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "nerixyz",
|
||||
"words": [
|
||||
"nerixyz"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"timed",
|
||||
"out"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "twitchdev",
|
||||
"words": [
|
||||
"TwitchDev"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"for"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"10m"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"in"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": false,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "testaccount_420",
|
||||
"words": [
|
||||
"테스트계정420"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"."
|
||||
]
|
||||
}
|
||||
],
|
||||
"flags": "System|Timeout|EventSub",
|
||||
"id": "",
|
||||
"localizedName": "",
|
||||
"loginName": "nerixyz",
|
||||
"messageText": "nerixyz timed out twitchdev for 10m in testaccount_420. ",
|
||||
"searchText": "nerixyz timed out twitchdev for 10m in testaccount_420. ",
|
||||
"serverReceivedTime": "2025-02-22T17:54:04Z",
|
||||
"timeoutUser": "twitchdev",
|
||||
"userID": "",
|
||||
"usernameColor": "#ff000000"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
{
|
||||
"input": {
|
||||
"__timestamp": "2025-02-22T17:53:49.800959069Z",
|
||||
"action": "timeout",
|
||||
"automod_terms": null,
|
||||
"ban": null,
|
||||
"broadcaster_user_id": "11148817",
|
||||
"broadcaster_user_login": "pajlada",
|
||||
"broadcaster_user_name": "pajlada",
|
||||
"delete": null,
|
||||
"followers": null,
|
||||
"mod": null,
|
||||
"moderator_user_id": "129546453",
|
||||
"moderator_user_login": "nerixyz",
|
||||
"moderator_user_name": "nerixyz",
|
||||
"raid": null,
|
||||
"shared_chat_ban": null,
|
||||
"shared_chat_delete": null,
|
||||
"shared_chat_timeout": null,
|
||||
"shared_chat_unban": null,
|
||||
"shared_chat_untimeout": null,
|
||||
"slow": null,
|
||||
"source_broadcaster_user_id": null,
|
||||
"source_broadcaster_user_login": null,
|
||||
"source_broadcaster_user_name": null,
|
||||
"timeout": {
|
||||
"expires_at": "2025-02-22T17:53:50.782129948Z",
|
||||
"reason": "test",
|
||||
"user_id": "141981764",
|
||||
"user_login": "twitchdev",
|
||||
"user_name": "TwitchDev"
|
||||
},
|
||||
"unban": null,
|
||||
"unban_request": null,
|
||||
"unmod": null,
|
||||
"unraid": null,
|
||||
"untimeout": null,
|
||||
"unvip": null,
|
||||
"vip": null,
|
||||
"warn": null
|
||||
},
|
||||
"output": [
|
||||
{
|
||||
"badgeInfos": {
|
||||
},
|
||||
"badges": [
|
||||
],
|
||||
"channelName": "",
|
||||
"count": 1,
|
||||
"displayName": "",
|
||||
"elements": [
|
||||
{
|
||||
"element": {
|
||||
"color": "System",
|
||||
"flags": "Timestamp",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"17:53"
|
||||
]
|
||||
},
|
||||
"flags": "Timestamp",
|
||||
"format": "",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"time": "17:53:49",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TimestampElement"
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "nerixyz",
|
||||
"words": [
|
||||
"nerixyz"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"timed",
|
||||
"out"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "twitchdev",
|
||||
"words": [
|
||||
"TwitchDev"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"for"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": false,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"1s"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
":"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"test"
|
||||
]
|
||||
}
|
||||
],
|
||||
"flags": "System|Timeout|EventSub",
|
||||
"id": "",
|
||||
"localizedName": "",
|
||||
"loginName": "nerixyz",
|
||||
"messageText": "nerixyz timed out twitchdev for 1s : test ",
|
||||
"searchText": "nerixyz timed out twitchdev for 1s : test ",
|
||||
"serverReceivedTime": "2025-02-22T17:53:49Z",
|
||||
"timeoutUser": "twitchdev",
|
||||
"userID": "",
|
||||
"usernameColor": "#ff000000"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -96,17 +96,25 @@ std::shared_ptr<TwitchChannel> makeMockTwitchChannel(const QString &name)
|
||||
}
|
||||
|
||||
boost::beast::flat_buffer makePayload(std::string_view subJson,
|
||||
const QJsonObject &event)
|
||||
QJsonObject event)
|
||||
{
|
||||
auto subscription =
|
||||
QJsonDocument::fromJson(
|
||||
QByteArray::fromRawData(subJson.data(),
|
||||
static_cast<qsizetype>(subJson.size())))
|
||||
.object();
|
||||
|
||||
QString timestamp = "2024-05-14T12:31:47.995298776Z";
|
||||
if (event.contains("__timestamp"))
|
||||
{
|
||||
timestamp = event["__timestamp"].toString();
|
||||
event.remove("__timestamp");
|
||||
}
|
||||
|
||||
QJsonObject metadata{
|
||||
{"message_id", "e8edc592-5550-4aa5-bba6-39e31a2be435"},
|
||||
{"message_type", "notification"},
|
||||
{"message_timestamp", "2024-05-14T12:31:47.995298776Z"},
|
||||
{"message_timestamp", timestamp},
|
||||
{"subscription_type", subscription["type"]},
|
||||
{"subscription_version", subscription["version"]},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user