windsor-bot 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -0
- package/SPEC.md +179 -0
- package/assets/pokemon-sprites/1.png +0 -0
- package/assets/pokemon-sprites/10.png +0 -0
- package/assets/pokemon-sprites/100.png +0 -0
- package/assets/pokemon-sprites/101.png +0 -0
- package/assets/pokemon-sprites/102.png +0 -0
- package/assets/pokemon-sprites/103.png +0 -0
- package/assets/pokemon-sprites/104.png +0 -0
- package/assets/pokemon-sprites/105.png +0 -0
- package/assets/pokemon-sprites/106.png +0 -0
- package/assets/pokemon-sprites/107.png +0 -0
- package/assets/pokemon-sprites/108.png +0 -0
- package/assets/pokemon-sprites/109.png +0 -0
- package/assets/pokemon-sprites/11.png +0 -0
- package/assets/pokemon-sprites/110.png +0 -0
- package/assets/pokemon-sprites/111.png +0 -0
- package/assets/pokemon-sprites/112.png +0 -0
- package/assets/pokemon-sprites/113.png +0 -0
- package/assets/pokemon-sprites/114.png +0 -0
- package/assets/pokemon-sprites/115.png +0 -0
- package/assets/pokemon-sprites/116.png +0 -0
- package/assets/pokemon-sprites/117.png +0 -0
- package/assets/pokemon-sprites/118.png +0 -0
- package/assets/pokemon-sprites/119.png +0 -0
- package/assets/pokemon-sprites/12.png +0 -0
- package/assets/pokemon-sprites/120.png +0 -0
- package/assets/pokemon-sprites/121.png +0 -0
- package/assets/pokemon-sprites/122.png +0 -0
- package/assets/pokemon-sprites/123.png +0 -0
- package/assets/pokemon-sprites/124.png +0 -0
- package/assets/pokemon-sprites/125.png +0 -0
- package/assets/pokemon-sprites/126.png +0 -0
- package/assets/pokemon-sprites/127.png +0 -0
- package/assets/pokemon-sprites/128.png +0 -0
- package/assets/pokemon-sprites/129.png +0 -0
- package/assets/pokemon-sprites/13.png +0 -0
- package/assets/pokemon-sprites/130.png +0 -0
- package/assets/pokemon-sprites/131.png +0 -0
- package/assets/pokemon-sprites/132.png +0 -0
- package/assets/pokemon-sprites/133.png +0 -0
- package/assets/pokemon-sprites/134.png +0 -0
- package/assets/pokemon-sprites/135.png +0 -0
- package/assets/pokemon-sprites/136.png +0 -0
- package/assets/pokemon-sprites/137.png +0 -0
- package/assets/pokemon-sprites/138.png +0 -0
- package/assets/pokemon-sprites/139.png +0 -0
- package/assets/pokemon-sprites/14.png +0 -0
- package/assets/pokemon-sprites/140.png +0 -0
- package/assets/pokemon-sprites/141.png +0 -0
- package/assets/pokemon-sprites/142.png +0 -0
- package/assets/pokemon-sprites/143.png +0 -0
- package/assets/pokemon-sprites/144.png +0 -0
- package/assets/pokemon-sprites/145.png +0 -0
- package/assets/pokemon-sprites/146.png +0 -0
- package/assets/pokemon-sprites/147.png +0 -0
- package/assets/pokemon-sprites/148.png +0 -0
- package/assets/pokemon-sprites/149.png +0 -0
- package/assets/pokemon-sprites/15.png +0 -0
- package/assets/pokemon-sprites/150.png +0 -0
- package/assets/pokemon-sprites/151.png +0 -0
- package/assets/pokemon-sprites/16.png +0 -0
- package/assets/pokemon-sprites/17.png +0 -0
- package/assets/pokemon-sprites/18.png +0 -0
- package/assets/pokemon-sprites/19.png +0 -0
- package/assets/pokemon-sprites/2.png +0 -0
- package/assets/pokemon-sprites/20.png +0 -0
- package/assets/pokemon-sprites/21.png +0 -0
- package/assets/pokemon-sprites/22.png +0 -0
- package/assets/pokemon-sprites/23.png +0 -0
- package/assets/pokemon-sprites/24.png +0 -0
- package/assets/pokemon-sprites/25.png +0 -0
- package/assets/pokemon-sprites/26.png +0 -0
- package/assets/pokemon-sprites/27.png +0 -0
- package/assets/pokemon-sprites/28.png +0 -0
- package/assets/pokemon-sprites/29.png +0 -0
- package/assets/pokemon-sprites/3.png +0 -0
- package/assets/pokemon-sprites/30.png +0 -0
- package/assets/pokemon-sprites/31.png +0 -0
- package/assets/pokemon-sprites/32.png +0 -0
- package/assets/pokemon-sprites/33.png +0 -0
- package/assets/pokemon-sprites/34.png +0 -0
- package/assets/pokemon-sprites/35.png +0 -0
- package/assets/pokemon-sprites/36.png +0 -0
- package/assets/pokemon-sprites/37.png +0 -0
- package/assets/pokemon-sprites/38.png +0 -0
- package/assets/pokemon-sprites/39.png +0 -0
- package/assets/pokemon-sprites/4.png +0 -0
- package/assets/pokemon-sprites/40.png +0 -0
- package/assets/pokemon-sprites/41.png +0 -0
- package/assets/pokemon-sprites/42.png +0 -0
- package/assets/pokemon-sprites/43.png +0 -0
- package/assets/pokemon-sprites/44.png +0 -0
- package/assets/pokemon-sprites/45.png +0 -0
- package/assets/pokemon-sprites/46.png +0 -0
- package/assets/pokemon-sprites/47.png +0 -0
- package/assets/pokemon-sprites/48.png +0 -0
- package/assets/pokemon-sprites/49.png +0 -0
- package/assets/pokemon-sprites/5.png +0 -0
- package/assets/pokemon-sprites/50.png +0 -0
- package/assets/pokemon-sprites/51.png +0 -0
- package/assets/pokemon-sprites/52.png +0 -0
- package/assets/pokemon-sprites/53.png +0 -0
- package/assets/pokemon-sprites/54.png +0 -0
- package/assets/pokemon-sprites/55.png +0 -0
- package/assets/pokemon-sprites/56.png +0 -0
- package/assets/pokemon-sprites/57.png +0 -0
- package/assets/pokemon-sprites/58.png +0 -0
- package/assets/pokemon-sprites/59.png +0 -0
- package/assets/pokemon-sprites/6.png +0 -0
- package/assets/pokemon-sprites/60.png +0 -0
- package/assets/pokemon-sprites/61.png +0 -0
- package/assets/pokemon-sprites/62.png +0 -0
- package/assets/pokemon-sprites/63.png +0 -0
- package/assets/pokemon-sprites/64.png +0 -0
- package/assets/pokemon-sprites/65.png +0 -0
- package/assets/pokemon-sprites/66.png +0 -0
- package/assets/pokemon-sprites/67.png +0 -0
- package/assets/pokemon-sprites/68.png +0 -0
- package/assets/pokemon-sprites/69.png +0 -0
- package/assets/pokemon-sprites/7.png +0 -0
- package/assets/pokemon-sprites/70.png +0 -0
- package/assets/pokemon-sprites/71.png +0 -0
- package/assets/pokemon-sprites/72.png +0 -0
- package/assets/pokemon-sprites/73.png +0 -0
- package/assets/pokemon-sprites/74.png +0 -0
- package/assets/pokemon-sprites/75.png +0 -0
- package/assets/pokemon-sprites/76.png +0 -0
- package/assets/pokemon-sprites/77.png +0 -0
- package/assets/pokemon-sprites/78.png +0 -0
- package/assets/pokemon-sprites/79.png +0 -0
- package/assets/pokemon-sprites/8.png +0 -0
- package/assets/pokemon-sprites/80.png +0 -0
- package/assets/pokemon-sprites/81.png +0 -0
- package/assets/pokemon-sprites/82.png +0 -0
- package/assets/pokemon-sprites/83.png +0 -0
- package/assets/pokemon-sprites/84.png +0 -0
- package/assets/pokemon-sprites/85.png +0 -0
- package/assets/pokemon-sprites/86.png +0 -0
- package/assets/pokemon-sprites/87.png +0 -0
- package/assets/pokemon-sprites/88.png +0 -0
- package/assets/pokemon-sprites/89.png +0 -0
- package/assets/pokemon-sprites/9.png +0 -0
- package/assets/pokemon-sprites/90.png +0 -0
- package/assets/pokemon-sprites/91.png +0 -0
- package/assets/pokemon-sprites/92.png +0 -0
- package/assets/pokemon-sprites/93.png +0 -0
- package/assets/pokemon-sprites/94.png +0 -0
- package/assets/pokemon-sprites/95.png +0 -0
- package/assets/pokemon-sprites/96.png +0 -0
- package/assets/pokemon-sprites/97.png +0 -0
- package/assets/pokemon-sprites/98.png +0 -0
- package/assets/pokemon-sprites/99.png +0 -0
- package/dist/ai.js +193 -0
- package/dist/bot.d.ts +22 -0
- package/dist/bot.d.ts.map +1 -0
- package/dist/bot.js +547 -0
- package/dist/bot.js.map +1 -0
- package/dist/commands/debug-fail.js +8 -0
- package/dist/commands/hello-world.js +12 -0
- package/dist/commands/hello.d.ts +3 -0
- package/dist/commands/hello.d.ts.map +1 -0
- package/dist/commands/hello.js +8 -0
- package/dist/commands/hello.js.map +1 -0
- package/dist/commands/index.d.ts +3 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +12 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/pokemon.js +132 -0
- package/dist/commands/print.d.ts +9 -0
- package/dist/commands/print.d.ts.map +1 -0
- package/dist/commands/print.js +46 -0
- package/dist/commands/print.js.map +1 -0
- package/dist/commands/sudoku.js +79 -0
- package/dist/commands/util.js +13 -0
- package/dist/commands/wordsearch.js +109 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +149 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +85 -0
- package/dist/index.js.map +1 -0
- package/dist/printer.js +245 -0
- package/dist/printing/cups.js +89 -0
- package/dist/printing/escp.js +147 -0
- package/dist/printing/imagefeed.js +212 -0
- package/dist/printing/index.js +54 -0
- package/dist/reactions.js +5 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +312 -0
- package/dist/server.js.map +1 -0
- package/dist/tests/config.test.js +78 -0
- package/dist/tests/urls.test.js +54 -0
- package/dist/types.d.ts +55 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/web/app.js +325 -0
- package/package.json +45 -0
- package/scripts/download-pokemon-sprites.mjs +38 -0
- package/src/ai.ts +214 -0
- package/src/bot.ts +657 -0
- package/src/commands/debug-fail.ts +11 -0
- package/src/commands/hello-world.ts +15 -0
- package/src/commands/index.ts +35 -0
- package/src/commands/pokemon.ts +146 -0
- package/src/commands/sudoku.ts +94 -0
- package/src/commands/util.ts +14 -0
- package/src/commands/wordsearch.ts +118 -0
- package/src/config.ts +166 -0
- package/src/index.ts +98 -0
- package/src/printer.ts +268 -0
- package/src/printing/cups.ts +104 -0
- package/src/printing/escp.ts +158 -0
- package/src/printing/imagefeed.ts +246 -0
- package/src/printing/index.ts +63 -0
- package/src/reactions.ts +6 -0
- package/src/server.ts +355 -0
- package/src/tests/config.test.ts +88 -0
- package/src/tests/urls.test.ts +64 -0
- package/src/types.ts +120 -0
- package/src/web/app.tsx +690 -0
- package/tsconfig.json +25 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/ai.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
import { mkdir, writeFile, readFile, access } from 'fs/promises';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import OpenAI from 'openai';
|
|
5
|
+
import { zodResponseFormat } from 'openai/helpers/zod.js';
|
|
6
|
+
import { z } from 'zod/v4';
|
|
7
|
+
import { getCurrentConfig, updateConfig } from './config.js';
|
|
8
|
+
import { logEvent } from './server.js';
|
|
9
|
+
const MODEL = 'gpt-5.4-nano';
|
|
10
|
+
const IMAGE_MODEL = 'gpt-image-1-mini';
|
|
11
|
+
const TOKEN_LIMIT_24H = 200_000;
|
|
12
|
+
export function trackTokenUsage(tokens) {
|
|
13
|
+
const config = getCurrentConfig();
|
|
14
|
+
const entry = { timestamp: new Date().toISOString(), tokens };
|
|
15
|
+
const usage = [...config.tokenUsage, entry];
|
|
16
|
+
// Keep only entries from the last 24 hours
|
|
17
|
+
const cutoff = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
|
|
18
|
+
const pruned = usage.filter(e => e.timestamp >= cutoff);
|
|
19
|
+
void updateConfig({ tokenUsage: pruned });
|
|
20
|
+
}
|
|
21
|
+
export function getTokenUsage24h() {
|
|
22
|
+
const config = getCurrentConfig();
|
|
23
|
+
const cutoff = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
|
|
24
|
+
return config.tokenUsage
|
|
25
|
+
.filter(e => e.timestamp >= cutoff)
|
|
26
|
+
.reduce((sum, e) => sum + e.tokens, 0);
|
|
27
|
+
}
|
|
28
|
+
export async function isOverTokenLimit() {
|
|
29
|
+
const used = getTokenUsage24h();
|
|
30
|
+
if (used >= TOKEN_LIMIT_24H) {
|
|
31
|
+
logEvent('error', `Token limit exceeded (${used} tokens in last 24h). Deleting OpenAI key.`);
|
|
32
|
+
const config = getCurrentConfig();
|
|
33
|
+
const updated = { ...config };
|
|
34
|
+
delete updated.openaiKey;
|
|
35
|
+
await updateConfig(updated);
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
function getClient() {
|
|
41
|
+
const key = getCurrentConfig().openaiKey;
|
|
42
|
+
if (!key)
|
|
43
|
+
return null;
|
|
44
|
+
return new OpenAI({ apiKey: key });
|
|
45
|
+
}
|
|
46
|
+
const ScheduleSchema = z.object({
|
|
47
|
+
'message without schedule': z.string(),
|
|
48
|
+
'next occurrence': z.string(),
|
|
49
|
+
});
|
|
50
|
+
function parseOccurrenceDate(str) {
|
|
51
|
+
try {
|
|
52
|
+
const d = new Date(str);
|
|
53
|
+
if (!isNaN(d.getTime()))
|
|
54
|
+
return d;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// ignore
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
export async function parseRecurringSchedule(userMessage, now) {
|
|
62
|
+
const client = getClient();
|
|
63
|
+
if (!client)
|
|
64
|
+
return null;
|
|
65
|
+
if (await isOverTokenLimit())
|
|
66
|
+
return null;
|
|
67
|
+
const nowStr = formatScheduleDate(now);
|
|
68
|
+
const prompt = `The user has asked for a recurring printout. It is currently ${nowStr}. Tell me the next time that I should do this, and what the non-schedule part of the message was (verbatim). If the user didn't specify a time of day, use 8:00 AM. Here's the user's message: ${userMessage}`;
|
|
69
|
+
const results = [];
|
|
70
|
+
const ATTEMPTS = 5;
|
|
71
|
+
for (let i = 0; i < ATTEMPTS; i++) {
|
|
72
|
+
try {
|
|
73
|
+
const completion = await client.chat.completions.create({
|
|
74
|
+
model: MODEL,
|
|
75
|
+
reasoning_effort: 'low',
|
|
76
|
+
messages: [{ role: 'user', content: prompt }],
|
|
77
|
+
response_format: zodResponseFormat(ScheduleSchema, 'schedule'),
|
|
78
|
+
});
|
|
79
|
+
const content = completion.choices[0]?.message?.content;
|
|
80
|
+
if (content) {
|
|
81
|
+
const parsed = ScheduleSchema.parse(JSON.parse(content));
|
|
82
|
+
results.push(parsed);
|
|
83
|
+
const tokens = completion.usage?.total_tokens ?? 0;
|
|
84
|
+
trackTokenUsage(tokens);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
logEvent('error', `Schedule parsing attempt ${i + 1} failed: ${err}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (results.length < 3)
|
|
92
|
+
return null;
|
|
93
|
+
// Majority voting: need 60% consistency for each field
|
|
94
|
+
const messageCounts = new Map();
|
|
95
|
+
const occurrenceCounts = new Map();
|
|
96
|
+
for (const r of results) {
|
|
97
|
+
messageCounts.set(r['message without schedule'], (messageCounts.get(r['message without schedule']) ?? 0) + 1);
|
|
98
|
+
occurrenceCounts.set(r['next occurrence'], (occurrenceCounts.get(r['next occurrence']) ?? 0) + 1);
|
|
99
|
+
}
|
|
100
|
+
const threshold = ATTEMPTS * 0.6;
|
|
101
|
+
let bestMessage = null;
|
|
102
|
+
for (const [msg, count] of messageCounts) {
|
|
103
|
+
if (count >= threshold) {
|
|
104
|
+
bestMessage = msg;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
let bestOccurrence = null;
|
|
109
|
+
for (const [occ, count] of occurrenceCounts) {
|
|
110
|
+
if (count >= threshold) {
|
|
111
|
+
bestOccurrence = occ;
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (!bestMessage || !bestOccurrence)
|
|
116
|
+
return null;
|
|
117
|
+
const occDate = parseOccurrenceDate(bestOccurrence);
|
|
118
|
+
if (!occDate)
|
|
119
|
+
return null;
|
|
120
|
+
return { message: bestMessage, nextOccurrence: occDate };
|
|
121
|
+
}
|
|
122
|
+
function formatScheduleDate(date) {
|
|
123
|
+
const year = date.getFullYear();
|
|
124
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
125
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
126
|
+
let hours = date.getHours();
|
|
127
|
+
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
128
|
+
const ampm = hours >= 12 ? 'PM' : 'AM';
|
|
129
|
+
hours = hours % 12 || 12;
|
|
130
|
+
return `${year}-${month}-${day} ${hours}:${minutes} ${ampm}`;
|
|
131
|
+
}
|
|
132
|
+
export { formatScheduleDate };
|
|
133
|
+
export async function getNextOccurrence(originalMessage, now) {
|
|
134
|
+
const result = await parseRecurringSchedule(originalMessage, now);
|
|
135
|
+
return result ? result.nextOccurrence : null;
|
|
136
|
+
}
|
|
137
|
+
export async function generateIcon(text, cacheDir) {
|
|
138
|
+
const prompt = `Black-on-transparent line drawing icon for the TODO item: "${text}". Do not produce any text. Use big, thick lines. No fine detailing.`;
|
|
139
|
+
const hash = createHash('sha1').update(prompt).digest('hex').slice(0, 9);
|
|
140
|
+
const filename = `${hash}.png`;
|
|
141
|
+
const cachePath = join(cacheDir, filename);
|
|
142
|
+
// Check cache first
|
|
143
|
+
try {
|
|
144
|
+
await access(cachePath);
|
|
145
|
+
return cachePath;
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// not cached
|
|
149
|
+
}
|
|
150
|
+
const client = getClient();
|
|
151
|
+
if (!client)
|
|
152
|
+
return null;
|
|
153
|
+
if (await isOverTokenLimit())
|
|
154
|
+
return null;
|
|
155
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
156
|
+
try {
|
|
157
|
+
const response = await client.images.generate({
|
|
158
|
+
model: IMAGE_MODEL,
|
|
159
|
+
prompt,
|
|
160
|
+
n: 1,
|
|
161
|
+
size: '1024x1024',
|
|
162
|
+
quality: 'low',
|
|
163
|
+
background: 'transparent',
|
|
164
|
+
output_format: 'png',
|
|
165
|
+
});
|
|
166
|
+
const imageData = response.data?.[0];
|
|
167
|
+
if (!imageData)
|
|
168
|
+
throw new Error('No image data returned');
|
|
169
|
+
let imageBuffer;
|
|
170
|
+
if ('b64_json' in imageData && imageData.b64_json) {
|
|
171
|
+
imageBuffer = Buffer.from(imageData.b64_json, 'base64');
|
|
172
|
+
}
|
|
173
|
+
else if ('url' in imageData && imageData.url) {
|
|
174
|
+
const res = await fetch(imageData.url);
|
|
175
|
+
imageBuffer = Buffer.from(await res.arrayBuffer());
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
throw new Error('No image URL or base64 data');
|
|
179
|
+
}
|
|
180
|
+
await mkdir(cacheDir, { recursive: true });
|
|
181
|
+
await writeFile(cachePath, imageBuffer);
|
|
182
|
+
return cachePath;
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
logEvent('error', `Icon generation attempt ${attempt + 1} failed: ${err}`);
|
|
186
|
+
if (attempt === 2)
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
// suppress unused import warning
|
|
193
|
+
void readFile;
|
package/dist/bot.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare class HouseholdBot {
|
|
2
|
+
private readonly client;
|
|
3
|
+
private readonly getConfiguredServerId;
|
|
4
|
+
constructor(getConfiguredServerId: () => string | null);
|
|
5
|
+
start(token: string): Promise<void>;
|
|
6
|
+
private onReady;
|
|
7
|
+
/**
|
|
8
|
+
* On startup, fetch the last 100 messages in every channel that has at
|
|
9
|
+
* least one applicable command and process any that the bot hasn't already
|
|
10
|
+
* reacted to.
|
|
11
|
+
*/
|
|
12
|
+
private scanForUnhandledMessages;
|
|
13
|
+
private getTargetGuilds;
|
|
14
|
+
private onMessage;
|
|
15
|
+
/**
|
|
16
|
+
* Parses and executes the command in `message` if applicable.
|
|
17
|
+
* Returns true if an action was executed, false if skipped (not a command,
|
|
18
|
+
* wrong channel, or already handled).
|
|
19
|
+
*/
|
|
20
|
+
private processMessage;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=bot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"AAeA,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAsB;IAE5D,YAAY,qBAAqB,EAAE,MAAM,MAAM,GAAG,IAAI,EAarD;IAEK,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAExC;YAEa,OAAO;IAgBrB;;;;OAIG;YACW,wBAAwB;IA+BtC,OAAO,CAAC,eAAe;YAiBT,SAAS;IAIvB;;;;OAIG;YACW,cAAc;CAgD/B"}
|