feat: store pluralkit users in redis

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
This commit is contained in:
Sefa Eyeoglu 2023-11-16 23:06:32 +01:00
parent c29d5dfb8d
commit e6337cf6bd
No known key found for this signature in database
GPG key ID: E13DFD4B47127951
3 changed files with 68 additions and 10 deletions

View file

@ -7,8 +7,14 @@ import {
PermissionFlagsBits, PermissionFlagsBits,
ChannelType, ChannelType,
Events, Events,
Message,
} from 'discord.js'; } from 'discord.js';
import { reuploadCommands } from './_reupload'; import { reuploadCommands } from './_reupload';
import {
connect as connectStorage,
isUserPlural,
storeUserPlurality,
} from './storage';
import * as BuildConfig from './constants'; import * as BuildConfig from './constants';
import { parseLog } from './logs'; import { parseLog } from './logs';
@ -26,7 +32,11 @@ import { sayCommand } from './commands/say';
import random from 'just-random'; import random from 'just-random';
import { green, bold, yellow, cyan } from 'kleur/colors'; import { green, bold, yellow, cyan } from 'kleur/colors';
import 'dotenv/config'; import 'dotenv/config';
import { proxied } from './utils/pluralKit'; import {
fetchPluralKitMessage,
isMessageProxied,
pkDelay,
} from './utils/pluralKit';
const client = new Client({ const client = new Client({
intents: [ intents: [
@ -42,6 +52,11 @@ const client = new Client({
partials: [Partials.Channel], partials: [Partials.Channel],
}); });
const handleWebhookMessage = async (e: Message<boolean>) => {
const pkMessage = await fetchPluralKitMessage(e);
if (pkMessage !== null) storeUserPlurality(pkMessage.sender);
};
client.once('ready', async () => { client.once('ready', async () => {
console.log(green('Discord bot ready!')); console.log(green('Discord bot ready!'));
@ -89,7 +104,15 @@ client.once('ready', async () => {
if (e.author === client.user) return; if (e.author === client.user) return;
if (await proxied(e)) return; if (e.webhookId !== null) {
// defer PK detection
setTimeout(async () => {
await handleWebhookMessage(e);
}, pkDelay);
}
if ((await isUserPlural(e.author.id)) && (await isMessageProxied(e)))
return;
if (e.cleanContent.match(BuildConfig.ETA_REGEX)) { if (e.cleanContent.match(BuildConfig.ETA_REGEX)) {
await e.reply( await e.reply(
@ -196,6 +219,7 @@ client.on(Events.ThreadCreate, async (channel) => {
reuploadCommands() reuploadCommands()
.then(() => { .then(() => {
connectStorage();
client.login(process.env.DISCORD_TOKEN); client.login(process.env.DISCORD_TOKEN);
}) })
.catch((e) => { .catch((e) => {

22
src/storage.ts Normal file
View file

@ -0,0 +1,22 @@
import { createClient } from 'redis';
export const client = createClient({
url: process.env.REDIS_URL || 'redis://localhost:6379',
});
export const storeUserPlurality = async (userId: string) => {
// Just store some value. We only care about the presence of this key
await client
.multi()
.set(`user:${userId}:pk`, '0')
.expire(`user:${userId}:pk`, 7 * 24 * 60 * 60)
.exec();
};
export const isUserPlural = async (userId: string) => {
return (await client.exists(`user:${userId}:pk`)) > 0;
};
export const connect = () => {
client.connect();
};

View file

@ -1,10 +1,22 @@
import { Message } from "discord.js"; import { Message } from 'discord.js';
export async function proxied(message: Message): Promise<boolean> { interface PkMessage {
if (message.webhookId !== null) sender: string;
return false; }
await new Promise(resolve => setTimeout(resolve, 300)); export const pkDelay = 500;
const response = await fetch(`https://api.pluralkit.me/v2/messages/${message.id}`);
return response.ok; export async function fetchPluralKitMessage(message: Message) {
const response = await fetch(
`https://api.pluralkit.me/v2/messages/${message.id}`
);
if (!response.ok) return null;
return (await response.json()) as PkMessage;
}
export async function isMessageProxied(message: Message) {
await new Promise((resolve) => setTimeout(resolve, pkDelay));
return (await fetchPluralKitMessage(message)) !== null;
} }