feat: add /endpoll and /cancelpoll commands for broadcasters (#6605)
Reviewed-by: pajlada <rasmus.karlsson@pajlada.com>
This commit is contained in:
@@ -484,6 +484,9 @@ CommandController::CommandController(const Paths &paths)
|
||||
this->registerCommand("/shoutout", &commands::sendShoutout);
|
||||
|
||||
this->registerCommand("/poll", &commands::createPoll);
|
||||
this->registerCommand("/cancelpoll", &commands::cancelPoll);
|
||||
this->registerCommand("/endpoll", &commands::endPoll);
|
||||
|
||||
this->registerCommand("/prediction", &commands::createPrediction);
|
||||
|
||||
this->registerCommand("/c2-set-logging-rules", &commands::setLoggingRules);
|
||||
|
||||
@@ -67,4 +67,164 @@ QString createPoll(const CommandContext &ctx)
|
||||
return "";
|
||||
}
|
||||
|
||||
QString endPoll(const CommandContext &ctx)
|
||||
{
|
||||
if (ctx.twitchChannel == nullptr)
|
||||
{
|
||||
const auto err = QStringLiteral(
|
||||
"The /endpoll 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 end a poll!");
|
||||
return "";
|
||||
}
|
||||
|
||||
const auto roomId = ctx.twitchChannel->roomId();
|
||||
getHelix()->getPolls(
|
||||
roomId, {}, 1, {},
|
||||
[channel = ctx.channel, roomId](const auto &result) {
|
||||
if (result.polls.empty())
|
||||
{
|
||||
channel->addSystemMessage("Failed to find any polls");
|
||||
return;
|
||||
}
|
||||
|
||||
auto poll = result.polls.front();
|
||||
if (poll.status != "ACTIVE")
|
||||
{
|
||||
channel->addSystemMessage("Could not find an active poll");
|
||||
return;
|
||||
}
|
||||
|
||||
getHelix()->endPoll(
|
||||
roomId, poll.id, false,
|
||||
[channel](const HelixPoll &data) {
|
||||
// find most popular choice
|
||||
HelixPollChoice winner = data.choices.front();
|
||||
int totalVotes = 0;
|
||||
int winnerCount = 0;
|
||||
for (const auto &choice : data.choices)
|
||||
{
|
||||
totalVotes += choice.votes;
|
||||
if (choice.votes > winner.votes)
|
||||
{
|
||||
winner = choice;
|
||||
winnerCount = 1;
|
||||
}
|
||||
else if (choice.votes == winner.votes)
|
||||
{
|
||||
winnerCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (totalVotes == 0)
|
||||
{
|
||||
channel->addSystemMessage(
|
||||
QString("Poll ended with zero votes: '%1'")
|
||||
.arg(data.title));
|
||||
return;
|
||||
}
|
||||
|
||||
if (winnerCount > 1)
|
||||
{
|
||||
channel->addSystemMessage(
|
||||
QString("Poll ended in a draw: '%1'")
|
||||
.arg(data.title));
|
||||
return;
|
||||
}
|
||||
|
||||
const double percent =
|
||||
100.0 * winner.votes / std::max(totalVotes, 1);
|
||||
|
||||
channel->addSystemMessage(
|
||||
QString(
|
||||
"Ended poll: '%1' - '%2' won with %3 votes (%4%)")
|
||||
.arg(data.title, winner.title,
|
||||
QString::number(winner.votes),
|
||||
QString::number(percent, 'f', 1)));
|
||||
},
|
||||
[channel](const auto &error) {
|
||||
channel->addSystemMessage("Failed to end the poll - " +
|
||||
error);
|
||||
});
|
||||
},
|
||||
[channel = ctx.channel](const auto &error) {
|
||||
channel->addSystemMessage("Failed to query polls - " + error);
|
||||
});
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
QString cancelPoll(const CommandContext &ctx)
|
||||
{
|
||||
if (ctx.twitchChannel == nullptr)
|
||||
{
|
||||
const auto err = QStringLiteral(
|
||||
"The /cancelpoll 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 poll!");
|
||||
return "";
|
||||
}
|
||||
|
||||
const auto roomId = ctx.twitchChannel->roomId();
|
||||
getHelix()->getPolls(
|
||||
roomId, {}, 1, {},
|
||||
[channel = ctx.channel, roomId](const auto &result) {
|
||||
if (result.polls.empty())
|
||||
{
|
||||
channel->addSystemMessage("Failed to find any polls");
|
||||
return;
|
||||
}
|
||||
|
||||
auto poll = result.polls.front();
|
||||
if (poll.status != "ACTIVE")
|
||||
{
|
||||
channel->addSystemMessage("Could not find an active poll");
|
||||
return;
|
||||
}
|
||||
|
||||
getHelix()->endPoll(
|
||||
roomId, poll.id, true,
|
||||
[channel](const HelixPoll &data) {
|
||||
channel->addSystemMessage(
|
||||
QString("Canceled poll: '%1'").arg(data.title));
|
||||
},
|
||||
[channel](const auto &error) {
|
||||
channel->addSystemMessage("Failed to cancel the poll - " +
|
||||
error);
|
||||
});
|
||||
},
|
||||
[channel = ctx.channel](const auto &error) {
|
||||
channel->addSystemMessage("Failed to query polls - " + error);
|
||||
});
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
} // namespace chatterino::commands
|
||||
|
||||
@@ -13,4 +13,10 @@ namespace chatterino::commands {
|
||||
/// /poll
|
||||
QString createPoll(const CommandContext &ctx);
|
||||
|
||||
/// /endpoll
|
||||
QString endPoll(const CommandContext &ctx);
|
||||
|
||||
/// /cancelpoll
|
||||
QString cancelPoll(const CommandContext &ctx);
|
||||
|
||||
} // namespace chatterino::commands
|
||||
|
||||
Reference in New Issue
Block a user