From bbc932355a90fdc5a275180acc4ff4ed18d9f815 Mon Sep 17 00:00:00 2001
From: Your Name
Date: Mon, 16 Dec 2024 20:47:00 -0700
Subject: [PATCH] Remove twitch.tv integration for NFL
---
README.md | 3 +-
package-lock.json | 4 +-
package.json | 2 +-
services/nfl-handler.ts | 170 +++-------------------
services/providers/nfl/index.tsx | 17 +--
services/providers/nfl/views/CardBody.tsx | 18 ---
6 files changed, 26 insertions(+), 188 deletions(-)
diff --git a/README.md b/README.md
index 53a546c..ce32fe4 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
-Current version: **4.1.3**
+Current version: **4.1.4**
# About
This takes ESPN+, ESPN, FOX Sports, CBS Sports, Paramount+, Gotham Sports, NFL, B1G+, NESN, Mountain West, FloSports, or MLB.tv programming and transforms it into a "live TV" experience with virtual linear channels. It will discover what is on, and generate a schedule of channels that will give you M3U and XMLTV files that you can import into something like [Jellyfin](https://jellyfin.org) or [Channels](https://getchannels.com).
@@ -117,7 +117,6 @@ If you don't have an NFL+ subscription, you can use these providers to access ga
| Provider Name | Description |
|---|---|
| Amazon Prime | Get TNF games from Amazon Prime |
-| Twitch | Get TNF games from Twitch.tv (no auth required) |
| Peacock | Get SNF games from Peacock |
| TV Provider | Get in-market games from your TV Provider |
| Sunday Ticket | Get out-of-market games from Youtube |
diff --git a/package-lock.json b/package-lock.json
index 3d1a51e..fd18b03 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "eplustv",
- "version": "4.1.3",
+ "version": "4.1.4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "eplustv",
- "version": "4.1.3",
+ "version": "4.1.4",
"license": "MIT",
"dependencies": {
"@hono/node-server": "^1.13.1",
diff --git a/package.json b/package.json
index 6cd1687..58dbc58 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "eplustv",
- "version": "4.1.3",
+ "version": "4.1.4",
"description": "",
"scripts": {
"start": "ts-node -r tsconfig-paths/register index.tsx",
diff --git a/services/nfl-handler.ts b/services/nfl-handler.ts
index 3e2aa0d..f7758bd 100644
--- a/services/nfl-handler.ts
+++ b/services/nfl-handler.ts
@@ -5,12 +5,12 @@ import axios from 'axios';
import moment from 'moment';
import jwt_decode from 'jwt-decode';
-import {okHttpUserAgent, userAgent} from './user-agent';
+import {okHttpUserAgent} from './user-agent';
import {configPath} from './config';
import {useNfl} from './networks';
import {ClassTypeWithoutMethods, IEntry, IHeaders, IProvider} from './shared-interfaces';
import {db} from './database';
-import {getRandomHex, getRandomUUID} from './shared-helpers';
+import {getRandomUUID} from './shared-helpers';
import {useLinear} from './channels';
import {debug} from './debug';
@@ -119,39 +119,6 @@ const CLIENT_SECRET = ['q', 'G', 'h', 'E', 'v', '1', 'R', 't', 'I', '2', 'S', 'f
const TV_CLIENT_SECRET = ['u', 'o', 'C', 'y', 'y', 'k', 'y', 'U', 'w', 'D', 'b', 'f', 'Q', 'Z', 'r', '2'].join('');
-const TWITCH_CLIENT_ID = [
- 'k',
- 'i',
- 'm',
- 'n',
- 'e',
- '7',
- '8',
- 'k',
- 'x',
- '3',
- 'n',
- 'c',
- 'x',
- '6',
- 'b',
- 'r',
- 'g',
- 'o',
- '4',
- 'm',
- 'v',
- '6',
- 'w',
- 'k',
- 'i',
- '5',
- 'h',
- '1',
- 'k',
- 'o',
-].join('');
-
const DEVICE_INFO = {
capabilities: {},
ctvDevice: 'AndroidTV',
@@ -194,7 +161,7 @@ const DEFAULT_CATEGORIES = ['NFL', 'NFL+', 'Football'];
const nflConfigPath = path.join(configPath, 'nfl_tokens.json');
-export type TOtherAuth = 'prime' | 'tve' | 'peacock' | 'sunday_ticket' | 'twitch';
+export type TOtherAuth = 'prime' | 'tve' | 'peacock' | 'sunday_ticket';
interface INFLJwt {
dmaCode: string;
@@ -202,19 +169,6 @@ interface INFLJwt {
networks?: {[key: string]: string};
}
-interface ITwitchAccessTokenRes {
- data: ITwitchAccessToken;
-}
-
-interface ITwitchAccessToken {
- streamPlaybackAccessToken: ITwitchStreamToken;
-}
-
-interface ITwitchStreamToken {
- value: string;
- signature: string;
-}
-
const parseAirings = async (events: INFLEvent[]) => {
const now = moment();
const endDate = moment().add(2, 'days').endOf('day');
@@ -291,7 +245,6 @@ class NflHandler {
public peacockUUID?: string;
public youTubeUserId?: string;
public youTubeUUID?: string;
- public twitchDeviceId?: string;
public initialize = async () => {
const setup = (await db.providers.count({name: 'nfl'})) > 0 ? true : false;
@@ -444,24 +397,10 @@ class NflHandler {
this.checkTVEEventAccess(i) ||
// Peacock
(i.authorizations.peacock && this.checkPeacockAccess()) ||
- // Prime || Twitch.tv
- (i.authorizations.amazon_prime && (this.checkPrimeAccess() || this.checkTwitchAccess()))
+ // Prime
+ (i.authorizations.amazon_prime && this.checkPrimeAccess())
) {
- if (i.authorizations.amazon_prime) {
- if (this.checkTwitchAccess()) {
- events.push({
- ...i,
- externalId: `${i.externalId}-twitch`,
- networks: ['Twitch'],
- });
- }
-
- if (this.checkPrimeAccess()) {
- events.push(i);
- }
- } else {
- events.push(i);
- }
+ events.push(i);
}
} else if (
i.callSign === 'NFLNRZ' &&
@@ -520,97 +459,31 @@ class NflHandler {
const isGame =
event.channel !== 'NFLNETWORK' && event.channel !== 'NFLDIGITAL1_OO_v3' && event.channel !== 'NFLNRZ';
- const isTwitch = event.feed === 'Twitch';
-
- if (!isTwitch) {
- const url = ['https://', 'api.nfl.com/', 'play/v1/asset/', id].join('');
-
- const {data} = await axios.post(
- url,
- {
- ...(this.checkTVEAccess() && {
- idp: this.mvpdIdp,
- mvpdUUID: this.mvpdUUID,
- mvpdUserId: this.mvpdUserId,
- networks: event.feed || 'NFLN',
- }),
- },
- {
- headers: {
- 'Content-Type': 'application/json',
- 'User-Agent': okHttpUserAgent,
- authorization: `Bearer ${isGame ? this.access_token : this.tv_access_token}`,
- },
- },
- );
-
- return [data.accessUrl, {}];
- } else {
- try {
- const channel = event.name.indexOf('Vision') > -1 ? 'primevision' : 'primevideo';
-
- const accessToken = await this.getTwitchAccessToken(channel);
-
- const url = [
- 'https://usher.ttvnw.net',
- '/api/channel/hls/',
- `${channel}.m3u8`,
- '?client_id=',
- TWITCH_CLIENT_ID,
- '&token=',
- accessToken.value,
- '&sig=',
- accessToken.signature,
- '&allow_source=true',
- '&allow_audio_only=false',
- ].join('');
-
- return [url, {}];
- } catch (e) {
- console.error(e);
- console.log('Could not start playback from Twitch');
- }
- }
- } catch (e) {
- console.error(e);
- console.log('Could not start playback');
- }
- };
+ const url = ['https://', 'api.nfl.com/', 'play/v1/asset/', id].join('');
- private getTwitchAccessToken = async (channel: string): Promise => {
- try {
- const {data} = await axios.post(
- 'https://gql.twitch.tv/gql',
+ const {data} = await axios.post(
+ url,
{
- extensions: {
- persistedQuery: {
- sha256Hash: 'ed230aa1e33e07eebb8928504583da78a5173989fadfb1ac94be06a04f3cdbe9',
- version: 1,
- },
- },
- operationName: 'PlaybackAccessToken',
- variables: {
- isLive: true,
- isVod: false,
- login: channel,
- platform: 'web',
- playerType: 'site',
- vodID: '',
- },
+ ...(this.checkTVEAccess() && {
+ idp: this.mvpdIdp,
+ mvpdUUID: this.mvpdUUID,
+ mvpdUserId: this.mvpdUserId,
+ networks: event.feed || 'NFLN',
+ }),
},
{
headers: {
- 'Client-id': TWITCH_CLIENT_ID,
- 'User-Agent': userAgent,
- 'X-Device-Id': this.twitchDeviceId || getRandomHex(),
+ 'Content-Type': 'application/json',
+ 'User-Agent': okHttpUserAgent,
+ authorization: `Bearer ${isGame ? this.access_token : this.tv_access_token}`,
},
},
);
- return data.data.streamPlaybackAccessToken;
+ return [data.accessUrl, {}];
} catch (e) {
console.error(e);
- console.log('Could not get Twitch access token');
+ console.log('Could not start playback');
}
};
@@ -698,7 +571,6 @@ class NflHandler {
private checkPeacockAccess = (): boolean => (this.peacockUserId ? true : false);
private checkPrimeAccess = (): boolean => (this.amazonPrimeUserId ? true : false);
private checkSundayTicketAccess = (): boolean => (this.youTubeUserId ? true : false);
- private checkTwitchAccess = (): boolean => (this.twitchDeviceId ? true : false);
private checkTVEEventAccess = (event: INFLEvent): boolean => {
let hasChannel = false;
@@ -1068,7 +940,6 @@ class NflHandler {
peacockUUID,
youTubeUserId,
youTubeUUID,
- twitchDeviceId,
} = tokens;
this.device_id = device_id;
@@ -1090,7 +961,6 @@ class NflHandler {
this.peacockUUID = peacockUUID;
this.youTubeUUID = youTubeUUID;
this.youTubeUserId = youTubeUserId;
- this.twitchDeviceId = twitchDeviceId;
};
private loadJSON = () => {
diff --git a/services/providers/nfl/index.tsx b/services/providers/nfl/index.tsx
index 6498bec..8e37c70 100644
--- a/services/providers/nfl/index.tsx
+++ b/services/providers/nfl/index.tsx
@@ -4,7 +4,6 @@ import { db } from '@/services/database';
import { IProvider } from '@/services/shared-interfaces';
import { removeEntriesProvider, scheduleEntries } from '@/services/build-schedule';
import { nflHandler, TNFLTokens, TOtherAuth } from '@/services/nfl-handler';
-import { getRandomHex } from '@/services/shared-helpers';
import { Login } from './views/Login';
import { NFLBody } from './views/CardBody';
@@ -62,24 +61,12 @@ nfl.put('/auth/:provider', async c => {
delete updatedTokens.youTubeUUID;
delete updatedTokens.youTubeUserId;
break;
- case 'twitch':
- delete updatedTokens.twitchDeviceId;
- break;
- }
- } else {
- if (provider === 'twitch') {
- updatedTokens.twitchDeviceId = getRandomHex();
}
}
- if (!enabled || provider === 'twitch') {
+ if (!enabled) {
const {linear_channels, tokens} = await db.providers.update>({name: 'nfl'}, {$set: {tokens: updatedTokens}}, {returnUpdatedDocs: true});
- if (provider === 'twitch' && enabled) {
- // Kickoff event scheduler
- await scheduleEvents();
- }
-
return c.html();
}
@@ -116,7 +103,7 @@ nfl.get('/login/:code/:other', async c => {
? ' (Peacock)'
: otherAuth === 'sunday_ticket'
? ' (Youtube)'
- : otherAuth === 'twitch' ? ' (Twitch)' : '';
+ : '';
const message = `NFL${otherAuthName}`;
diff --git a/services/providers/nfl/views/CardBody.tsx b/services/providers/nfl/views/CardBody.tsx
index e6afb03..83e1c40 100644
--- a/services/providers/nfl/views/CardBody.tsx
+++ b/services/providers/nfl/views/CardBody.tsx
@@ -110,24 +110,6 @@ export const NFLBody: FC = ({enabled, tokens, open, channels}) =>
-
-
Twitch:
-
-
Sunday Ticket: