feat: add /lockprediction and /cancelprediction commands for broadcasters (#6612)
Reviewed-by: pajlada <rasmus.karlsson@pajlada.com>
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user