Add /setgame and /settitle (#2534)

Co-authored-by: pajlada <rasmus.karlsson@pajlada.com>
This commit is contained in:
Mm2PL 2021-04-04 15:31:08 +00:00 committed by GitHub
parent dff2629e81
commit f9246a9e3a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 151 additions and 0 deletions

View file

@ -5,6 +5,7 @@
- Major: Added clip creation support. You can create clips with `/clip` command, `Alt+X` keybind or `Create a clip` option in split header's context menu. This requires a new authentication scope so re-authentication will be required to use it. (#2271, #2377, #2528) - Major: Added clip creation support. You can create clips with `/clip` command, `Alt+X` keybind or `Create a clip` option in split header's context menu. This requires a new authentication scope so re-authentication will be required to use it. (#2271, #2377, #2528)
- Major: Added "Channel Filters". See https://wiki.chatterino.com/Filters/ for how they work or how to configure them. (#1748, #2083, #2090, #2200, #2225) - Major: Added "Channel Filters". See https://wiki.chatterino.com/Filters/ for how they work or how to configure them. (#1748, #2083, #2090, #2200, #2225)
- Major: Added Streamer Mode configuration (under `Settings -> General`), where you can select which features of Chatterino should behave differently when you are in Streamer Mode. (#2001, #2316, #2342, #2376) - Major: Added Streamer Mode configuration (under `Settings -> General`), where you can select which features of Chatterino should behave differently when you are in Streamer Mode. (#2001, #2316, #2342, #2376)
- Major: Add `/settitle` and `/setgame` commands, originally made for Mm2PL/Dankerino. (#2534)
- Major: Color mentions to match the mentioned users. You can disable this by unchecking "Color @usernames" under `Settings -> General -> Advanced (misc.)`. (#1963, #2284) - Major: Color mentions to match the mentioned users. You can disable this by unchecking "Color @usernames" under `Settings -> General -> Advanced (misc.)`. (#1963, #2284)
- Major: Commands `/ignore` and `/unignore` have been renamed to `/block` and `/unblock` in order to keep consistency with Twitch's terms. (#2370) - Major: Commands `/ignore` and `/unignore` have been renamed to `/block` and `/unblock` in order to keep consistency with Twitch's terms. (#2370)
- Major: Added support for bit emotes - the ones you unlock after cheering to streamer. (#2550) - Major: Added support for bit emotes - the ones you unlock after cheering to streamer. (#2550)

View file

@ -19,6 +19,7 @@ enum class NetworkRequestType {
Post, Post,
Put, Put,
Delete, Delete,
Patch,
}; };
} // namespace chatterino } // namespace chatterino

View file

@ -116,6 +116,19 @@ void loadUncached(const std::shared_ptr<NetworkData> &data)
return NetworkManager::accessManager.post( return NetworkManager::accessManager.post(
data->request_, data->payload_); data->request_, data->payload_);
} }
case NetworkRequestType::Patch:
if (data->multiPartPayload_)
{
assert(data->payload_.isNull());
return NetworkManager::accessManager.sendCustomRequest(
data->request_, "PATCH", data->multiPartPayload_);
}
else
{
return NetworkManager::accessManager.sendCustomRequest(
data->request_, "PATCH", data->payload_);
}
} }
return nullptr; return nullptr;
}(); }();

View file

