Skip to content

Commit

Permalink
Migrated follow and unfollow methods to Helix API (#2306)
Browse files Browse the repository at this point in the history
  • Loading branch information
zneix authored Dec 22, 2020
1 parent 89c74e0 commit 2f5df3d
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 87 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
- Bugfix: Fix a crash bug that occurred when moving splits across windows and closing the "parent tab" (#2249, #2259)
- Dev: Updated minimum required Qt framework version to 5.12. (#2210)
- Dev: Migrated `Kraken::getUser` to Helix (#2260)
- Dev: Migrated `TwitchAccount::(un)followUser` from Kraken to Helix and moved it to `Helix::(un)followUser`. (#2306)

## 2.2.2

Expand Down
58 changes: 37 additions & 21 deletions src/controllers/commands/CommandController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,29 +313,39 @@ void CommandController::initialize(Settings &, Paths &paths)
channel->addMessage(makeSystemMessage("Usage: /follow [user]"));
return "";
}
auto app = getApp();

auto user = app->accounts->twitch.getCurrent();
auto target = words.at(1);
auto currentUser = getApp()->accounts->twitch.getCurrent();

if (user->isAnon())
if (currentUser->isAnon())
{
channel->addMessage(
makeSystemMessage("You must be logged in to follow someone"));
return "";
}

auto target = words.at(1);

getHelix()->getUserByName(
target,
[user, channel, target](const auto &targetUser) {
user->followUser(targetUser.id, [channel, target]() {
channel->addMessage(makeSystemMessage(
"You successfully followed " + target));
});
[currentUser, channel, target](const auto &targetUser) {
getHelix()->followUser(
currentUser->getUserId(), targetUser.id,
[channel, target]() {
channel->addMessage(makeSystemMessage(
"You successfully followed " + target));
},
[channel, target]() {
channel->addMessage(makeSystemMessage(
QString("User %1 could not be followed, an unknown "
"error occured!")
.arg(target)));
});
},
[channel, target] {
channel->addMessage(makeSystemMessage(
"User " + target + " could not be followed!"));
channel->addMessage(
makeSystemMessage(QString("User %1 could not be followed, "
"no user with that name found!")
.arg(target)));
});

return "";
Expand All @@ -347,29 +357,35 @@ void CommandController::initialize(Settings &, Paths &paths)
channel->addMessage(makeSystemMessage("Usage: /unfollow [user]"));
return "";
}
auto app = getApp();

auto user = app->accounts->twitch.getCurrent();
auto target = words.at(1);
auto currentUser = getApp()->accounts->twitch.getCurrent();

if (user->isAnon())
if (currentUser->isAnon())
{
channel->addMessage(
makeSystemMessage("You must be logged in to follow someone"));
return "";
}

auto target = words.at(1);

getHelix()->getUserByName(
target,
[user, channel, target](const auto &targetUser) {
user->unfollowUser(targetUser.id, [channel, target]() {
channel->addMessage(makeSystemMessage(
"You successfully unfollowed " + target));
});
[currentUser, channel, target](const auto &targetUser) {
getHelix()->unfollowUser(
currentUser->getUserId(), targetUser.id,
[channel, target]() {
channel->addMessage(makeSystemMessage(
"You successfully unfollowed " + target));
},
[channel, target]() {
channel->addMessage(makeSystemMessage(
"An error occurred while unfollowing " + target));
});
},
[channel, target] {
channel->addMessage(makeSystemMessage(
"User " + target + " could not be followed!"));
QString("User %1 could not be followed!").arg(target)));
});

return "";
Expand Down
41 changes: 0 additions & 41 deletions src/providers/twitch/TwitchAccount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,47 +290,6 @@ void TwitchAccount::checkFollow(const QString targetUserID,
[] {});
}

void TwitchAccount::followUser(const QString userID,
std::function<void()> successCallback)
{
QUrl requestUrl("https://api.twitch.tv/kraken/users/" + this->getUserId() +
"/follows/channels/" + userID);

NetworkRequest(requestUrl, NetworkRequestType::Put)

.authorizeTwitchV5(this->getOAuthClient(), this->getOAuthToken())
.onSuccess([successCallback](auto result) -> Outcome {
// TODO: Properly check result of follow request
successCallback();

return Success;
})
.execute();
}

void TwitchAccount::unfollowUser(const QString userID,
std::function<void()> successCallback)
{
QUrl requestUrl("https://api.twitch.tv/kraken/users/" + this->getUserId() +
"/follows/channels/" + userID);

NetworkRequest(requestUrl, NetworkRequestType::Delete)

.authorizeTwitchV5(this->getOAuthClient(), this->getOAuthToken())
.onError([successCallback](NetworkResult result) {
if (result.status() >= 200 && result.status() <= 299)
{
successCallback();
}
})
.onSuccess([successCallback](const auto &document) -> Outcome {
successCallback();

return Success;
})
.execute();
}

std::set<TwitchUser> TwitchAccount::getIgnores() const
{
std::lock_guard<std::mutex> lock(this->ignoresMutex_);
Expand Down
4 changes: 0 additions & 4 deletions src/providers/twitch/TwitchAccount.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,6 @@ class TwitchAccount : public Account

void checkFollow(const QString targetUserID,
std::function<void(FollowResult)> onFinished);
void followUser(const QString userID,
std::function<void()> successCallback);
void unfollowUser(const QString userID,
std::function<void()> successCallback);

std::set<TwitchUser> getIgnores() const;

Expand Down
44 changes: 44 additions & 0 deletions src/providers/twitch/api/Helix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,50 @@ void Helix::getGameById(QString gameId,
failureCallback);
}

void Helix::followUser(QString userId, QString targetId,
std::function<void()> successCallback,
HelixFailureCallback failureCallback)
{
QUrlQuery urlQuery;

urlQuery.addQueryItem("from_id", userId);
urlQuery.addQueryItem("to_id", targetId);

this->makeRequest("users/follows", urlQuery)
.type(NetworkRequestType::Post)
.onSuccess([successCallback](auto result) -> Outcome {
successCallback();
return Success;
})
.onError([failureCallback](auto result) {
// TODO: make better xd
failureCallback();
})
.execute();
}

void Helix::unfollowUser(QString userId, QString targetId,
std::function<void()> successCallback,
HelixFailureCallback failureCallback)
{
QUrlQuery urlQuery;

urlQuery.addQueryItem("from_id", userId);
urlQuery.addQueryItem("to_id", targetId);

this->makeRequest("users/follows", urlQuery)
.type(NetworkRequestType::Delete)
.onSuccess([successCallback](auto result) -> Outcome {
successCallback();
return Success;
})
.onError([failureCallback](auto result) {
// TODO: make better xd
failureCallback();
})
.execute();
}

NetworkRequest Helix::makeRequest(QString url, QUrlQuery urlQuery)
{
assert(!url.startsWith("/"));
Expand Down
8 changes: 8 additions & 0 deletions src/providers/twitch/api/Helix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@ class Helix final : boost::noncopyable
void getGameById(QString gameId, ResultCallback<HelixGame> successCallback,
HelixFailureCallback failureCallback);

void followUser(QString userId, QString targetId,
std::function<void()> successCallback,
HelixFailureCallback failureCallback);

void unfollowUser(QString userId, QString targetlId,
std::function<void()> successCallback,
HelixFailureCallback failureCallback);

void update(QString clientId, QString oauthToken);

static void initialize();
Expand Down
35 changes: 18 additions & 17 deletions src/providers/twitch/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,6 @@ Migration path: **Unknown**
Used in:
* `TwitchChannel::refreshTitle` to check the current stream title/game of offline channels

### Follow Channel
URL: https://dev.twitch.tv/docs/v5/reference/users#follow-channel
Requires `user_follows_edit` scope

Migration path: **Unknown**

* We implement this API in `providers/twitch/TwitchAccount.cpp followUser`

### Unfollow Channel
URL: https://dev.twitch.tv/docs/v5/reference/users#unfollow-channel
Requires `user_follows_edit` scope

Migration path: **Unknown**

* We implement this API in `providers/twitch/TwitchAccount.cpp unfollowUser`


### Get Cheermotes
URL: https://dev.twitch.tv/docs/v5/reference/bits#get-cheermotes

Expand Down Expand Up @@ -106,6 +89,24 @@ URL: https://dev.twitch.tv/docs/api/reference#get-streams
* `TwitchChannel` to get live status, game, title, and viewer count of a channel
* `NotificationController` to provide notifications for channels you might not have open in Chatterino, but are still interested in getting notifications for

### Follow User
URL: https://dev.twitch.tv/docs/api/reference#create-user-follows
Requires `user:edit:follows` scope

* We implement this in `providers/twitch/api/Helix.cpp followUser`
Used in:
* `widgets/dialogs/UserInfoPopup.cpp` to follow a user by ticking follow checkbox in usercard
* `controllers/commands/CommandController.cpp` in /follow command

### Unfollow User
URL: https://dev.twitch.tv/docs/api/reference#delete-user-follows
Requires `user:edit:follows` scope

* We implement this in `providers/twitch/api/Helix.cpp unfollowUser`
Used in:
* `widgets/dialogs/UserInfoPopup.cpp` to unfollow a user by unticking follow checkbox in usercard
* `controllers/commands/CommandController.cpp` in /unfollow command

## TMI
The TMI api is undocumented.

Expand Down
14 changes: 10 additions & 4 deletions src/widgets/dialogs/UserInfoPopup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,11 @@ void UserInfoPopup::installEvents()
{
case Qt::CheckState::Unchecked: {
this->ui_.follow->setEnabled(false);
currentUser->unfollowUser(this->userId_,
reenableFollowCheckbox);
getHelix()->unfollowUser(currentUser->getUserId(),
this->userId_,
reenableFollowCheckbox, [] {
//
});
}
break;

Expand All @@ -398,8 +401,11 @@ void UserInfoPopup::installEvents()

case Qt::CheckState::Checked: {
this->ui_.follow->setEnabled(false);
currentUser->followUser(this->userId_,
reenableFollowCheckbox);
getHelix()->followUser(currentUser->getUserId(),
this->userId_,
reenableFollowCheckbox, [] {
//
});
}
break;
}
Expand Down

0 comments on commit 2f5df3d

Please sign in to comment.