Merge pull request #297 from Scrumplex/feat/detect-pk
This commit is contained in:
commit
d05e1cbc5e
6 changed files with 138 additions and 12 deletions
|
@ -37,7 +37,7 @@
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
${config.pre-commit.installationScript}
|
${config.pre-commit.installationScript}
|
||||||
'';
|
'';
|
||||||
packages = with pkgs; [nodePackages.pnpm];
|
packages = with pkgs; [nodePackages.pnpm redis];
|
||||||
};
|
};
|
||||||
formatter = pkgs.alejandra;
|
formatter = pkgs.alejandra;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
"discord.js": "14.14.1",
|
"discord.js": "14.14.1",
|
||||||
"just-random": "3.2.0",
|
"just-random": "3.2.0",
|
||||||
"kleur": "4.1.5",
|
"kleur": "4.1.5",
|
||||||
|
"redis": "4.6.10",
|
||||||
"tsx": "4.1.1"
|
"tsx": "4.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
74
pnpm-lock.yaml
generated
74
pnpm-lock.yaml
generated
|
@ -17,6 +17,9 @@ dependencies:
|
||||||
kleur:
|
kleur:
|
||||||
specifier: 4.1.5
|
specifier: 4.1.5
|
||||||
version: 4.1.5
|
version: 4.1.5
|
||||||
|
redis:
|
||||||
|
specifier: 4.6.10
|
||||||
|
version: 4.6.10
|
||||||
tsx:
|
tsx:
|
||||||
specifier: 4.1.1
|
specifier: 4.1.1
|
||||||
version: 4.1.1
|
version: 4.1.1
|
||||||
|
@ -403,6 +406,55 @@ packages:
|
||||||
fastq: 1.15.0
|
fastq: 1.15.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@redis/bloom@1.2.0(@redis/client@1.5.11):
|
||||||
|
resolution: {integrity: sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@redis/client': ^1.0.0
|
||||||
|
dependencies:
|
||||||
|
'@redis/client': 1.5.11
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@redis/client@1.5.11:
|
||||||
|
resolution: {integrity: sha512-cV7yHcOAtNQ5x/yQl7Yw1xf53kO0FNDTdDU6bFIMbW6ljB7U7ns0YRM+QIkpoqTAt6zK5k9Fq0QWlUbLcq9AvA==}
|
||||||
|
engines: {node: '>=14'}
|
||||||
|
dependencies:
|
||||||
|
cluster-key-slot: 1.1.2
|
||||||
|
generic-pool: 3.9.0
|
||||||
|
yallist: 4.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@redis/graph@1.1.0(@redis/client@1.5.11):
|
||||||
|
resolution: {integrity: sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@redis/client': ^1.0.0
|
||||||
|
dependencies:
|
||||||
|
'@redis/client': 1.5.11
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@redis/json@1.0.6(@redis/client@1.5.11):
|
||||||
|
resolution: {integrity: sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@redis/client': ^1.0.0
|
||||||
|
dependencies:
|
||||||
|
'@redis/client': 1.5.11
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@redis/search@1.1.5(@redis/client@1.5.11):
|
||||||
|
resolution: {integrity: sha512-hPP8w7GfGsbtYEJdn4n7nXa6xt6hVZnnDktKW4ArMaFQ/m/aR7eFvsLQmG/mn1Upq99btPJk+F27IQ2dYpCoUg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@redis/client': ^1.0.0
|
||||||
|
dependencies:
|
||||||
|
'@redis/client': 1.5.11
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@redis/time-series@1.0.5(@redis/client@1.5.11):
|
||||||
|
resolution: {integrity: sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@redis/client': ^1.0.0
|
||||||
|
dependencies:
|
||||||
|
'@redis/client': 1.5.11
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@sapphire/async-queue@1.5.0:
|
/@sapphire/async-queue@1.5.0:
|
||||||
resolution: {integrity: sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==}
|
resolution: {integrity: sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==}
|
||||||
engines: {node: '>=v14.0.0', npm: '>=7.0.0'}
|
engines: {node: '>=v14.0.0', npm: '>=7.0.0'}
|
||||||
|
@ -665,6 +717,11 @@ packages:
|
||||||
supports-color: 7.2.0
|
supports-color: 7.2.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/cluster-key-slot@1.1.2:
|
||||||
|
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/color-convert@2.0.1:
|
/color-convert@2.0.1:
|
||||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||||
engines: {node: '>=7.0.0'}
|
engines: {node: '>=7.0.0'}
|
||||||
|
@ -966,6 +1023,11 @@ packages:
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
/generic-pool@3.9.0:
|
||||||
|
resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==}
|
||||||
|
engines: {node: '>= 4'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/get-tsconfig@4.7.2:
|
/get-tsconfig@4.7.2:
|
||||||
resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==}
|
resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -1281,6 +1343,17 @@ packages:
|
||||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/redis@4.6.10:
|
||||||
|
resolution: {integrity: sha512-mmbyhuKgDiJ5TWUhiKhBssz+mjsuSI/lSZNPI9QvZOYzWvYGejtb+W3RlDDf8LD6Bdl5/mZeG8O1feUGhXTxEg==}
|
||||||
|
dependencies:
|
||||||
|
'@redis/bloom': 1.2.0(@redis/client@1.5.11)
|
||||||
|
'@redis/client': 1.5.11
|
||||||
|
'@redis/graph': 1.1.0(@redis/client@1.5.11)
|
||||||
|
'@redis/json': 1.0.6(@redis/client@1.5.11)
|
||||||
|
'@redis/search': 1.1.5(@redis/client@1.5.11)
|
||||||
|
'@redis/time-series': 1.0.5(@redis/client@1.5.11)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/resolve-from@4.0.0:
|
/resolve-from@4.0.0:
|
||||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
@ -1482,7 +1555,6 @@ packages:
|
||||||
|
|
||||||
/yallist@4.0.0:
|
/yallist@4.0.0:
|
||||||
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/yocto-queue@0.1.0:
|
/yocto-queue@0.1.0:
|
||||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||||
|
|
23
src/index.ts
23
src/index.ts
|
@ -9,6 +9,11 @@ import {
|
||||||
Events,
|
Events,
|
||||||
} 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 +31,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: [
|
||||||
|
@ -89,7 +98,16 @@ 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 () => {
|
||||||
|
const pkMessage = await fetchPluralKitMessage(e);
|
||||||
|
if (pkMessage !== null) storeUserPlurality(pkMessage.sender);
|
||||||
|
}, 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 +214,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
22
src/storage.ts
Normal 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();
|
||||||
|
};
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue