feat: add /lockprediction and /cancelprediction commands for broadcasters (#6612)

Reviewed-by: pajlada <rasmus.karlsson@pajlada.com>
This commit is contained in:
iProdigy
2025-12-07 04:04:36 -06:00
committed by GitHub
parent bd026b3551
commit 40483efbf8
8 changed files with 374 additions and 5 deletions
@@ -488,6 +488,8 @@ CommandController::CommandController(const Paths &paths)
this->registerCommand("/endpoll", &commands::endPoll);
this->registerCommand("/prediction", &commands::createPrediction);
this->registerCommand("/lockprediction", &commands::lockPrediction);
this->registerCommand("/cancelprediction", &commands::cancelPrediction);
this->registerCommand("/c2-set-logging-rules", &commands::setLoggingRules);
this->registerCommand("/c2-theme-autoreload", &commands::toggleThemeReload);
@@ -8,6 +8,7 @@
#include "providers/twitch/api/Helix.hpp"
#include "providers/twitch/TwitchAccount.hpp"
#include "providers/twitch/TwitchChannel.hpp"
#include "util/Helpers.hpp"
#include <chrono>
@@ -66,4 +67,155 @@ QString createPrediction(const CommandContext &ctx)
return "";
}
QString lockPrediction(const CommandContext &ctx)
{
if (ctx.twitchChannel == nullptr)
{
const auto err = QStringLiteral(
"The /lockprediction command only works in Twitch channels");
if (ctx.channel != nullptr)
{
ctx.channel->addSystemMessage(err);
}
else
{
qCWarning(chatterinoCommands) << "Invalid command context:" << err;
}
return "";
}
auto currentUser = getApp()->getAccounts()->twitch.getCurrent();
if (currentUser->isAnon())
{
ctx.channel->addSystemMessage(
"You must be logged in to lock a prediction!");
return "";
}
const auto roomId = ctx.twitchChannel->roomId();
getHelix()->getPredictions(
roomId, {}, 1, {},
[channel = ctx.channel, roomId](const auto &result) {
if (result.predictions.empty())
{
channel->addSystemMessage("Failed to find any predictions");
return;
}
auto prediction = result.predictions.front();
if (prediction.status == "LOCKED")
{
channel->addSystemMessage(
"The current prediction is already locked: " +
prediction.title);
return;
}
if (prediction.status != "ACTIVE")
{
channel->addSystemMessage(
"Could not find an active prediction");
return;
}
getHelix()->endPrediction(
roomId, prediction.id, false, {},
[channel](const HelixPrediction &data) {
int totalPoints = 0;
int numUsers = 0;
for (const auto &outcome : data.outcomes)
{
totalPoints += outcome.channelPoints;
numUsers += outcome.users;
}
channel->addSystemMessage(
QString("Locked prediction with %1 points wagered by "
"%2 users: '%3'")
.arg(localizeNumbers(totalPoints),
localizeNumbers(numUsers), data.title));
},
[channel](const auto &error) {
channel->addSystemMessage("Failed to lock prediction - " +
error);
});
},
[channel = ctx.channel](const auto &error) {
channel->addSystemMessage("Failed to query predictions - " + error);
});
return "";
}
QString cancelPrediction(const CommandContext &ctx)
{
if (ctx.twitchChannel == nullptr)
{
const auto err = QStringLiteral(
"The /cancelprediction command only works in Twitch channels");
if (ctx.channel != nullptr)
{
ctx.channel->addSystemMessage(err);
}
else
{
qCWarning(chatterinoCommands) << "Invalid command context:" << err;
}
return "";
}
auto currentUser = getApp()->getAccounts()->twitch.getCurrent();
if (currentUser->isAnon())
{
ctx.channel->addSystemMessage(
"You must be logged in to cancel a prediction!");
return "";
}
const auto roomId = ctx.twitchChannel->roomId();
getHelix()->getPredictions(
roomId, {}, 1, {},
[channel = ctx.channel, roomId](const auto &result) {
if (result.predictions.empty())
{
channel->addSystemMessage("Failed to find any predictions");
return;
}
auto prediction = result.predictions.front();
if (prediction.status != "ACTIVE" && prediction.status != "LOCKED")
{
channel->addSystemMessage("Could not find an open prediction");
return;
}
getHelix()->endPrediction(
roomId, prediction.id, true, {},
[channel](const HelixPrediction &data) {
int totalPoints = 0;
int numUsers = 0;
for (const auto &outcome : data.outcomes)
{
totalPoints += outcome.channelPoints;
numUsers += outcome.users;
}
channel->addSystemMessage(
QString("Refunded %1 points to %2 users for "
"prediction: '%3'")
.arg(localizeNumbers(totalPoints),
localizeNumbers(numUsers), data.title));
},
[channel](const auto &error) {
channel->addSystemMessage("Failed to cancel prediction - " +
error);
});
},
[channel = ctx.channel](const auto &error) {
channel->addSystemMessage("Failed to query predictions - " + error);
});
return "";
}
} // namespace chatterino::commands
@@ -13,4 +13,10 @@ namespace chatterino::commands {
/// /prediction
QString createPrediction(const CommandContext &ctx);
/// /lockprediction
QString lockPrediction(const CommandContext &ctx);
/// /cancelprediction
QString cancelPrediction(const CommandContext &ctx);
} // namespace chatterino::commands