mirror of
https://github.com/qwerinope/qweribot.git
synced 2025-12-19 08:41:39 +01:00
greatly improve user caching system
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
import { eventSub } from "..";
|
import { eventSub } from "..";
|
||||||
|
|
||||||
|
eventSub.onRevoke(event => {
|
||||||
|
console.info(`Successfully revoked EventSub subscription: ${event.id}`);
|
||||||
|
});
|
||||||
|
|
||||||
eventSub.onSubscriptionCreateSuccess(event => {
|
eventSub.onSubscriptionCreateSuccess(event => {
|
||||||
console.info(`Successfully created EventSub subscription: ${event.id}`);
|
console.info(`Successfully created EventSub subscription: ${event.id}`);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
import { redis } from "bun";
|
import { redis } from "bun";
|
||||||
import { chatterId, streamerId, eventSub, commandPrefix } from "..";
|
import { chatterId, streamerId, eventSub, commandPrefix, singleUserMode } from "..";
|
||||||
import { User } from "../user";
|
import { User } from "../user";
|
||||||
import commands, { sendMessage } from "../commands";
|
import commands, { sendMessage } from "../commands";
|
||||||
|
|
||||||
console.info(`Loaded the ${commands.keys().toArray().join(', ')} commands`);
|
console.info(`Loaded the following commands: ${commands.keys().toArray().join(', ')}`);
|
||||||
|
|
||||||
eventSub.onChannelChatMessage(streamerId, streamerId, async msg => {
|
eventSub.onChannelChatMessage(streamerId, streamerId, async msg => {
|
||||||
|
// return if double user mode is on and the chatter says something, we don't need them
|
||||||
|
if (!singleUserMode && msg.chatterId === chatterId) return
|
||||||
|
|
||||||
// Get user from cache or place user in cache
|
// Get user from cache or place user in cache
|
||||||
const user = await User.init(msg.chatterName);
|
const user = await User.initUserId(msg.chatterId);
|
||||||
|
|
||||||
// Manage vulnerable chatters
|
// Manage vulnerable chatters
|
||||||
if (![chatterId, streamerId].includes(msg.chatterId)) {// Don't add the chatter or streamer to the vulnerable chatters
|
if (![chatterId, streamerId].includes(msg.chatterId)) {// Don't add the chatter or streamer to the vulnerable chatters
|
||||||
|
|||||||
83
bot/user.ts
83
bot/user.ts
@@ -1,45 +1,82 @@
|
|||||||
import { redis } from "bun";
|
import { redis } from "bun";
|
||||||
import { chatterApi } from ".";
|
import { chatterApi } from ".";
|
||||||
|
import { HelixUser } from "@twurple/api"
|
||||||
|
|
||||||
|
const EXPIRETIME = 60 * 15 // 15 minutes
|
||||||
|
|
||||||
export class User {
|
export class User {
|
||||||
constructor(username: string) {
|
public username: string | undefined;
|
||||||
this.username = username;
|
public id: string | undefined;
|
||||||
};
|
public displayName: string | undefined;
|
||||||
|
|
||||||
public username: string;
|
static async initUsername(username: string): Promise<User | null> {
|
||||||
public id: string | undefined | null; // The null here and below serves the function to make typescript shut the fuck up
|
const userObj = new User();
|
||||||
public displayName: string | undefined | null;
|
userObj.username = username;
|
||||||
|
const userid = await redis.get(`userlookup:${username}`);
|
||||||
static async init(username: string): Promise<User | null> {
|
if (!userid) {
|
||||||
const userObj = new User(username);
|
const userdata = await chatterApi.users.getUserByName(username);
|
||||||
const cachedata = await redis.exists(`user:${username}`);
|
if (!userdata) return null;
|
||||||
if (!cachedata) {
|
userObj._setCache(userdata);
|
||||||
const twitchdata = await chatterApi.users.getUserByName(username!);
|
userObj.id = userdata.id;
|
||||||
if (!twitchdata) return null; // User does not exist in redis and twitch api can't get them: return null
|
userObj.displayName = userdata.displayName;
|
||||||
await redis.set(`user:${username}:id`, twitchdata.id);
|
} else {
|
||||||
await redis.set(`user:${username}:displayName`, twitchdata.displayName);
|
const displayname = await redis.get(`user:${userid}:displayName`);
|
||||||
await redis.set(`user:${username}:itemlock`, '0');
|
userObj._setExpire(userid, username);
|
||||||
|
userObj.id = userid;
|
||||||
|
userObj.displayName = displayname!;
|
||||||
};
|
};
|
||||||
await userObj._setOptions();
|
|
||||||
return userObj;
|
return userObj;
|
||||||
};
|
};
|
||||||
|
|
||||||
private async _setOptions(): Promise<void> {
|
static async initUserId(userId: string): Promise<User | null> {
|
||||||
this.id = await redis.get(`user:${this.username}:id`);
|
const userObj = new User();
|
||||||
this.displayName = await redis.get(`user:${this.username}:displayName`);
|
userObj.id = userId;
|
||||||
|
if (!await redis.exists(`user:${userId}:displayName`)) {
|
||||||
|
const userdata = await chatterApi.users.getUserById(userId);
|
||||||
|
if (!userdata) return null;
|
||||||
|
userObj._setCache(userdata);
|
||||||
|
userObj.username = userdata.name;
|
||||||
|
userObj.displayName = userdata.displayName;
|
||||||
|
} else {
|
||||||
|
const [displayName, username] = await Promise.all([
|
||||||
|
redis.get(`user:${userId}:displayName`),
|
||||||
|
redis.get(`user:${userId}:username`)
|
||||||
|
]);
|
||||||
|
userObj._setExpire(userId, username!);
|
||||||
|
userObj.username = username!;
|
||||||
|
userObj.displayName = displayName!;
|
||||||
|
};
|
||||||
|
return userObj;
|
||||||
|
};
|
||||||
|
|
||||||
|
private async _setCache(userdata: HelixUser) {
|
||||||
|
await Promise.all([
|
||||||
|
redis.set(`user:${userdata.id}:displayName`, userdata.displayName),
|
||||||
|
redis.set(`user:${userdata.id}:username`, userdata.name),
|
||||||
|
redis.set(`userlookup:${userdata.name}`, userdata.id)
|
||||||
|
]);
|
||||||
|
await this._setExpire(userdata.id, userdata.name);
|
||||||
|
};
|
||||||
|
|
||||||
|
private async _setExpire(userId: string, userName: string) {
|
||||||
|
await Promise.all([
|
||||||
|
redis.expire(`user:${userId}:displayName`, EXPIRETIME),
|
||||||
|
redis.expire(`user:${userId}:username`, EXPIRETIME),
|
||||||
|
redis.expire(`userlookup:${userName}`, EXPIRETIME)
|
||||||
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
public async itemLock(): Promise<boolean> {
|
public async itemLock(): Promise<boolean> {
|
||||||
const lock = await redis.get(`user:${this.username}:itemlock`);
|
const lock = await redis.get(`user:${this.id}:itemlock`);
|
||||||
if (lock === '0') return false;
|
if (lock === '0') return false;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
public async setLock(): Promise<void> {
|
public async setLock(): Promise<void> {
|
||||||
await redis.set(`user:${this.username}:itemlock`, '1');
|
await redis.set(`user:${this.id}:itemlock`, '1');
|
||||||
};
|
};
|
||||||
|
|
||||||
public async clearLock(): Promise<void> {
|
public async clearLock(): Promise<void> {
|
||||||
await redis.set(`user:${this.username}:itemlock`, '0');
|
await redis.set(`user:${this.id}:itemlock`, '0');
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user