Skip to content

Commit

Permalink
fix: use viewerfeedback creator api
Browse files Browse the repository at this point in the history
  • Loading branch information
riccardobl committed Jul 29, 2022
1 parent 3a0606b commit 2b6a015
Showing 1 changed file with 92 additions and 28 deletions.
120 changes: 92 additions & 28 deletions src/extension/content-script/batteries/Twitch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,45 @@ const urlMatcher = /^https:\/\/(?:www\.)?twitch.tv\/([^/]+).+$/;
const validationRegex = /^[a-z0-9_.-]+$/i;
const clientIdExtractor = /clientId="([A-Z0-9]+)"/i;

/* eslint-disable @typescript-eslint/no-explicit-any */
async function twitchApiCall(
clientId: string,
version: number,
operationName: string,
staticHash: string,
variables: { [prop: string]: string | number }
): Promise<any> {
const data = await fetch(`https://gql.twitch.tv/gql`, {
headers: {
"Client-Id": clientId,
"User-Agent": navigator.userAgent,
},
method: "POST",
body: JSON.stringify([
{
operationName: operationName,
variables: variables,
extensions: {
persistedQuery: {
version: version,
sha256Hash: staticHash,
},
},
},
]),
}).then((res) => res.json());
return data;
}

const battery = async (): Promise<void> => {
const urlParts = document.location.pathname.split("/");
const channel = urlParts[1];

if (!channel) return; // not a channel
if (!validationRegex.test(channel)) return; // invalid channel
let channel = urlParts[1] != "videos" ? urlParts[1] : undefined;
const video = urlParts[1] == "videos" ? urlParts[2] : undefined;

if (!channel && !video) return; // not a channel
if (channel && !validationRegex.test(channel)) return; // invalid channel
if (video && !validationRegex.test(video)) return; // invalid video

let channelData;

Expand All @@ -37,37 +70,68 @@ const battery = async (): Promise<void> => {
}
}

let channelID;

// Get channel ID
if (video) {
// If video page
channelData = (
await twitchApiCall(
clientId,
1,
"ChannelVideoCore",
"cf1ccf6f5b94c94d662efec5223dfb260c9f8bf053239a76125a58118769e8e2",
{
videoID: video,
}
)
)[0];
if (
channelData &&
channelData.data &&
channelData.data.video &&
channelData.data.video.owner
) {
channelID = channelData.data.video.owner.id;
channel = channelData.data.video.owner.login;
}
} else if (channel) {
// if channel page
channelData = (
await twitchApiCall(
clientId,
1,
"ChannelShell",
"580ab410bcd0c1ad194224957ae2241e5d252b2c5173d8e0cce9d32d5bb14efe",
{
login: channel,
}
)
)[0];
if (channelData && channelData.data && channelData.data.userOrError) {
channelID = channelData.data.userOrError.id;
}
}

if (!channelID) return;

// Simulate internal API call to obtain channelData.
// A public api should be used here instead, but i couldn't find an alternative
// that didn't require oauth (thus breaking user experience).
channelData = await fetch(`https://gql.twitch.tv/gql`, {
headers: {
"Client-Id": clientId,
"User-Agent": navigator.userAgent,
},
method: "POST",
body: JSON.stringify([
{
operationName: "ChannelRoot_AboutPanel",
variables: {
channelLogin: channel,
skipSchedule: true,
},
extensions: {
persistedQuery: {
version: 1,
sha256Hash:
"6089531acef6c09ece01b440c41978f4c8dc60cb4fa0124c9a9d3f896709b6c6",
},
},
},
]),
}).then((res) => res.json());
channelData = await twitchApiCall(
clientId,
1,
"ViewerFeedback_Creator",
"26c143e165e6d56fc69daddac9942d93ca48aa9ad3b6f38abf75ac45f5e59571",
{
channelID: channelID,
}
);

channelData =
!channelData || !channelData[0] || !channelData[0].data.user
!channelData || !channelData[0] || !channelData[0].data.creator
? null
: channelData[0].data.user;
: channelData[0].data.creator;

if (channelData) break;
else {
Expand Down

0 comments on commit 2b6a015

Please sign in to comment.