Skip to content

Commit

Permalink
Merge pull request #1017 from riccardobl/twitch
Browse files Browse the repository at this point in the history
Add twitch support
  • Loading branch information
im-adithya authored Apr 6, 2023
2 parents 192b3a0 + 53c9420 commit 842a24b
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 0 deletions.
132 changes: 132 additions & 0 deletions src/extension/content-script/batteries/Twitch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import getOriginData from "../originData";
import { findLightningAddressInText, setLightningData } from "./helpers";

const urlMatcher = /^https:\/\/(?:www\.)?twitch.tv\/([^/]+).+$/;

/* 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;
}

function extractClientId() {
const clientIdExtractor = /clientId="([A-Z0-9]+)"/i;
for (const scriptEl of document.querySelectorAll("script")) {
const clientIdMatch = scriptEl.innerHTML.match(clientIdExtractor);
const clientId = clientIdMatch ? clientIdMatch[1] : "";
if (clientId) {
return clientId;
}
}
}

async function fetchChannelDescription(channelID: string, clientId: string) {
const channelData = (
await twitchApiCall(
clientId,
1,
"ViewerFeedback_Creator",
"26c143e165e6d56fc69daddac9942d93ca48aa9ad3b6f38abf75ac45f5e59571",
{
channelID,
}
)
)[0];
if (channelData?.data?.creator) {
const creatorDetails = channelData.data.creator;
const channelDescription = creatorDetails.description;
const address = findLightningAddressInText(channelDescription);

if (address) {
setLightningData([
{
method: "lnurl",
address,
...getOriginData(),
description: channelDescription,
name: creatorDetails.displayName ?? creatorDetails.login,
icon: creatorDetails.profileImageURL ?? "",
},
]);
}
}
}

async function handleChannelPage(channel: string, clientId: string) {
const channelData = (
await twitchApiCall(
clientId,
1,
"ChannelShell",
"580ab410bcd0c1ad194224957ae2241e5d252b2c5173d8e0cce9d32d5bb14efe",
{
login: channel,
}
)
)[0];
if (channelData?.data?.userOrError?.id) {
fetchChannelDescription(channelData.data.userOrError.id, clientId);
}
}

async function handleVideoPage(videoID: string, clientId: string) {
const channelData = (
await twitchApiCall(
clientId,
1,
"ChannelVideoCore",
"cf1ccf6f5b94c94d662efec5223dfb260c9f8bf053239a76125a58118769e8e2",
{
videoID,
}
)
)[0];
if (channelData?.data?.video?.owner?.id) {
fetchChannelDescription(channelData.data.video.owner.id, clientId);
}
return;
}

const battery = async (): Promise<void> => {
const urlParts = document.location.pathname.split("/");
const clientId = extractClientId();

if (!clientId) return;

if (urlParts[1] === "videos") {
await handleVideoPage(urlParts[2], clientId);
} else {
await handleChannelPage(urlParts[1], clientId);
}
};

const Twitch = {
urlMatcher,
battery,
};

export default Twitch;
2 changes: 2 additions & 0 deletions src/extension/content-script/batteries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Reddit from "./Reddit";
import SoundCloud from "./SoundCloud";
import StackOverflow from "./StackOverflow";
import Substack from "./Substack";
import Twitch from "./Twitch";
import Twitter from "./Twitter";
import Vida from "./Vida";
import VimeoVideo from "./VimeoVideo";
Expand All @@ -34,6 +35,7 @@ const enhancements = [
Substack,
GeyserProject,
Vida,
Twitch,

// Monetization must likely always be the last one as this is the fallback option if no specific enhancement matched
Monetization,
Expand Down

0 comments on commit 842a24b

Please sign in to comment.