@ -643,7 +643,85 @@ void CommandController::initialize(Settings &, Paths &paths)
getApp()->windows->getMainWindow().getNotebook().getSelectedPage()); getApp()->windows->getMainWindow().getNotebook().getSelectedPage());
currentPage->getSelectedSplit()->getChannelView().clearMessages(); currentPage->getSelectedSplit()->getChannelView().clearMessages();
return "";
});
this->registerCommand("/settitle", [](const QStringList &words,
ChannelPtr channel) {
if (words.size() < 2)
{
channel->addMessage(
makeSystemMessage("Usage: /settitle <stream title>."));
return "";
}
if (auto twitchChannel = dynamic_cast<TwitchChannel *>(channel.get()))
{
auto status = twitchChannel->accessStreamStatus();
auto title = words.mid(1).join(" ");
getHelix()->updateChannel(
twitchChannel->roomId(), "", "", title,
[channel, title](NetworkResult) {
channel->addMessage(makeSystemMessage(
QString("Updated title to %1").arg(title)));
},
[channel] {
channel->addMessage(
makeSystemMessage("Title update failed! Are you "
"missing the required scope?"));
});
}
else
{
channel->addMessage(makeSystemMessage(
"Unable to set title of non-Twitch channel."));
}
return "";
});
this->registerCommand("/setgame", [](const QStringList &words,
ChannelPtr channel) {
if (words.size() < 2)
{
channel->addMessage(
makeSystemMessage("Usage: /setgame <stream game>."));
return "";
}
if (auto twitchChannel = dynamic_cast<TwitchChannel *>(channel.get()))
{
getHelix()->fetchGames(
QStringList(), {words.mid(1).join(" ")},
[channel, twitchChannel](std::vector<HelixGame> games) {
if (games.size() == 0)
{
channel->addMessage(
makeSystemMessage("Game not found."));
}
else // 0 or 1 games
{
auto status = twitchChannel->accessStreamStatus();
getHelix()->updateChannel(
twitchChannel->roomId(), games.at(0).id, "", "",
[channel, games](NetworkResult) {
channel->addMessage(makeSystemMessage(
QString("Updated game to %1")
.arg(games.at(0).name)));
},
[channel] {
channel->addMessage(makeSystemMessage(
"Game update failed! Are you "
"missing the required scope?"));
});
}
},
[channel] {
channel->addMessage(
makeSystemMessage("Failed to look up game."));
});
}
else
{
channel->addMessage(
makeSystemMessage("Unable to set game of non-Twitch channel."));
}
return ""; return "";
}); });
} }

View file

@ -578,6 +578,48 @@ void Helix::unblockUser(QString targetUserId,
.execute(); .execute();
} }
void Helix::updateChannel(QString broadcasterId, QString gameId,
QString language, QString title,
std::function<void(NetworkResult)> successCallback,
HelixFailureCallback failureCallback)
{
QUrlQuery urlQuery;
auto data = QJsonDocument();
auto obj = QJsonObject();
if (!gameId.isEmpty())
{
obj.insert("game_id", gameId);
}
if (!language.isEmpty())
{
obj.insert("broadcaster_language", language);
}
if (!title.isEmpty())
{
obj.insert("title", title);
}
if (title.isEmpty() && gameId.isEmpty() && language.isEmpty())
{
qCDebug(chatterinoCommon) << "Tried to update channel with no changes!";
return;
}
data.setObject(obj);
urlQuery.addQueryItem("broadcaster_id", broadcasterId);
this->makeRequest("channels", urlQuery)
.type(NetworkRequestType::Patch)
.header("Content-Type", "application/json")
.payload(data.toJson())
.onSuccess([successCallback, failureCallback](auto result) -> Outcome {
successCallback(result);
return Success;
})
.onError([failureCallback](NetworkResult result) {
failureCallback();
})
.execute();
}
NetworkRequest Helix::makeRequest(QString url, QUrlQuery urlQuery) NetworkRequest Helix::makeRequest(QString url, QUrlQuery urlQuery)
{ {
assert(!url.startsWith("/")); assert(!url.startsWith("/"));

View file

@ -296,6 +296,12 @@ public:
std::function<void()> successCallback, std::function<void()> successCallback,
HelixFailureCallback failureCallback); HelixFailureCallback failureCallback);
// https://dev.twitch.tv/docs/api/reference#modify-channel-information
void updateChannel(QString broadcasterId, QString gameId, QString language,
QString title,
std::function<void(NetworkResult)> successCallback,
HelixFailureCallback failureCallback);
void update(QString clientId, QString oauthToken); void update(QString clientId, QString oauthToken);
static void initialize(); static void initialize();

View file

@ -104,6 +104,16 @@ URL: https://dev.twitch.tv/docs/api/reference#get-channel-information
Used in: Used in:
- `TwitchChannel` to refresh stream title - `TwitchChannel` to refresh stream title
### Update Channel
URL: https://dev.twitch.tv/docs/api/reference#modify-channel-information
Requires `channel:manage:broadcast` scope
- We implement this in `providers/twitch/api/Helix.cpp updateChannel`
Used in:
- `/setgame` to update the game in the current channel
- `/settitle` to update the title in the current channel
### Create Stream Marker ### Create Stream Marker
URL: https://dev.twitch.tv/docs/api/reference/#create-stream-marker URL: https://dev.twitch.tv/docs/api/reference/#create-stream-marker