⬆️ Upgrade dependencies and migrate to @twurple/*
This commit is contained in:
@@ -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"
|
||||||
},
|
},
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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}.`
|
||||||
);
|
);
|
||||||
|
@@ -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> {
|
||||||
|
@@ -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;
|
||||||
|
@@ -1,5 +0,0 @@
|
|||||||
export interface TokenData {
|
|
||||||
access_token: string;
|
|
||||||
refresh_token: string;
|
|
||||||
expiryTimestamp: number;
|
|
||||||
}
|
|
Reference in New Issue
Block a user