Migrate /commercial command to the Helix API (#4094)

Co-authored-by: pajlada <rasmus.karlsson@pajlada.com>
This commit is contained in:
xel86
2022-11-05 05:43:31 -04:00
committed by GitHub
parent f0ad606d7a
commit f00f766eeb
7 changed files with 302 additions and 0 deletions
+92
View File
@@ -2199,6 +2199,98 @@ void Helix::getChannelVIPs(
.execute();
}
void Helix::startCommercial(
QString broadcasterID, int length,
ResultCallback<HelixStartCommercialResponse> successCallback,
FailureCallback<HelixStartCommercialError, QString> failureCallback)
{
using Error = HelixStartCommercialError;
QJsonObject payload;
payload.insert("broadcaster_id", QJsonValue(broadcasterID));
payload.insert("length", QJsonValue(length));
this->makeRequest("channels/commercial", QUrlQuery())
.type(NetworkRequestType::Post)
.header("Content-Type", "application/json")
.payload(QJsonDocument(payload).toJson(QJsonDocument::Compact))
.onSuccess([successCallback, failureCallback](auto result) -> Outcome {
auto obj = result.parseJson();
if (obj.isEmpty())
{
failureCallback(
Error::Unknown,
"Twitch didn't send any information about this error.");
return Failure;
}
successCallback(HelixStartCommercialResponse(obj));
return Success;
})
.onError([failureCallback](auto result) {
auto obj = result.parseJson();
auto message = obj.value("message").toString();
switch (result.status())
{
case 400: {
if (message.startsWith("Missing scope",
Qt::CaseInsensitive))
{
failureCallback(Error::UserMissingScope, message);
}
else if (message.contains(
"To start a commercial, the broadcaster must "
"be streaming live.",
Qt::CaseInsensitive))
{
failureCallback(Error::BroadcasterNotStreaming,
message);
}
else
{
failureCallback(Error::Forwarded, message);
}
}
break;
case 401: {
if (message.contains(
"The ID in broadcaster_id must match the user ID "
"found in the request's OAuth token.",
Qt::CaseInsensitive))
{
failureCallback(Error::TokenMustMatchBroadcaster,
message);
}
else
{
failureCallback(Error::Forwarded, message);
}
}
break;
case 429: {
// The cooldown period is implied to be included
// in the error's "retry_after" response field but isn't.
// If this becomes available we should append that to the error message.
failureCallback(Error::Ratelimited, message);
}
break;
default: {
qCDebug(chatterinoTwitch)
<< "Unhandled error starting commercial:"
<< result.status() << result.getData() << obj;
failureCallback(Error::Unknown, message);
}
break;
}
})
.execute();
}
NetworkRequest Helix::makeRequest(QString url, QUrlQuery urlQuery)
{
assert(!url.startsWith("/"));
+42
View File
@@ -564,6 +564,34 @@ enum class HelixListVIPsError { // /vips
Forwarded,
}; // /vips
struct HelixStartCommercialResponse {
// Length of the triggered commercial
int length;
// Provides contextual information on why the request failed
QString message;
// Seconds until the next commercial can be served on this channel
int retryAfter;
explicit HelixStartCommercialResponse(const QJsonObject &jsonObject)
{
auto jsonData = jsonObject.value("data").toArray().at(0).toObject();
this->length = jsonData.value("length").toInt();
this->message = jsonData.value("message").toString();
this->retryAfter = jsonData.value("retry_after").toInt();
}
};
enum class HelixStartCommercialError {
Unknown,
TokenMustMatchBroadcaster,
UserMissingScope,
BroadcasterNotStreaming,
Ratelimited,
// The error message is forwarded directly from the Twitch API
Forwarded,
};
class IHelix
{
public:
@@ -832,6 +860,13 @@ public:
ResultCallback<std::vector<HelixVip>> successCallback,
FailureCallback<HelixListVIPsError, QString> failureCallback) = 0;
// https://dev.twitch.tv/docs/api/reference#start-commercial
virtual void startCommercial(
QString broadcasterID, int length,
ResultCallback<HelixStartCommercialResponse> successCallback,
FailureCallback<HelixStartCommercialError, QString>
failureCallback) = 0;
virtual void update(QString clientId, QString oauthToken) = 0;
protected:
@@ -1101,6 +1136,13 @@ public:
ResultCallback<std::vector<HelixVip>> successCallback,
FailureCallback<HelixListVIPsError, QString> failureCallback) final;
// https://dev.twitch.tv/docs/api/reference#start-commercial
void startCommercial(
QString broadcasterID, int length,
ResultCallback<HelixStartCommercialResponse> successCallback,
FailureCallback<HelixStartCommercialError, QString> failureCallback)
final;
void update(QString clientId, QString oauthToken) final;
static void initialize();