Skip to content

Commit b4faf1a

Browse files
committed
feat: morritz
1 parent f907301 commit b4faf1a

File tree

7 files changed

+1365
-60
lines changed

7 files changed

+1365
-60
lines changed

src/commands/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { InvalidUsageError } from '../types';
88
import { addKarma, karma, KARMA_REGEX } from './karma';
99
import co from './co';
1010
import execute from './execute';
11-
import grzesiu from './grzesiu';
11+
import { grzesiu, morritz } from './kocopoly';
1212
import link from './link';
1313
import m1 from './m1';
1414
import markdown from './markdown';
@@ -46,6 +46,7 @@ const allCommands = [
4646
markdown,
4747
mdn,
4848
mongodb,
49+
morritz,
4950
mydevil,
5051
npm,
5152
odpowiedz,

src/commands/kocopoly.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { Command, CommandWithArgs } from '../types';
2+
3+
import Fsp from 'fs/promises';
4+
import Path from 'path';
5+
import { getRandomKocopolyAnswers } from './kocopoly/kocopolyUtils';
6+
import { capitalizeFirst, wait } from '../utils';
7+
8+
const COOLDOWN = 20;
9+
const KOCOPOLY_DELAY = 1500;
10+
11+
const kocopolyExecute =
12+
(kocopolyFilename: string, kocopolyName: string): CommandWithArgs['execute'] =>
13+
async (msg, args) => {
14+
const username = (msg.member?.displayName || msg.author.username).trim().split(/\s/)[0];
15+
const question = args.join(' ');
16+
17+
const kocopolyJson = JSON.parse(
18+
await Fsp.readFile(Path.join(__dirname, '..', kocopolyFilename), 'utf-8'),
19+
) as string[];
20+
21+
const messages = await getRandomKocopolyAnswers(username, question, kocopolyJson, kocopolyName);
22+
23+
if (!messages.length) {
24+
return msg.channel.send(
25+
`Niestety, ${capitalizeFirst(kocopolyName)} nie miał nic do powiedzenia!`,
26+
);
27+
}
28+
29+
return messages.reduce(async (acc, message) => {
30+
await acc;
31+
await msg.channel.send(`_${message}_`);
32+
await wait(200 + Math.random() * KOCOPOLY_DELAY);
33+
return null;
34+
}, Promise.resolve(null));
35+
};
36+
37+
export const grzesiu: Command = {
38+
name: 'grzesiu',
39+
description: 'Użyj tego, gdy tęsknisz za Grzesiem',
40+
args: 'optional',
41+
cooldown: COOLDOWN,
42+
execute: kocopolyExecute('grzes.json', 'grzegorz'),
43+
};
44+
45+
export const morritz: Command = {
46+
name: 'morritz',
47+
description: 'Użyj tego, gdy tęsknisz za Morritzem',
48+
args: 'optional',
49+
cooldown: COOLDOWN,
50+
execute: kocopolyExecute('morritz.json', 'morritz'),
51+
};

src/commands/grzesiu.ts renamed to src/commands/kocopoly/kocopolyUtils.ts

Lines changed: 32 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,33 @@
1-
import { Command } from '../types';
21
import { Configuration, OpenAIApi } from 'openai';
3-
import Fsp from 'fs/promises';
4-
import Path from 'path';
52
import Natural from 'natural';
63

7-
const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
8-
94
const configuration = new Configuration({
105
apiKey: process.env.OPENAI_API_KEY,
116
});
127
const openai = new OpenAIApi(configuration);
138

149
const MAX_TOKENS = 2049;
1510
const RESPONSE_TOKENS = 64;
11+
1612
const MAX_GENERATED_CONTENT_LEN = Math.floor((MAX_TOKENS - RESPONSE_TOKENS) / 2); // make it cheaper
1713
const BANNED_PATTERNS = /[`\[\]{}\(\)]|http/g;
18-
const COOLDOWN = 20;
19-
const GRZESIU_DELAY = 1500;
20-
const GRZESIU_NAME = 'grzegorz';
21-
22-
const grzesiu: Command = {
23-
name: 'grzesiu',
24-
description: 'Użyj tego, gdy tęsknisz za Grzesiem',
25-
args: 'optional',
26-
cooldown: COOLDOWN,
27-
async execute(msg, args) {
28-
const username = (msg.member?.displayName || msg.author.username).trim().split(/\s/)[0];
29-
const question = args.join(' ');
30-
31-
const grzesJson = JSON.parse(
32-
await Fsp.readFile(Path.join(__dirname, '..', 'grzes.json'), 'utf-8'),
33-
) as string[];
34-
35-
const generators = {
36-
getGrzesiuAnswerFromOpenAI,
37-
getRandomGrzesiuAnswers,
38-
};
39-
40-
const messages = await generators.getRandomGrzesiuAnswers(username, question, grzesJson);
41-
42-
if (!messages.length) {
43-
return msg.channel.send(`Niestety, Grzesiu nie miał nic do powiedzenia!`);
44-
}
45-
46-
return messages.reduce(async (acc, message) => {
47-
await acc;
48-
await msg.channel.send(`_${message}_`);
49-
await wait(200 + Math.random() * GRZESIU_DELAY);
50-
return null;
51-
}, Promise.resolve(null));
52-
},
53-
};
54-
55-
export default grzesiu;
5614

5715
const getRandomInt = (len: number) => Math.floor(Math.random() * len);
5816

59-
interface GrzesiuGenerator {
60-
(username: string, question: string, grzesJson: string[]): Promise<string[]>;
17+
interface KocopolyGenerator {
18+
(username: string, question: string, kocopolyJson: string[], kocopolyName: string): Promise<
19+
string[]
20+
>;
6121
}
6222

6323
// random
64-
const getRandomGrzesiuAnswers: GrzesiuGenerator = async (_username, question, grzesJson) => {
65-
const g = grzesJson
24+
export const getRandomKocopolyAnswers: KocopolyGenerator = async (
25+
_username,
26+
question,
27+
kocopolyJson,
28+
_kocopolyName,
29+
) => {
30+
const g = kocopolyJson
6631
.map((l) => l.trim())
6732
.filter((line) => !BANNED_PATTERNS.test(line) && line.length > 0);
6833

@@ -92,8 +57,13 @@ const getRandomGrzesiuAnswers: GrzesiuGenerator = async (_username, question, gr
9257
};
9358

9459
// openAI
95-
const getGrzesiuAnswerFromOpenAI: GrzesiuGenerator = async (username, question, grzesJson) => {
96-
const prompt = await generateGrzesiuPrompt(username, question, grzesJson);
60+
export const getKocopolyAnswerFromOpenAI: KocopolyGenerator = async (
61+
username,
62+
question,
63+
kocopolyJson,
64+
kocopolyName,
65+
) => {
66+
const prompt = await generateKocopolyPrompt(username, question, kocopolyJson, kocopolyName);
9767

9868
const engine = 'text-davinci-001';
9969
// const engine = 'text-babbage-001';
@@ -116,8 +86,8 @@ const getGrzesiuAnswerFromOpenAI: GrzesiuGenerator = async (username, question,
11686
const messages = response.data.choices[0].text
11787
.split('\n')
11888
.map((l) => l.trim())
119-
.filter((l) => l.startsWith(`${GRZESIU_NAME}:`))
120-
.flatMap((l) => l.split(`${GRZESIU_NAME}:`))
89+
.filter((l) => l.startsWith(`${kocopolyName}:`))
90+
.flatMap((l) => l.split(`${kocopolyName}:`))
12191
.filter((l) => l.trim().length > 0);
12292
return messages;
12393
};
@@ -128,21 +98,26 @@ const getRandomIndices = (num: number, max: number) => {
12898
return [...set];
12999
};
130100

131-
const generateGrzesiuPrompt = async (username: string, question: string, grzesJson: string[]) => {
132-
const indices = getRandomIndices(100, grzesJson.length);
133-
const uniqueLines = [...new Set(indices.map((idx) => grzesJson[idx].trim()))].filter(
101+
const generateKocopolyPrompt = async (
102+
username: string,
103+
question: string,
104+
kocopolyJson: string[],
105+
kocopolyName: string,
106+
) => {
107+
const indices = getRandomIndices(100, kocopolyJson.length);
108+
const uniqueLines = [...new Set(indices.map((idx) => kocopolyJson[idx].trim()))].filter(
134109
(line) => !BANNED_PATTERNS.test(line) && line.length > 0,
135110
);
136111

137112
const getFullConvo = (txt: string, username: string, question: string) => {
138113
if (question) {
139-
return `${txt.trim()}\n${username}: ${question}\n${GRZESIU_NAME}:`;
114+
return `${txt.trim()}\n${username}: ${question}\n${kocopolyName}:`;
140115
}
141-
return `${txt.trim()}\n${GRZESIU_NAME}:`;
116+
return `${txt.trim()}\n${kocopolyName}:`;
142117
};
143118

144119
const txt = uniqueLines.reduce((txt, line) => {
145-
const newTxt = txt + `${GRZESIU_NAME}: ` + line + '\n';
120+
const newTxt = txt + `${kocopolyName}: ` + line + '\n';
146121
const fullConvo = getFullConvo(newTxt, username, question);
147122
return fullConvo.length <= MAX_GENERATED_CONTENT_LEN ? newTxt : txt;
148123
}, '');

src/commands/odpowiedz.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ const odpowiedz: Command = {
2828
description: 'Pomoże ci wybrać odpowiedź',
2929
args: 'prohibited',
3030
execute(msg) {
31-
// Really randomize the answer
3231
const randomAnswer = randomizeArray(ANSWERS)[0];
3332
return msg.channel.send(randomAnswer);
3433
},

0 commit comments

Comments
 (0)