Skip to content
This repository was archived by the owner on Feb 25, 2026. It is now read-only.

Commit 56e5878

Browse files
committed
fix: kowalski now hosted at @kowalski4tgbot
The old bot was shadow-ratelimited, so we've decided to move the bot to a new username entirely to fix the issue.
1 parent 8885009 commit 56e5878

File tree

7 files changed

+438
-6
lines changed

7 files changed

+438
-6
lines changed

TERMS_OF_USE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Terms of Use
22

3-
By using Kowalski ([@KowalskiNodeBot](https://t.me/KowalskiNodeBot), you agree to the terms outlined below. If you do not agree with any of these terms, please discontinue use of the bot immediately.
3+
By using Kowalski ([@kowalski4tgbot](https://t.me/kowalski4tgbot), you agree to the terms outlined below. If you do not agree with any of these terms, please discontinue use of the bot immediately.
44

55
## 1. Blocklist System
66

@@ -10,7 +10,7 @@ Additionally, Kowalski integrates with the SpamWatch API to automatically deny a
1010

1111
## 2. Source Code
1212

13-
The bot's source code is publicly available. You can review it at the Kowalski GitHub Repository:
13+
The bot's source code is publicly available. You can review it at the Kowalski GitHub Repository:
1414
[https://github.com/abocn/TelegramBot](https://github.com/abocn/TelegramBot)
1515

1616
## 3. Changes to These Terms

webui/app/about/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export default function About() {
6565
</Link>
6666
</Button>
6767
<Button variant="outline" size="lg" className="min-w-32" asChild>
68-
<Link href="https://t.me/KowalskiNodeBot" target="_blank">
68+
<Link href="https://t.me/kowalski4tgbot" target="_blank">
6969
<RiTelegram2Line />
7070
{t('about.tryOnTelegram')}
7171
</Link>

webui/app/account/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ export default function AccountPage() {
458458
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 sm:gap-6 lg:gap-20 p-4 sm:p-6 lg:p-8 rounded-xl bg-gradient-to-r from-muted/30 to-muted/60 border border-border/50 shadow-lg backdrop-blur-sm">
459459
<h3 className="font-semibold text-base sm:text-lg lg:text-xl text-center sm:text-left flex-1 sm:flex-none">{t('account.readyToStart')}</h3>
460460
<Button asChild size="lg" className="shrink-0 shadow-md hover:shadow-lg transition-all duration-200 w-full sm:w-auto">
461-
<a href="https://t.me/KowalskiNodeBot" target="_blank" rel="noopener noreferrer" className="flex items-center justify-center gap-2">
461+
<a href="https://t.me/kowalski4tgbot" target="_blank" rel="noopener noreferrer" className="flex items-center justify-center gap-2">
462462
<RiTelegram2Line className="w-4 h-4 sm:w-5 sm:h-5" />
463463
<span className="text-sm sm:text-base">{t('account.openOnTelegram')}</span>
464464
</a>

webui/app/api/auth/username/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export async function POST(request: NextRequest) {
3838
});
3939

4040
if (!user) {
41-
const botUsername = process.env.botUsername || "KowalskiNodeBot";
41+
const botUsername = process.env.botUsername || "kowalski4tgbot";
4242
return NextResponse.json({ success: false, error: `Please DM @${botUsername} before signing in.` }, { status: 404 });
4343
}
4444

webui/app/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export default function Home() {
4949

5050
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center pt-8">
5151
<Button size="lg" className="min-w-32" asChild>
52-
<Link href="https://t.me/KowalskiNodeBot" target="_blank" rel="noopener noreferrer">
52+
<Link href="https://t.me/kowalski4tgbot" target="_blank" rel="noopener noreferrer">
5353
<RiTelegram2Line />
5454
{t('home.tryOnTelegram')}
5555
</Link>
Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
import { drizzle } from "drizzle-orm/node-postgres";
2+
import { Pool } from "pg";
3+
import * as schema from "../lib/schema";
4+
import { v4 as uuidv4 } from 'uuid';
5+
6+
const pool = new Pool({
7+
connectionString: process.env.databaseUrl,
8+
});
9+
10+
const db = drizzle(pool, { schema });
11+
12+
const errorTypes = [
13+
'TypeError',
14+
'ReferenceError',
15+
'SyntaxError',
16+
'RangeError',
17+
'NetworkError',
18+
'DatabaseError',
19+
'AuthenticationError',
20+
'ValidationError',
21+
'TimeoutError',
22+
'PermissionError'
23+
];
24+
25+
const errorMessages = [
26+
'Cannot read property of undefined',
27+
'Connection timed out',
28+
'Invalid user credentials',
29+
'Database connection failed',
30+
'Rate limit exceeded',
31+
'Insufficient permissions',
32+
'Invalid input format',
33+
'Resource not found',
34+
'Server internal error',
35+
'Memory limit exceeded',
36+
'Invalid API response',
37+
'File upload failed',
38+
'Session expired',
39+
'Token validation failed',
40+
'Query execution failed',
41+
'Cache miss error',
42+
'Webhook delivery failed',
43+
'Message sending failed',
44+
'User not found',
45+
'Command execution failed'
46+
];
47+
48+
const commandNames = [
49+
'start',
50+
'help',
51+
'settings',
52+
'ai',
53+
'wiki',
54+
'translate',
55+
'weather',
56+
'news',
57+
'stats',
58+
'export',
59+
'import',
60+
'search',
61+
'notify',
62+
'schedule',
63+
'reminder',
64+
'poll',
65+
'game',
66+
'music',
67+
'video',
68+
'image'
69+
];
70+
71+
const chatTypes = ['private', 'group', 'supergroup', 'channel'];
72+
73+
const telegramMethods = [
74+
'sendMessage',
75+
'sendPhoto',
76+
'sendDocument',
77+
'sendVideo',
78+
'sendAudio',
79+
'editMessageText',
80+
'deleteMessage',
81+
'getMe',
82+
'getChat',
83+
'getChatMember',
84+
'setChatPermissions',
85+
'answerCallbackQuery',
86+
'sendPoll',
87+
'sendVoice',
88+
'sendLocation'
89+
];
90+
91+
const telegramErrorCodes = [400, 401, 403, 404, 429, 500, 502, 503];
92+
93+
const telegramDescriptions = [
94+
'Bad Request: message text is empty',
95+
'Unauthorized: bot token is invalid',
96+
'Forbidden: bot was kicked from the group chat',
97+
'Not Found: chat not found',
98+
'Too Many Requests: retry after 30 seconds',
99+
'Internal Server Error',
100+
'Bad Gateway',
101+
'Service Unavailable',
102+
'Bad Request: message to edit not found',
103+
'Bad Request: message can\'t be deleted',
104+
'Bad Request: poll has already been closed',
105+
'Bad Request: file is too big',
106+
'Bad Request: wrong file identifier',
107+
'Forbidden: user is deactivated',
108+
'Bad Request: invalid user ID'
109+
];
110+
111+
function getRandomElement<T>(array: T[]): T {
112+
return array[Math.floor(Math.random() * array.length)];
113+
}
114+
115+
function getRandomDate(startDate: Date, endDate: Date): Date {
116+
const startTime = startDate.getTime();
117+
const endTime = endDate.getTime();
118+
const randomTime = startTime + Math.random() * (endTime - startTime);
119+
return new Date(randomTime);
120+
}
121+
122+
function getRandomSeverity(): 'info' | 'warning' | 'error' | 'critical' {
123+
const rand = Math.random();
124+
if (rand < 0.2) return 'info';
125+
if (rand < 0.45) return 'warning';
126+
if (rand < 0.85) return 'error';
127+
return 'critical';
128+
}
129+
130+
function generateStackTrace(errorType: string, errorMessage: string): string {
131+
const functions = [
132+
'at processTicksAndRejections (node:internal/process/task_queues:96:5)',
133+
'at async handleCommand (/app/telegram/bot.ts:145:13)',
134+
'at async MessageHandler.handle (/app/telegram/handlers/message.ts:78:9)',
135+
'at async Bot.processUpdate (/app/node_modules/telegraf/bot.ts:234:17)',
136+
'at async middleware (/app/telegram/middleware/error.ts:45:5)',
137+
'at async Database.query (/app/database/client.ts:112:11)',
138+
'at async Redis.get (/app/cache/redis.ts:34:7)',
139+
'at async ApiClient.request (/app/api/client.ts:89:15)'
140+
];
141+
142+
const stack = [`${errorType}: ${errorMessage}`];
143+
const numLines = Math.floor(Math.random() * 4) + 3;
144+
145+
for (let i = 0; i < numLines; i++) {
146+
stack.push(getRandomElement(functions));
147+
}
148+
149+
return stack.join('\n ');
150+
}
151+
152+
async function generateBotErrors(count: number) {
153+
const errors = [];
154+
const endDate = new Date();
155+
const startDate = new Date();
156+
startDate.setFullYear(startDate.getFullYear() - 1);
157+
158+
for (let i = 0; i < count; i++) {
159+
const errorType = getRandomElement(errorTypes);
160+
const errorMessage = getRandomElement(errorMessages);
161+
const severity = getRandomSeverity();
162+
const isResolved = Math.random() < 0.3;
163+
const createdAt = getRandomDate(startDate, endDate);
164+
165+
const error = {
166+
id: uuidv4(),
167+
errorType,
168+
errorMessage: `${errorMessage} in ${getRandomElement(commandNames)} command`,
169+
errorStack: Math.random() < 0.7 ? generateStackTrace(errorType, errorMessage) : null,
170+
commandName: Math.random() < 0.8 ? getRandomElement(commandNames) : null,
171+
chatType: Math.random() < 0.9 ? getRandomElement(chatTypes) : null,
172+
severity,
173+
resolved: isResolved,
174+
createdAt,
175+
resolvedAt: isResolved ? getRandomDate(createdAt, endDate) : null
176+
};
177+
178+
errors.push(error);
179+
}
180+
181+
return errors;
182+
}
183+
184+
async function generateTelegramErrors(count: number) {
185+
const errors = [];
186+
const endDate = new Date();
187+
const startDate = new Date();
188+
startDate.setFullYear(startDate.getFullYear() - 1);
189+
190+
for (let i = 0; i < count; i++) {
191+
const isResolved = Math.random() < 0.25;
192+
const createdAt = getRandomDate(startDate, endDate);
193+
const retryCount = Math.floor(Math.random() * 5);
194+
195+
const error = {
196+
id: `tg_${uuidv4()}`,
197+
errorCode: Math.random() < 0.9 ? getRandomElement(telegramErrorCodes) : null,
198+
errorDescription: getRandomElement(telegramDescriptions),
199+
method: Math.random() < 0.85 ? getRandomElement(telegramMethods) : null,
200+
parameters: Math.random() < 0.5 ? JSON.stringify({
201+
chat_id: Math.floor(Math.random() * 1000000),
202+
text: 'Sample message',
203+
parse_mode: 'Markdown'
204+
}) : null,
205+
retryCount,
206+
resolved: isResolved,
207+
createdAt,
208+
lastRetryAt: retryCount > 0 ? getRandomDate(createdAt, endDate) : null
209+
};
210+
211+
errors.push(error);
212+
}
213+
214+
return errors;
215+
}
216+
217+
async function generateCommandUsageEntries(count: number) {
218+
const entries = [];
219+
const endDate = new Date();
220+
const startDate = new Date();
221+
startDate.setFullYear(startDate.getFullYear() - 1);
222+
223+
for (let i = 0; i < count; i++) {
224+
const isError = Math.random() < 0.3;
225+
const commandName = getRandomElement(commandNames);
226+
const createdAt = getRandomDate(startDate, endDate);
227+
228+
const entry = {
229+
id: uuidv4(),
230+
commandName,
231+
chatType: getRandomElement(chatTypes),
232+
isSuccess: !isError,
233+
errorMessage: isError ? getRandomElement(errorMessages) : null,
234+
executionTime: Math.floor(Math.random() * 500) + 50,
235+
createdAt
236+
};
237+
238+
entries.push(entry);
239+
}
240+
241+
return entries;
242+
}
243+
244+
async function insertErrors() {
245+
try {
246+
console.log('🚀 Starting dummy error generation...\n');
247+
248+
const botErrorCount = parseInt(process.argv[2]) || 50;
249+
const telegramErrorCount = parseInt(process.argv[3]) || 30;
250+
const commandUsageCount = parseInt(process.argv[4]) || 100;
251+
252+
console.log(`📝 Generating ${botErrorCount} bot errors...`);
253+
const botErrors = await generateBotErrors(botErrorCount);
254+
255+
console.log(`📝 Generating ${telegramErrorCount} Telegram errors...`);
256+
const telegramErrors = await generateTelegramErrors(telegramErrorCount);
257+
258+
console.log(`📝 Generating ${commandUsageCount} command usage entries...`);
259+
const commandUsageEntries = await generateCommandUsageEntries(commandUsageCount);
260+
261+
console.log('\n💾 Inserting bot errors into database...');
262+
for (const error of botErrors) {
263+
await db.insert(schema.botErrorsTable).values(error);
264+
}
265+
console.log(`✅ Inserted ${botErrors.length} bot errors`);
266+
267+
console.log('\n💾 Inserting Telegram errors into database...');
268+
for (const error of telegramErrors) {
269+
const { id, ...errorData } = error;
270+
await db.insert(schema.telegramErrorsTable).values({
271+
...errorData,
272+
id: id.replace('tg_', '')
273+
});
274+
}
275+
console.log(`✅ Inserted ${telegramErrors.length} Telegram errors`);
276+
277+
console.log('\n💾 Inserting command usage entries into database...');
278+
for (const entry of commandUsageEntries) {
279+
await db.insert(schema.commandUsageTable).values(entry);
280+
}
281+
console.log(`✅ Inserted ${commandUsageEntries.length} command usage entries`);
282+
283+
const resolvedBotErrors = botErrors.filter(e => e.resolved).length;
284+
const unresolvedBotErrors = botErrors.filter(e => !e.resolved).length;
285+
const resolvedTelegramErrors = telegramErrors.filter(e => e.resolved).length;
286+
const unresolvedTelegramErrors = telegramErrors.filter(e => !e.resolved).length;
287+
288+
const failedCommands = commandUsageEntries.filter(e => !e.isSuccess).length;
289+
const successfulCommands = commandUsageEntries.filter(e => e.isSuccess).length;
290+
291+
console.log('\n📊 Summary:');
292+
console.log('─────────────────────────────────');
293+
console.log(`Bot Errors:`);
294+
console.log(` • Total: ${botErrors.length}`);
295+
console.log(` • Resolved: ${resolvedBotErrors}`);
296+
console.log(` • Unresolved: ${unresolvedBotErrors}`);
297+
console.log(` • Severities:`);
298+
console.log(` - Critical: ${botErrors.filter(e => e.severity === 'critical').length}`);
299+
console.log(` - Error: ${botErrors.filter(e => e.severity === 'error').length}`);
300+
console.log(` - Warning: ${botErrors.filter(e => e.severity === 'warning').length}`);
301+
console.log(` - Info: ${botErrors.filter(e => e.severity === 'info').length}`);
302+
console.log(`\nTelegram Errors:`);
303+
console.log(` • Total: ${telegramErrors.length}`);
304+
console.log(` • Resolved: ${resolvedTelegramErrors}`);
305+
console.log(` • Unresolved: ${unresolvedTelegramErrors}`);
306+
console.log(`\nCommand Usage:`);
307+
console.log(` • Total: ${commandUsageEntries.length}`);
308+
console.log(` • Failed: ${failedCommands} (${((failedCommands/commandUsageEntries.length)*100).toFixed(1)}%)`);
309+
console.log(` • Successful: ${successfulCommands}`);
310+
311+
console.log('\n✨ Done! Check the Error Review page in the WebUI to see the generated errors.');
312+
313+
} catch (error) {
314+
console.error('❌ Error generating dummy data:', error);
315+
process.exit(1);
316+
} finally {
317+
await pool.end();
318+
process.exit(0);
319+
}
320+
}
321+
322+
if (import.meta.main) {
323+
insertErrors();
324+
}

0 commit comments

Comments
 (0)