rework auth a little
This commit is contained in:
@@ -8,8 +8,8 @@
|
|||||||
"build": "npm run clean && tsc -p .",
|
"build": "npm run clean && tsc -p .",
|
||||||
"start": "node dist/bot.js",
|
"start": "node dist/bot.js",
|
||||||
"dev": "nodemon src/bot.ts",
|
"dev": "nodemon src/bot.ts",
|
||||||
"setup:env": "nodemon src/setup-env.ts",
|
"setup:env": "node src/setup/setup-env.ts",
|
||||||
"setup:auth": "nodemon src/setup-auth.ts"
|
"setup:auth": "node src/setup/setup-auth.ts"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { chatClient } from "./core/chat-client.ts";
|
import { chatClient } from "./core/client.ts";
|
||||||
import { registerAllEvents } from "./events/registry.ts";
|
import { registerAllEvents } from "./events/registry.ts";
|
||||||
|
|
||||||
registerAllEvents();
|
registerAllEvents();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { ChatUser } from "@twurple/chat";
|
import type { ChatUser } from "@twurple/chat";
|
||||||
import { Config } from "../config/config.ts";
|
import { Config } from "../config/config.ts";
|
||||||
import { chatClient } from "../core/chat-client.ts";
|
import { chatClient } from "../core/client.ts";
|
||||||
import type { ICommand, ICommandRequirements } from "./interface.ts";
|
import type { ICommand, ICommandRequirements } from "./interface.ts";
|
||||||
|
|
||||||
export abstract class BaseCommand implements ICommand {
|
export abstract class BaseCommand implements ICommand {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { ApiClient } from "@twurple/api";
|
||||||
import { type AccessToken, RefreshingAuthProvider } from "@twurple/auth";
|
import { type AccessToken, RefreshingAuthProvider } from "@twurple/auth";
|
||||||
import { ChatClient } from "@twurple/chat";
|
import { ChatClient } from "@twurple/chat";
|
||||||
import { Config } from "../config/config.ts";
|
import { Config } from "../config/config.ts";
|
||||||
@@ -12,18 +13,20 @@ if (!tokenData) {
|
|||||||
throw new Error();
|
throw new Error();
|
||||||
}
|
}
|
||||||
|
|
||||||
const authProviderPrivate = new RefreshingAuthProvider({
|
export const authProviderUserToken = new RefreshingAuthProvider({
|
||||||
clientId: Config.client_id,
|
clientId: Config.client_id,
|
||||||
clientSecret: Config.client_secret,
|
clientSecret: Config.client_secret,
|
||||||
});
|
});
|
||||||
|
|
||||||
authProviderPrivate.onRefresh(async (_userId, newTokenData: AccessToken) =>
|
authProviderUserToken.onRefresh(async (_userId, newTokenData: AccessToken) =>
|
||||||
tokenManager.createTokenFile(newTokenData),
|
tokenManager.createTokenFile(newTokenData),
|
||||||
);
|
);
|
||||||
|
|
||||||
authProviderPrivate.addUser(Config.bot_user_id, tokenData, ["chat"]);
|
authProviderUserToken.addUser(Config.bot_user_id, tokenData, ["chat"]);
|
||||||
|
|
||||||
export const chatClient = new ChatClient({
|
export const chatClient = new ChatClient({
|
||||||
authProvider: authProviderPrivate,
|
authProvider: authProviderUserToken,
|
||||||
channels: Config.channels,
|
channels: Config.channels,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const apiClient = new ApiClient({ authProvider: authProviderUserToken });
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { chatClient } from "../core/chat-client.ts";
|
import { chatClient } from "../core/client.ts";
|
||||||
import type { IEvent } from "./interface.ts";
|
import type { IEvent } from "./interface.ts";
|
||||||
import type { EventName } from "./registry.ts";
|
import type { EventName } from "./registry.ts";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { chatClient } from "../core/chat-client.ts";
|
import { chatClient } from "../core/client.ts";
|
||||||
import { logInfo } from "../util/logger.ts";
|
import { logInfo } from "../util/logger.ts";
|
||||||
import ConnectedEvent from "./impl/connected.ts";
|
import ConnectedEvent from "./impl/connected.ts";
|
||||||
import MessageEvent from "./impl/message.ts";
|
import MessageEvent from "./impl/message.ts";
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
import { exchangeCode } from "@twurple/auth";
|
|
||||||
import { Config } from "./config/config.ts";
|
|
||||||
import { TokenManager } from "./core/token-manager.ts";
|
|
||||||
import { TwitchAuth } from "./util/auth.ts";
|
|
||||||
import { logInfo } from "./util/logger.ts";
|
|
||||||
|
|
||||||
const port = 3000;
|
|
||||||
const redirectUri = `http://localhost:${port}`;
|
|
||||||
const scopes = ["chat:read", "chat:edit", "channel:moderate"];
|
|
||||||
|
|
||||||
const auth = new TwitchAuth(redirectUri);
|
|
||||||
const state = auth.generateState();
|
|
||||||
const authUrl = auth.getAuthorizationUrl(scopes, state);
|
|
||||||
logInfo("To authorize your Twitch bot, visit this URL:");
|
|
||||||
logInfo(authUrl);
|
|
||||||
const code = await auth.startCallbackServer(port, 120, state);
|
|
||||||
|
|
||||||
const tokenManager = new TokenManager(Config.bot_user_id);
|
|
||||||
|
|
||||||
tokenManager.createTokenFile(
|
|
||||||
await exchangeCode(Config.client_id, Config.client_secret, code, redirectUri),
|
|
||||||
);
|
|
||||||
97
src/setup/setup-auth.ts
Normal file
97
src/setup/setup-auth.ts
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import { exchangeCode } from "@twurple/auth";
|
||||||
|
import { Config } from "../config/config.ts";
|
||||||
|
import { TokenManager } from "../core/token-manager.ts";
|
||||||
|
import { TwitchAuth } from "../util/auth.ts";
|
||||||
|
import { logInfo } from "../util/logger.ts";
|
||||||
|
|
||||||
|
const port = 3000;
|
||||||
|
const redirectUri = `http://localhost:${port}`;
|
||||||
|
const scopes = [
|
||||||
|
"analytics:read:extensions",
|
||||||
|
"analytics:read:games",
|
||||||
|
"bits:read",
|
||||||
|
"channel:manage:ads",
|
||||||
|
"channel:read:ads",
|
||||||
|
"channel:manage:broadcast",
|
||||||
|
"channel:read:charity",
|
||||||
|
"channel:edit:commercial",
|
||||||
|
"channel:read:editors",
|
||||||
|
"channel:manage:extensions",
|
||||||
|
"channel:read:goals",
|
||||||
|
"channel:read:guest_star",
|
||||||
|
"channel:manage:guest_star",
|
||||||
|
"channel:read:hype_train",
|
||||||
|
"channel:manage:moderators",
|
||||||
|
"channel:read:polls",
|
||||||
|
"channel:manage:polls",
|
||||||
|
"channel:read:predictions",
|
||||||
|
"channel:manage:predictions",
|
||||||
|
"channel:manage:raids",
|
||||||
|
"channel:read:redemptions",
|
||||||
|
"channel:manage:redemptions",
|
||||||
|
"channel:manage:schedule",
|
||||||
|
"channel:read:stream_key",
|
||||||
|
"channel:read:subscriptions",
|
||||||
|
"channel:manage:videos",
|
||||||
|
"channel:read:vips",
|
||||||
|
"channel:manage:vips",
|
||||||
|
"clips:edit",
|
||||||
|
"moderation:read",
|
||||||
|
"moderator:manage:announcements",
|
||||||
|
"moderator:manage:automod",
|
||||||
|
"moderator:read:automod_settings",
|
||||||
|
"moderator:manage:automod_settings",
|
||||||
|
"moderator:manage:banned_users",
|
||||||
|
"moderator:read:blocked_terms",
|
||||||
|
"moderator:manage:blocked_terms",
|
||||||
|
"moderator:manage:chat_messages",
|
||||||
|
"moderator:read:chat_settings",
|
||||||
|
"moderator:manage:chat_settings",
|
||||||
|
"moderator:read:chatters",
|
||||||
|
"moderator:read:followers",
|
||||||
|
"moderator:read:guest_star",
|
||||||
|
"moderator:manage:guest_star",
|
||||||
|
"moderator:read:shield_mode",
|
||||||
|
"moderator:manage:shield_mode",
|
||||||
|
"moderator:read:shoutouts",
|
||||||
|
"moderator:manage:shoutouts",
|
||||||
|
"moderator:read:unban_requests",
|
||||||
|
"moderator:manage:unban_requests",
|
||||||
|
"user:edit",
|
||||||
|
"user:edit:follows",
|
||||||
|
"user:read:blocked_users",
|
||||||
|
"user:manage:blocked_users",
|
||||||
|
"user:read:broadcast",
|
||||||
|
"user:manage:chat_color",
|
||||||
|
"user:read:email",
|
||||||
|
"user:read:emotes",
|
||||||
|
"user:read:follows",
|
||||||
|
"user:read:moderated_channels",
|
||||||
|
"user:read:subscriptions",
|
||||||
|
"user:manage:whispers",
|
||||||
|
"channel:bot",
|
||||||
|
"channel:moderate",
|
||||||
|
"chat:edit",
|
||||||
|
"chat:read",
|
||||||
|
"user:bot",
|
||||||
|
"user:read:chat",
|
||||||
|
"user:write:chat",
|
||||||
|
"whispers:read",
|
||||||
|
"whispers:edit",
|
||||||
|
"moderator:manage:warnings",
|
||||||
|
];
|
||||||
|
|
||||||
|
const auth = new TwitchAuth(redirectUri);
|
||||||
|
const state = auth.generateState();
|
||||||
|
const authUrl = auth.getAuthorizationUrl(scopes, state);
|
||||||
|
logInfo("To authorize your Twitch bot, visit this URL:");
|
||||||
|
logInfo(authUrl);
|
||||||
|
const code = await auth.startCallbackServer(port, 120, state);
|
||||||
|
|
||||||
|
const tokenManager = new TokenManager(Config.bot_user_id);
|
||||||
|
|
||||||
|
tokenManager.createTokenFile(
|
||||||
|
await exchangeCode(Config.client_id, Config.client_secret, code, redirectUri),
|
||||||
|
);
|
||||||
|
|
||||||
|
logInfo("Token file created");
|
||||||
@@ -7,4 +7,4 @@ const authProvider = new AppTokenAuthProvider(
|
|||||||
Config.client_secret,
|
Config.client_secret,
|
||||||
);
|
);
|
||||||
|
|
||||||
export const apiClient = new ApiClient({ authProvider });
|
export const setupClient = new ApiClient({ authProvider });
|
||||||
@@ -1,12 +1,23 @@
|
|||||||
import { getUserId, promptForInput } from "./util/general.ts";
|
import { promptForInput } from "../util/general.ts";
|
||||||
import { logError, logSuccess, logWarning } from "./util/logger.ts";
|
import { logError, logSuccess, logWarning } from "../util/logger.ts";
|
||||||
|
import { setupClient } from "./setup-client.ts";
|
||||||
|
|
||||||
const botname = await promptForInput("enter bot username: ");
|
const botname = await promptForInput("enter bot username: ");
|
||||||
const developers = (
|
const developers = (
|
||||||
await promptForInput("enter developer usernames (,separated): ")
|
await promptForInput("enter developer usernames (,separated): ")
|
||||||
).split(",");
|
).split(",");
|
||||||
|
|
||||||
const botId = await getUserId(botname);
|
const getUid = async (username: string) => {
|
||||||
|
const user = await setupClient.users.getUserByName(username);
|
||||||
|
if (user?.id) {
|
||||||
|
logSuccess(`${user.name} => ${user.id}`);
|
||||||
|
return user.id;
|
||||||
|
}
|
||||||
|
logWarning(`no user with name ${username} found`);
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
const botId = await getUid(botname);
|
||||||
if (!botId) {
|
if (!botId) {
|
||||||
logError("bot not found. please check the configuration");
|
logError("bot not found. please check the configuration");
|
||||||
throw new Error();
|
throw new Error();
|
||||||
@@ -14,7 +25,7 @@ if (!botId) {
|
|||||||
|
|
||||||
const developerIds = [];
|
const developerIds = [];
|
||||||
for (const dev of developers) {
|
for (const dev of developers) {
|
||||||
const devId = await getUserId(dev);
|
const devId = await getUid(dev);
|
||||||
if (devId) {
|
if (devId) {
|
||||||
developerIds.push(devId);
|
developerIds.push(devId);
|
||||||
} else {
|
} else {
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { UserIdResolvable } from "@twurple/api";
|
import { HellFreezesOverError, type UserIdResolvable } from "@twurple/api";
|
||||||
import { Config } from "../config/config.ts";
|
import { Config } from "../config/config.ts";
|
||||||
import { apiClient } from "../core/api-client.ts";
|
import { apiClient } from "../core/client.ts";
|
||||||
import { getUserId } from "./general.ts";
|
import { getUserId } from "./general.ts";
|
||||||
import { logError } from "./logger.ts";
|
import { logError } from "./logger.ts";
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as readline from "node:readline";
|
import * as readline from "node:readline";
|
||||||
import type { UserIdResolvable } from "@twurple/api";
|
import type { UserIdResolvable } from "@twurple/api";
|
||||||
import { apiClient } from "../core/api-client.ts";
|
import { apiClient } from "../core/client.ts";
|
||||||
import { logSuccess, logWarning } from "./logger.ts";
|
import { logSuccess, logWarning } from "./logger.ts";
|
||||||
|
|
||||||
export async function getUserId(username: string): Promise<UserIdResolvable> {
|
export async function getUserId(username: string): Promise<UserIdResolvable> {
|
||||||
|
|||||||
Reference in New Issue
Block a user