switch to twurple
This commit is contained in:
12
src/bot.ts
12
src/bot.ts
@@ -1,13 +1,5 @@
|
||||
import type { Events } from "tmi.js";
|
||||
import { client } from "./core/client.ts";
|
||||
import { events } from "./events/collection.ts";
|
||||
|
||||
// Register all events with the TMI client
|
||||
for (const [eventName, eventHandler] of events) {
|
||||
client.on(
|
||||
eventName as keyof Events,
|
||||
eventHandler.triggered.bind(null, client),
|
||||
);
|
||||
}
|
||||
import { registerAllEvents } from "./events/registry.ts";
|
||||
|
||||
registerAllEvents(client);
|
||||
client.connect();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { ChatUserstate, Client } from "tmi.js";
|
||||
import type { ChatMessage } from "@twurple/chat";
|
||||
import { logSuccess } from "../logger/logger.ts";
|
||||
import type { ICommand, ICommandRequirements } from "./interface.ts";
|
||||
|
||||
export class SongCommand implements ICommand {
|
||||
@@ -12,12 +13,12 @@ export class SongCommand implements ICommand {
|
||||
};
|
||||
|
||||
triggered = async (
|
||||
client: Client,
|
||||
channel: string,
|
||||
_state: ChatUserstate,
|
||||
_message: string,
|
||||
_args: Array<string>,
|
||||
user: string,
|
||||
text: string,
|
||||
msg: ChatMessage,
|
||||
) => {
|
||||
client.say(channel, "testing");
|
||||
logSuccess(`${channel} song command triggered`);
|
||||
// client.say(channel, "testing");
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,8 +4,9 @@ dotenv.config();
|
||||
|
||||
export const Config = {
|
||||
prefix: process.env.PREFIX || "",
|
||||
username: process.env.USERNAME || "",
|
||||
access_token: process.env.ACCESS_TOKEN || "",
|
||||
bot_user_id: process.env.BOT_USER_ID || "",
|
||||
client_id: process.env.CLIENT_ID || "",
|
||||
client_secret: process.env.CLIENT_SECRET || "",
|
||||
channels: [process.env.CHANNELS || ""],
|
||||
developers: [process.env.DEVELOPERS || ""],
|
||||
};
|
||||
|
||||
@@ -1,11 +1,30 @@
|
||||
import { Client } from "tmi.js";
|
||||
import { promises as fs } from "node:fs";
|
||||
import { RefreshingAuthProvider } from "@twurple/auth";
|
||||
import { ChatClient } from "@twurple/chat";
|
||||
import { Config } from "../config/config.ts";
|
||||
|
||||
export const client = new Client({
|
||||
connection: { reconnect: true, secure: true },
|
||||
identity: {
|
||||
username: Config.username,
|
||||
password: `oauth:${Config.access_token}`,
|
||||
},
|
||||
// Auth Token Stuff
|
||||
const tokenData = JSON.parse(
|
||||
await fs.readFile("./tokens.125328655.json", "utf-8"),
|
||||
);
|
||||
|
||||
const authProvider = new RefreshingAuthProvider({
|
||||
clientId: Config.client_id,
|
||||
clientSecret: Config.client_secret,
|
||||
});
|
||||
|
||||
authProvider.onRefresh(
|
||||
async (userId, newTokenData) =>
|
||||
await fs.writeFile(
|
||||
`./tokens.${userId}.json`,
|
||||
JSON.stringify(newTokenData, null, 4),
|
||||
"utf-8",
|
||||
),
|
||||
);
|
||||
|
||||
await authProvider.addUserForToken(tokenData, ["chat"]);
|
||||
|
||||
export const client = new ChatClient({
|
||||
authProvider,
|
||||
channels: Config.channels,
|
||||
});
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import { Collection } from "@discordjs/collection";
|
||||
import ConnectedEvent from "./event-connected.ts";
|
||||
import MessageEvent from "./event-message.ts";
|
||||
import type { IEvent } from "./interface.ts";
|
||||
|
||||
export const events = new Collection<string, IEvent>();
|
||||
|
||||
events.set(ConnectedEvent.name, new ConnectedEvent());
|
||||
events.set(MessageEvent.name, new MessageEvent());
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { Events } from "tmi.js";
|
||||
import { logSuccess } from "../logger/logger.ts";
|
||||
import type { IEvent } from "./interface.ts";
|
||||
import type { EventName } from "./registry.ts";
|
||||
|
||||
export default class ConnectedEvent implements IEvent {
|
||||
name: keyof Events = "connected";
|
||||
name: EventName = "connected";
|
||||
|
||||
triggered = async () => {
|
||||
logSuccess("connected");
|
||||
logSuccess(this.name);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,66 +1,63 @@
|
||||
import { Collection } from "@discordjs/collection";
|
||||
import type { ChatUserstate, Client, Events } from "tmi.js";
|
||||
import type { ChatMessage } from "@twurple/chat";
|
||||
import { commands } from "../commands/collection.ts";
|
||||
import type { ICommand } from "../commands/interface.ts";
|
||||
import { Config } from "../config/config.ts";
|
||||
import type { IEvent } from "./interface.ts";
|
||||
import type { EventName } from "./registry.ts";
|
||||
|
||||
const Cooldowns = new Collection<string, number>();
|
||||
|
||||
export default class MessageEvent implements IEvent {
|
||||
name: keyof Events = "message";
|
||||
name: EventName = "message";
|
||||
|
||||
triggered = async (
|
||||
client: Client,
|
||||
channel: string,
|
||||
state: ChatUserstate,
|
||||
message: string,
|
||||
self: boolean,
|
||||
user: string,
|
||||
text: string,
|
||||
msg: ChatMessage,
|
||||
) => {
|
||||
if (self) return;
|
||||
await checkMessage(client, channel, state, message);
|
||||
await checkMessage(channel, user, text, msg);
|
||||
};
|
||||
}
|
||||
|
||||
async function checkMessage(
|
||||
client: Client,
|
||||
channel: string,
|
||||
state: ChatUserstate,
|
||||
message: string,
|
||||
user: string,
|
||||
text: string,
|
||||
msg: ChatMessage,
|
||||
) {
|
||||
const prefix = Config.prefix;
|
||||
if (!text.startsWith(prefix)) return;
|
||||
|
||||
if (!message.startsWith(prefix)) return;
|
||||
|
||||
const args = message.slice(prefix.length).trim().split(/ +/g);
|
||||
const commandName = args[0].toLowerCase();
|
||||
const commandName = text
|
||||
.slice(prefix.length)
|
||||
.trim()
|
||||
.split(/ +/g)[0]
|
||||
.toLowerCase();
|
||||
const command = commands.get(commandName);
|
||||
if (!command) return;
|
||||
if (!command.enabled) return;
|
||||
|
||||
const userId = state["user-id"] as string;
|
||||
if (command.requirements.developer && !isDeveloper(userId)) return;
|
||||
if (command.requirements.mod && !isMod(state)) return;
|
||||
if (command.requirements.developer && !isDeveloper(msg.userInfo.userId))
|
||||
return;
|
||||
if (command.requirements.mod && !msg.userInfo.isMod) return;
|
||||
|
||||
const timeLeft = checkCooldown(command);
|
||||
if (timeLeft > 0) {
|
||||
return client.say(
|
||||
channel,
|
||||
`you must wait ${timeLeft} more seconds to use the command again`,
|
||||
);
|
||||
// return client.say(
|
||||
// channel,
|
||||
// `@${user}, you must wait ${timeLeft} more seconds to use the command again`,
|
||||
// );
|
||||
}
|
||||
|
||||
await command.triggered(client, channel, state, message, args);
|
||||
await command.triggered(channel, user, text, msg);
|
||||
}
|
||||
|
||||
function isDeveloper(userId: string): boolean {
|
||||
return Config.developers.includes(userId);
|
||||
}
|
||||
|
||||
function isMod(state: ChatUserstate): boolean {
|
||||
return state.mod as boolean;
|
||||
}
|
||||
|
||||
function checkCooldown(command: ICommand): number {
|
||||
const now = Date.now();
|
||||
if (command.cooldown > 0) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Events } from "tmi.js";
|
||||
import type { EventName } from "./registry";
|
||||
|
||||
export interface IEvent {
|
||||
name: keyof Events;
|
||||
name: EventName;
|
||||
triggered(...args: unknown[]): Promise<unknown>;
|
||||
}
|
||||
|
||||
24
src/events/registry.ts
Normal file
24
src/events/registry.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import type { ChatClient } from "@twurple/chat";
|
||||
import ConnectedEvent from "./event-connected";
|
||||
import MessageEvent from "./event-message";
|
||||
import type { IEvent } from "./interface";
|
||||
|
||||
export const eventRegistry = {
|
||||
message: (client: ChatClient, handler: IEvent) =>
|
||||
client.onMessage(handler.triggered),
|
||||
connected: (client: ChatClient, handler: IEvent) =>
|
||||
client.onConnect(handler.triggered),
|
||||
};
|
||||
|
||||
export function registerAllEvents(client: ChatClient) {
|
||||
const events = [new MessageEvent(), new ConnectedEvent()];
|
||||
|
||||
for (const event of events) {
|
||||
const registerFn = eventRegistry[event.name];
|
||||
if (registerFn) {
|
||||
registerFn(client, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type EventName = keyof typeof eventRegistry;
|
||||
Reference in New Issue
Block a user