feat: add poll and prediction commands for broadcasters (#6583)

Reviewed-by: nerix <nero.9@hotmail.de>
Reviewed-by: pajlada <rasmus.karlsson@pajlada.com>
This commit is contained in:
iProdigy
2025-11-23 09:55:39 -06:00
committed by GitHub
parent b63739e792
commit 118e1781dd
12 changed files with 432 additions and 0 deletions
+111
View File
@@ -3218,6 +3218,117 @@ void Helix::getFollowedChannel(
.execute();
}
void Helix::createPoll(QString broadcasterID, QString title,
QStringList choices, const std::chrono::seconds duration,
const int pointsPerVote,
ResultCallback<> successCallback,
FailureCallback<QString> failureCallback)
{
// Prepare request body
QJsonArray choiceArray;
for (auto choice : choices)
{
choiceArray.append(QJsonObject{{{"title", choice}}});
}
QJsonObject json{{{"broadcaster_id", broadcasterID},
{"title", title},
{"duration", static_cast<int>(duration.count())},
{"choices", choiceArray}}};
if (pointsPerVote > 0)
{
json["channel_points_voting_enabled"] = true;
json["channel_points_per_vote"] = static_cast<qint64>(pointsPerVote);
}
// Execute API call
this->makePost("polls", {})
.json(json)
.onSuccess([successCallback](const NetworkResult &result) {
if (result.status() != 200)
{
qCWarning(chatterinoTwitch)
<< "Success result for creating a poll was "
<< result.formatError() << "but we expected it to be 200";
}
successCallback();
})
.onError([failureCallback](const NetworkResult &result) -> void {
if (!result.status())
{
failureCallback(result.formatError());
return;
}
const auto obj = result.parseJson();
const auto message = obj.value("message").toString();
if (!message.isEmpty())
{
failureCallback(message);
}
else
{
failureCallback(result.formatError());
}
})
.execute();
}
void Helix::createPrediction(const QString broadcasterID, const QString title,
QStringList outcomes,
const std::chrono::seconds duration,
ResultCallback<> successCallback,
FailureCallback<QString> failureCallback)
{
// Prepare request body
QJsonArray outcomeArray;
for (auto outcome : outcomes)
{
outcomeArray.append(QJsonObject{{{"title", outcome}}});
}
QJsonObject payload;
payload.insert("broadcaster_id", broadcasterID);
payload.insert("title", title);
payload.insert("prediction_window", static_cast<int>(duration.count()));
payload.insert("outcomes", outcomeArray);
// Execute API call
this->makePost("predictions", {})
.json(payload)
.onSuccess([successCallback](const NetworkResult &result) {
if (result.status() != 200)
{
qCWarning(chatterinoTwitch)
<< "Success result for creating a prediction was "
<< result.formatError() << "but we expected it to be 200";
}
successCallback();
})
.onError([failureCallback](const NetworkResult &result) -> void {
if (!result.status())
{
failureCallback(result.formatError());
return;
}
const auto obj = result.parseJson();
const auto message = obj.value("message").toString();
if (!message.isEmpty())
{
failureCallback(message);
}
else
{
failureCallback(result.formatError());
}
})
.execute();
}
void Helix::createEventSubSubscription(
const eventsub::SubscriptionRequest &request, const QString &sessionID,
ResultCallback<HelixCreateEventSubSubscriptionResponse> successCallback,
+26
View File
@@ -16,6 +16,7 @@
#include <QUrl>
#include <QUrlQuery>
#include <chrono>
#include <functional>
#include <optional>
#include <unordered_set>
@@ -1211,6 +1212,19 @@ public:
ResultCallback<std::optional<HelixFollowedChannel>> successCallback,
FailureCallback<QString> failureCallback) = 0;
/// https://dev.twitch.tv/docs/api/reference#create-poll
virtual void createPoll(QString broadcasterID, QString title,
QStringList choices, std::chrono::seconds duration,
int pointsPerVote, ResultCallback<> successCallback,
FailureCallback<QString> failureCallback) = 0;
/// https://dev.twitch.tv/docs/api/reference#create-prediction
virtual void createPrediction(QString broadcasterID, QString title,
QStringList choices,
std::chrono::seconds duration,
ResultCallback<> successCallback,
FailureCallback<QString> failureCallback) = 0;
// https://dev.twitch.tv/docs/api/reference/#create-eventsub-subscription
virtual void createEventSubSubscription(
const eventsub::SubscriptionRequest &request, const QString &sessionID,
@@ -1566,6 +1580,18 @@ public:
ResultCallback<std::optional<HelixFollowedChannel>> successCallback,
FailureCallback<QString> failureCallback) final;
/// https://dev.twitch.tv/docs/api/reference#create-poll
void createPoll(QString broadcasterID, QString title, QStringList choices,
std::chrono::seconds duration, int pointsPerVote,
ResultCallback<> successCallback,
FailureCallback<QString> failureCallback) final;
/// https://dev.twitch.tv/docs/api/reference#create-prediction
void createPrediction(QString broadcasterID, QString title,
QStringList outcomes, std::chrono::seconds duration,
ResultCallback<> successCallback,
FailureCallback<QString> failureCallback) final;
// https://dev.twitch.tv/docs/api/reference/#create-eventsub-subscription
void createEventSubSubscription(
const eventsub::SubscriptionRequest &request, const QString &sessionID,