1
0

⬆️ Upgrade dependencies and migrate to @twurple/*

This commit is contained in:
2022-01-06 01:16:49 +01:00
parent f1ea2a1b64
commit 213fb9d390
7 changed files with 639 additions and 650 deletions

View File

@@ -8,15 +8,15 @@
"dev": "cross-env NODE_ENV=development nodemon -r dotenv/config index.ts" "dev": "cross-env NODE_ENV=development nodemon -r dotenv/config index.ts"
}, },
"dependencies": { "dependencies": {
"@twurple/api": "^5.0.13",
"@twurple/auth": "^5.0.13",
"@twurple/chat": "^5.0.13",
"@twurple/pubsub": "^5.0.13",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"express": "^4.17.1", "express": "^4.17.1",
"nodemon": "^2.0.5", "nodemon": "^2.0.5",
"ts-node": "^10.0.0", "ts-node": "^10.0.0",
"twitch": "^4.2.6",
"twitch-auth": "^4.2.6",
"twitch-chat-client": "^4.2.6",
"twitch-pubsub-client": "^4.2.6",
"typescript": "^4.3.2", "typescript": "^4.3.2",
"ws": "^7.3.1" "ws": "^7.3.1"
}, },

View File

@@ -3,7 +3,7 @@ import { getAuthProvider, getUsernameFromId } from "../helpers/twitch";
import { Action } from "../../interfaces/actions/Action"; import { Action } from "../../interfaces/actions/Action";
import { ActionType } from "../../enums/ActionType"; import { ActionType } from "../../enums/ActionType";
import { ChatClient } from "twitch-chat-client"; import { ChatClient } from "@twurple/chat";
import { broadcast } from "../helpers/webServer"; import { broadcast } from "../helpers/webServer";
import { start } from "../helpers/miniDb"; import { start } from "../helpers/miniDb";
@@ -20,7 +20,10 @@ async function connect(channels: Array<any>): Promise<void> {
return; return;
} }
chatClient = new ChatClient(authProvider, { channels: channels }); chatClient = new ChatClient({
authProvider,
channels
});
chatClient.onConnect(onConnect); chatClient.onConnect(onConnect);

View File

@@ -1,20 +1,17 @@
import { TokenData } from "../../interfaces/TokenData"; import { AccessToken } from "@twurple/auth";
import { promises as fs } from "fs"; import { promises as fs } from "fs";
import { resolve } from "path"; import { resolve } from "path";
const TOKENS_FILE = "tokens.json"; const TOKENS_FILE = "tokens.json";
const LOG_PREFIX = "[TokenData] "; const LOG_PREFIX = "[TokenData] ";
export { export { getTokenData, saveTokenData };
getTokenData,
saveTokenData
};
function getTokenDataFilePath(): string { function getTokenDataFilePath(): string {
return resolve(process.cwd(), TOKENS_FILE); return resolve(process.cwd(), TOKENS_FILE);
} }
async function getTokenData(): Promise<TokenData> { async function getTokenData(): Promise<AccessToken> {
const tokenDataFilePath = getTokenDataFilePath(); const tokenDataFilePath = getTokenDataFilePath();
let buffer: Buffer; let buffer: Buffer;
@@ -34,7 +31,7 @@ async function getTokenData(): Promise<TokenData> {
return tokenData; return tokenData;
} }
async function saveTokenData(tokenData: TokenData): Promise<void> { async function saveTokenData(tokenData: AccessToken): Promise<void> {
const tokenDataFilePath = getTokenDataFilePath(); const tokenDataFilePath = getTokenDataFilePath();
const jsonTokenData = JSON.stringify(tokenData); const jsonTokenData = JSON.stringify(tokenData);
@@ -42,8 +39,8 @@ async function saveTokenData(tokenData: TokenData): Promise<void> {
console.log(`${LOG_PREFIX}Token data saved`); console.log(`${LOG_PREFIX}Token data saved`);
} }
function checkTokenData(tokenData: TokenData): void { function checkTokenData(tokenData: AccessToken): void {
if (!tokenData.access_token || !tokenData.refresh_token) { if (!tokenData.accessToken || !tokenData.refreshToken) {
console.error( console.error(
`${LOG_PREFIX}Missing refresh_token or access_token in ${TOKENS_FILE}.` `${LOG_PREFIX}Missing refresh_token or access_token in ${TOKENS_FILE}.`
); );

View File

@@ -1,29 +1,17 @@
import { import { AccessToken, RefreshingAuthProvider } from "@twurple/auth";
AccessToken,
RefreshableAuthProvider,
StaticAuthProvider
} from "twitch-auth";
import { getTokenData, saveTokenData } from "./tokenData"; import { getTokenData, saveTokenData } from "./tokenData";
import { ApiClient } from "twitch"; import { ApiClient } from "@twurple/api";
import { ClientCredentials } from "../../interfaces/ClientCredentials"; import { ClientCredentials } from "../../interfaces/ClientCredentials";
import { TokenData } from "../../interfaces/TokenData";
const LOG_PREFIX = "[Twitch] "; const LOG_PREFIX = "[Twitch] ";
let refreshAuthProvider: RefreshableAuthProvider; let refreshAuthProvider: RefreshingAuthProvider;
export { export { getAuthProvider, getApiClient, getUsernameFromId };
getAuthProvider,
getApiClient,
getUsernameFromId
};
function getClientCredentials(): ClientCredentials { function getClientCredentials(): ClientCredentials {
if ( if (!process.env.TWITCH_CLIENT_ID || !process.env.TWITCH_CLIENT_SECRET) {
!process.env.TWITCH_CLIENT_ID ||
!process.env.TWITCH_CLIENT_SECRET
) {
console.error( console.error(
`${LOG_PREFIX}Missing environment parameters TWITCH_CLIENT_ID or TWITCH_CLIENT_SECRET` `${LOG_PREFIX}Missing environment parameters TWITCH_CLIENT_ID or TWITCH_CLIENT_SECRET`
); );
@@ -36,57 +24,31 @@ function getClientCredentials(): ClientCredentials {
}; };
} }
async function createStaticAuthProvider(): Promise<StaticAuthProvider> { async function getAuthProvider(): Promise<RefreshingAuthProvider> {
let tokenData = await getTokenData();
const credentials = getClientCredentials();
return new StaticAuthProvider(credentials.clientId, tokenData.access_token);
}
async function getAuthProvider(): Promise<RefreshableAuthProvider> {
if (refreshAuthProvider) { if (refreshAuthProvider) {
return refreshAuthProvider; return refreshAuthProvider;
} }
let tokenData = await getTokenData(); let tokenData = await getTokenData();
const staticAuthProvider = await createStaticAuthProvider();
const credentials = getClientCredentials(); const credentials = getClientCredentials();
const expiry = refreshAuthProvider = new RefreshingAuthProvider(
tokenData.expiryTimestamp === null {
? null clientId: credentials.clientId,
: new Date(tokenData.expiryTimestamp); clientSecret: credentials.clientSecret,
onRefresh
refreshAuthProvider = new RefreshableAuthProvider(staticAuthProvider, { },
clientSecret: credentials.clientSecret, tokenData
refreshToken: tokenData.refresh_token, );
expiry,
onRefresh: onRefresh
});
return refreshAuthProvider; return refreshAuthProvider;
} }
async function onRefresh(refreshData: AccessToken): Promise<void> { async function onRefresh(refreshData: AccessToken): Promise<void> {
const {
accessToken,
refreshToken,
expiryDate
} = refreshData;
console.log(`${LOG_PREFIX}Tokens refreshed`); console.log(`${LOG_PREFIX}Tokens refreshed`);
const expiryTimestamp = expiryDate === null await saveTokenData(refreshData);
? 0
: expiryDate.getTime();
const newTokenData: TokenData = {
access_token: accessToken,
refresh_token: refreshToken,
expiryTimestamp
};
await saveTokenData(newTokenData);
} }
async function getApiClient(): Promise<ApiClient> { async function getApiClient(): Promise<ApiClient> {

View File

@@ -1,13 +1,14 @@
import { PubSubClient, PubSubRedemptionMessage } from "twitch-pubsub-client"; import { PubSubClient, PubSubRedemptionMessage } from "@twurple/pubsub";
import { RedemptionIds } from "../../enums/Redemptions"; import { RedemptionIds } from "../../enums/Redemptions";
import { RedemptionMessage } from "../../interfaces/RedemptionMessage"; import { RedemptionMessage } from "../../interfaces/RedemptionMessage";
import { UserIdResolvable } from "twitch"; import { UserIdResolvable } from "@twurple/api";
import { broadcast } from "../helpers/webServer"; import { broadcast } from "../helpers/webServer";
import { getApiClient } from "../helpers/twitch"; import { getAuthProvider } from "../helpers/twitch";
import { getVip } from "./actions/getVip"; import { getVip } from "./actions/getVip";
import { hidrate } from "./actions/hidrate"; import { hidrate } from "./actions/hidrate";
import { highlightMessage } from "./actions/highlightMessage"; import { highlightMessage } from "./actions/highlightMessage";
import { rawDataSymbol } from "@twurple/common";
import { russianRoulette } from "./actions/russianRoulette"; import { russianRoulette } from "./actions/russianRoulette";
import { stealVip } from "./actions/stealVip"; import { stealVip } from "./actions/stealVip";
import { timeoutFriend } from "./actions/timeoutFriend"; import { timeoutFriend } from "./actions/timeoutFriend";
@@ -15,10 +16,11 @@ import { timeoutFriend } from "./actions/timeoutFriend";
const LOG_PREFIX = "[PubSub] "; const LOG_PREFIX = "[PubSub] ";
async function registerUserListener(user: UserIdResolvable) { async function registerUserListener(user: UserIdResolvable) {
const apiClient = await getApiClient();
const pubSubClient = new PubSubClient(); const pubSubClient = new PubSubClient();
const userId = await pubSubClient.registerUserListener(apiClient, user); const userId = await pubSubClient.registerUserListener(
await getAuthProvider(),
user
);
/*const listener = */ await pubSubClient.onRedemption(userId, onRedemption); /*const listener = */ await pubSubClient.onRedemption(userId, onRedemption);
console.log(`${LOG_PREFIX}Connected & registered`); console.log(`${LOG_PREFIX}Connected & registered`);
@@ -26,24 +28,23 @@ async function registerUserListener(user: UserIdResolvable) {
async function onRedemption(message: PubSubRedemptionMessage) { async function onRedemption(message: PubSubRedemptionMessage) {
console.log( console.log(
`${LOG_PREFIX}Reward: "${message.rewardName}" (${message.rewardId}) redeemed by ${message.userDisplayName}` `${LOG_PREFIX}Reward: "${message.rewardTitle}" (${message.rewardId}) redeemed by ${message.userDisplayName}`
); );
// @ts-ignore
const reward = message._data.data.redemption.reward; const raw = message[rawDataSymbol];
const msg: RedemptionMessage = { const msg: RedemptionMessage = {
id: message.id, id: message.id,
channelId: message.channelId, channelId: message.channelId,
rewardId: message.rewardId, rewardId: message.rewardId,
rewardName: message.rewardName, rewardName: message.rewardTitle,
rewardImage: message.rewardImage rewardImage: message.rewardImage
? message.rewardImage.url_4x ? message.rewardImage.url_4x
: "https://static-cdn.jtvnw.net/custom-reward-images/default-4.png", : "https://static-cdn.jtvnw.net/custom-reward-images/default-4.png",
message: message.message, message: message.message,
userId: message.userId, userId: message.userId,
userDisplayName: message.userDisplayName, userDisplayName: message.userDisplayName,
// non directly available values from PubSubRedemptionMessage backgroundColor: raw.data.redemption.reward.background_color
backgroundColor: reward.background_color
}; };
let handledMessage: RedemptionMessage | undefined; let handledMessage: RedemptionMessage | undefined;

View File

@@ -1,5 +0,0 @@
export interface TokenData {
access_token: string;
refresh_token: string;
expiryTimestamp: number;
}

1161
yarn.lock

File diff suppressed because it is too large Load Diff