Bot Development & Automation 2026: Discord, Telegram, Slack i nie tylko - kompletny przewodnik
Bot Development & Automation 2026: Discord, Telegram, Slack i nie tylko
Wyobraź sobie, że Twój serwer Discord działa sam. Moderation odbywa się automatycznie. Nowi użytkownicy są witani personalnie. System economy zachęca do aktywności. A to wszystko działa 24/7, bez ani jednej minuty Twojego czasu.
To nie utopia. To custom bot development.
W 2026 roku boty to nie tylko zabawki dla geeks. To infrastruktura biznesowa dla communities liczących setki tysięcy użytkowników, automatyzacje generujące przychód dla firm, i AI asystenci, którzy zastępują całe działy customer support.
Przez ostatnie lata zbudowałem dziesiątki botów - od prostych moderation systems po zaawansowane platformy z Stripe payments, GPT-4 integracją i real-time analytics. W tym artykule dzielę się wszystkim, co wiem o bot development na Discord, Telegram, Slack i innych platformach.
Spis treści
- Dlaczego boty to przyszłość - liczby i trendy
- Architektura: Jak myśleć o botach jak inżynier
- Discord Bot Development - od zera do produkcji
- Telegram Bot Development - potęga inline i webhooks
- Slack Bot Automation - enterprise-grade solutions
- AI-Powered Bots - integracja z GPT-4 i Claude
- Databases & Caching - MongoDB, Redis, PostgreSQL
- Payment Integration - Stripe, PayPal w botach
- Skalowanie i hosting production botów
- Case Studies - prawdziwe projekty
- Pełny ekosystem: Multi-Platform Bot Architecture
1. Dlaczego boty to przyszłość
Rynek botów w liczbach (2026)
Boty nie są trendem. To fundamentalna zmiana w komunikacji cyfrowej:
🔥 Rynek i adopcja:
- Discord: 500+ milionów użytkowników, over 1 million active bots (Discord Developer Portal 2026)
- Telegram: 900+ milionów aktywnych użytkowników, boty generują $2.1B przychodu rocznie
- Slack: 32 miliony użytkowników dziennie, 90% Fortune 100 korzysta z Slack bots
- Chatbot market: Wyceniany na $27.3 miliarda w 2030 (Grand View Research)
⚡ Dlaczego firmy inwestują w boty:
ROI z automatyzacji botów (dane rzeczywiste):
Customer Support Bot:
→ Redukuje ticekty o 40-70%
→ Czas odpowiedzi: 30 min → 2 sekundy
→ Koszt obsługi: $15/ticket → $0.05/ticket
Community Management Bot:
→ Moderation 24/7 (vs człowiek: 8h/dzień)
→ Zero human error w spam detection
→ Engagement +35% przez gamification
E-commerce Bot:
→ Order tracking automation
→ Payment confirmations instant
→ Revenue per bot: $500-$5000/miesiąc
Który typ bota wybrać?
Zanim zaczniesz kodować, musisz wiedzieć co chcesz osiągnąć. Oto mapa typów botów:
| Typ | Platforma | Złożoność | Potencjalny przychód | |-----|-----------|-----------|---------------------| | Moderation Bot | Discord | ⭐⭐ | $99-499/serwer | | Economy/Leveling | Discord | ⭐⭐⭐ | $199-999/serwer | | Music Bot | Discord | ⭐⭐⭐ | Freemium + premium | | Customer Support | Telegram | ⭐⭐ | $299-1499/miesiąc | | Payment Bot | Telegram | ⭐⭐⭐⭐ | $499-2999/projekt | | Workspace Automation | Slack | ⭐⭐⭐ | $999-4999/rok | | AI Assistant | Dowolna | ⭐⭐⭐⭐⭐ | $299-9999/projekt |
2. Architektura: Jak myśleć o botach jak inżynier
Event-Driven Architecture
Każdy bot działa na tej samej zasadzie: słuchaj zdarzeń → reaguj. Ale to jak reagujesz decyduje o jakości bota.
[Platform API] ──── WebSocket/Polling ────► [Bot Core]
│
┌──────────────────────┤
▼ ▼
[Event Router] [Command Handler]
│ │
┌──────────┤ ┌────────┤
▼ ▼ ▼ ▼
[Commands] [Auto-Mod] [Database] [AI API]
│ │ │ │
└──────────┴──────────────┴────────┘
│
[Response Layer]
│
┌─────────────┴────────────┐
▼ ▼
[Platform API] [Webhooks/External]
Trzy filary production bota
1. Reliability (niezawodność) Bot musi działać 24/7. Zero downtime = zero strat. Używam:
- Process managers: PM2 (Node.js) lub Supervisor (Python)
- Health checks: Endpoint
/healthsprawdzany co 30s - Auto-restart: Graceful shutdown + restart przy crashach
- Logging: Winston (Node.js) lub Loguru (Python) z rotacją logów
2. Performance (wydajność) Latency to wszystko. Użytkownik czeka na odpowiedź bota w ciągu milisekund.
- Caching: Redis dla często używanych danych (prefix commands, user settings)
- Database indexing: Indeksy na polach
userId,guildId,timestamp - Rate limiting: Kolejkowanie requestów do API żeby nie przekroczyć limitów
- Lazy loading: Ładuj moduły tylko gdy potrzebne
3. Security (bezpieczeństwo) Boty mają dostęp do danych tysięcy użytkowników. Bezpieczeństwo nie jest opcją.
- Permission checks: Sprawdzaj role PRZED każdą komendą
- Input validation: Nigdy nie ufaj user input
- Token security: Secrets w
.env, nigdy w kodzie - Rate limiting per user: Chroń przed spam/abuse
3. Discord Bot Development - od zera do produkcji
Dlaczego Discord.js?
Discord.js v14 to de facto standard dla Node.js Discord botów. Dlaczego go wybieram:
- ✅ TypeScript support - typy dla wszystkich Discord API objectów
- ✅ Slash Commands - nowoczesny interface zamiast prefix commands
- ✅ Sharding - skalowanie do tysięcy serwerów
- ✅ Voice support - audio streaming dla music botów
- ✅ Collectors - awaitMessages, awaitReactions dla interaktywnych flow'ów
Setup bota - projekt struktury
discord-bot/
├── src/
│ ├── commands/
│ │ ├── moderation/
│ │ │ ├── ban.ts
│ │ │ ├── kick.ts
│ │ │ └── timeout.ts
│ │ ├── economy/
│ │ │ ├── balance.ts
│ │ │ ├── daily.ts
│ │ │ └── shop.ts
│ │ └── utility/
│ │ ├── help.ts
│ │ └── ping.ts
│ ├── events/
│ │ ├── ready.ts
│ │ ├── interactionCreate.ts
│ │ └── guildMemberAdd.ts
│ ├── utils/
│ │ ├── database.ts
│ │ ├── logger.ts
│ │ └── permissions.ts
│ └── index.ts
├── .env
├── package.json
└── tsconfig.json
Slash Commands z TypeScript (production-ready)
// src/commands/moderation/ban.ts
import {
ChatInputCommandInteraction,
SlashCommandBuilder,
PermissionFlagsBits,
GuildMember,
EmbedBuilder
} from 'discord.js';
import { logModAction } from '../../utils/logger';
import { db } from '../../utils/database';
export const data = new SlashCommandBuilder()
.setName('ban')
.setDescription('Ban użytkownika z serwera')
.addUserOption(option =>
option.setName('target')
.setDescription('Użytkownik do zbanowania')
.setRequired(true)
)
.addStringOption(option =>
option.setName('reason')
.setDescription('Powód bana')
.setRequired(false)
.setMaxLength(512)
)
.addIntegerOption(option =>
option.setName('delete_days')
.setDescription('Ile dni wiadomości usunąć (0-7)')
.setMinValue(0)
.setMaxValue(7)
)
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers);
export async function execute(interaction: ChatInputCommandInteraction) {
// 1. Defer reply - daje 15 minut na odpowiedź
await interaction.deferReply({ ephemeral: true });
const target = interaction.options.getMember('target') as GuildMember;
const reason = interaction.options.getString('reason') ?? 'Brak powodu';
const deleteDays = interaction.options.getInteger('delete_days') ?? 0;
// 2. Validation - zawsze sprawdź zanim wykonasz
if (!target) {
return interaction.editReply('❌ Nie znaleziono użytkownika na serwerze.');
}
if (!target.bannable) {
return interaction.editReply('❌ Nie mogę zbanować tego użytkownika (wyższe uprawnienia).');
}
if (target.id === interaction.user.id) {
return interaction.editReply('❌ Nie możesz zbanować samego siebie.');
}
// 3. Execute
try {
await target.ban({
reason: `${reason} | Moderator: ${interaction.user.tag}`,
deleteMessageSeconds: deleteDays * 86400
});
// 4. Log do bazy danych
await db.collection('mod_logs').insertOne({
action: 'BAN',
targetId: target.id,
targetTag: target.user.tag,
moderatorId: interaction.user.id,
moderatorTag: interaction.user.tag,
reason,
guildId: interaction.guildId,
timestamp: new Date()
});
// 5. Rich embed response
const embed = new EmbedBuilder()
.setColor(0xFF0000)
.setTitle('🔨 Użytkownik zbanowany')
.addFields(
{ name: 'Użytkownik', value: `${target.user.tag} (${target.id})`, inline: true },
{ name: 'Moderator', value: interaction.user.tag, inline: true },
{ name: 'Powód', value: reason }
)
.setTimestamp();
return interaction.editReply({ embeds: [embed] });
} catch (error) {
console.error('Ban failed:', error);
return interaction.editReply('❌ Wystąpił błąd podczas banowania.');
}
}
Auto-Moderation System
Zaawansowany system moderacji wykrywający spam, flood i zakazane treści:
// src/events/messageCreate.ts - Auto-Mod Engine
import { Message } from 'discord.js';
import { cache } from '../utils/cache'; // Redis wrapper
const SPAM_THRESHOLD = 5; // wiadomości
const SPAM_WINDOW = 5000; // w 5 sekundach
export async function handleMessage(message: Message) {
if (message.author.bot || !message.guild) return;
// 1. Spam detection z sliding window
const key = `spam:${message.guild.id}:${message.author.id}`;
const count = await cache.incr(key);
if (count === 1) await cache.expire(key, 5); // 5s window
if (count >= SPAM_THRESHOLD) {
await message.delete().catch(() => {});
const member = message.member;
if (member) {
await member.timeout(60000, 'Auto-Mod: Spam detection');
await message.channel.send(
`⚠️ ${message.author} - timeout 1 minuta za spam.`
).then(msg => setTimeout(() => msg.delete(), 5000));
}
return;
}
// 2. Badwords filter (z regex)
const BADWORDS_REGEX = /\b(spam|offensive_word)\b/gi; // customize!
if (BADWORDS_REGEX.test(message.content)) {
await message.delete();
await message.author.send('⚠️ Twoja wiadomość została usunięta - naruszyła regulamin serwera.');
return;
}
// 3. Link filter dla nieweryfikowanych użytkowników
const hasLink = /https?:\/\/[^\s]+/.test(message.content);
const isVerified = message.member?.roles.cache.some(r => r.name === 'Verified');
if (hasLink && !isVerified) {
await message.delete();
await message.reply('❌ Musisz być zweryfikowany aby wysyłać linki.').then(
msg => setTimeout(() => msg.delete(), 5000)
);
}
}
4. Telegram Bot Development - potęga inline i webhooks
Telegram vs Discord: Kluczowe różnice dla developerów
Discord:
✓ Guild (server) structure - hierarchia, kanały, role
✓ Rich Embeds - piękne wiadomości
✓ Voice channels - audio/video
✗ Mniejsza baza użytkowników poza gaming
Telegram:
✓ 900M+ użytkowników
✓ Inline bots - działają w dowolnym chacie
✓ Bot payments API wbudowany
✓ WebApp support (mini-apps!)
✓ Kanały + grupy + bot jednocześnie
✓ Ogromna adopcja w crypto, biznes, e-commerce
Telegraf v4 - Node.js framework
import { Telegraf, Markup, session } from 'telegraf';
import { message } from 'telegraf/filters';
import { MongoClient } from 'mongodb';
interface SessionData {
step?: string;
orderData?: Partial<Order>;
}
const bot = new Telegraf<Context>(process.env.TELEGRAM_TOKEN!);
// Session middleware (persisted w MongoDB)
bot.use(session({
defaultSession: (): SessionData => ({})
}));
// Inline keyboard z callback buttons
bot.command('start', async (ctx) => {
const keyboard = Markup.inlineKeyboard([
[
Markup.button.callback('🛒 Sklep', 'shop'),
Markup.button.callback('📦 Zamówienia', 'orders')
],
[
Markup.button.callback('💬 Support', 'support'),
Markup.button.webApp('🌐 Panel', 'https://yourapp.com/panel')
]
]);
await ctx.reply(
`Witaj w **${process.env.BOT_NAME}** 👋\n\nCo mogę dla Ciebie zrobić?`,
{ parse_mode: 'Markdown', ...keyboard }
);
});
// Conversation flow - multi-step form
bot.action('shop', async (ctx) => {
ctx.session.step = 'choosing_product';
const products = await db.collection('products').find({ active: true }).toArray();
const keyboard = Markup.inlineKeyboard(
products.map(p => [
Markup.button.callback(`${p.name} - $${p.price}`, `buy_${p._id}`)
])
);
await ctx.editMessageText('🛍️ Wybierz produkt:', keyboard);
});
// Payment integration (Telegram Payments API)
bot.action(/^buy_(.+)$/, async (ctx) => {
const productId = ctx.match[1];
const product = await db.collection('products').findOne({ _id: new ObjectId(productId) });
if (!product) return ctx.answerCbQuery('Produkt niedostępny');
await ctx.replyWithInvoice({
title: product.name,
description: product.description,
payload: JSON.stringify({ productId, userId: ctx.from.id }),
provider_token: process.env.STRIPE_PROVIDER_TOKEN!,
currency: 'USD',
prices: [{ label: product.name, amount: product.price * 100 }],
photo_url: product.imageUrl,
need_name: false,
need_email: true
});
});
// Pre-checkout answer (wymagane przez Telegram!)
bot.on('pre_checkout_query', (ctx) => ctx.answerPreCheckoutQuery(true));
// Successful payment handler
bot.on(message('successful_payment'), async (ctx) => {
const payload = JSON.parse(ctx.message.successful_payment.invoice_payload);
// Zapisz zakup w bazie
await db.collection('orders').insertOne({
userId: ctx.from.id,
productId: payload.productId,
amount: ctx.message.successful_payment.total_amount / 100,
currency: ctx.message.successful_payment.currency,
telegramPaymentId: ctx.message.successful_payment.telegram_payment_charge_id,
timestamp: new Date()
});
await ctx.reply(
'✅ **Płatność przyjęta!**\n\nDziękujemy za zakup. Twój dostęp zostanie przyznany w ciągu kilku minut.',
{ parse_mode: 'Markdown' }
);
});
// Webhook zamiast polling (production!)
bot.launch({
webhook: {
domain: process.env.WEBHOOK_DOMAIN!,
port: 3001
}
});
Telegram Mini Apps (Web Apps)
Najnowszy feature Telegrama - mini aplikacje działające bezpośrednio w chacie:
// Frontend (React/Next.js) - Telegram Web App SDK
import WebApp from '@twa-dev/sdk';
export function ShopApp() {
const user = WebApp.initDataUnsafe.user;
// Dostęp do danych Telegram user
console.log(user?.id, user?.username, user?.first_name);
const handlePurchase = async (productId: string) => {
// Zamknij web app i wyślij dane do bota
WebApp.sendData(JSON.stringify({ action: 'purchase', productId }));
};
return (
<div style={{ background: WebApp.backgroundColor }}>
{/* Twoja React aplikacja działa w Telegramie! */}
<button onClick={() => handlePurchase('product-123')}>
Kup teraz
</button>
</div>
);
}
5. Slack Bot Automation - enterprise-grade solutions
Slack API - trzy warstwy możliwości
Warstwa 1: Basic Bot
→ Respond to messages
→ Post notifications
→ Simple commands
→ Use case: Alerts, CI/CD notifications
Warstwa 2: Workflow Automation
→ Modals (popup forms)
→ Block Kit UI (rich interactive messages)
→ App Home tab
→ Use case: Ticket systems, approval workflows
Warstwa 3: Platform Integration
→ Slack Connect (B2B)
→ External integrations (Jira, GitHub, Salesforce)
→ Custom dashboards in Slack
→ Use case: Enterprise CRM, HR systems
Bolt.js - oficjalny Slack framework
import { App, BlockAction, ViewSubmitAction } from '@slack/bolt';
import { WebClient } from '@slack/web-api';
const app = new App({
token: process.env.SLACK_BOT_TOKEN!,
signingSecret: process.env.SLACK_SIGNING_SECRET!,
socketMode: true, // dev mode - bez publicznego URL
appToken: process.env.SLACK_APP_TOKEN!
});
// Slash command z Modal (formularz popup)
app.command('/ticket', async ({ command, ack, client }) => {
await ack();
// Otwórz modal
await client.views.open({
trigger_id: command.trigger_id,
view: {
type: 'modal',
callback_id: 'create_ticket',
title: { type: 'plain_text', text: '🎫 Nowy Ticket' },
submit: { type: 'plain_text', text: 'Utwórz' },
blocks: [
{
type: 'input',
block_id: 'title',
element: {
type: 'plain_text_input',
action_id: 'value',
placeholder: { type: 'plain_text', text: 'Opisz problem...' }
},
label: { type: 'plain_text', text: 'Tytuł' }
},
{
type: 'input',
block_id: 'priority',
element: {
type: 'static_select',
action_id: 'value',
options: [
{ text: { type: 'plain_text', text: '🔴 Krytyczny' }, value: 'critical' },
{ text: { type: 'plain_text', text: '🟡 Średni' }, value: 'medium' },
{ text: { type: 'plain_text', text: '🟢 Niski' }, value: 'low' }
]
},
label: { type: 'plain_text', text: 'Priorytet' }
}
]
}
});
});
// Modal submission handler
app.view('create_ticket', async ({ ack, body, view, client }) => {
await ack();
const title = view.state.values.title.value.value!;
const priority = view.state.values.priority.value.selected_option!.value;
const userId = body.user.id;
// Stwórz ticket w DB i wyślij do kanału support
const ticket = await createTicketInDB({ title, priority, userId });
await client.chat.postMessage({
channel: process.env.SUPPORT_CHANNEL!,
blocks: [
{
type: 'section',
text: {
type: 'mrkdwn',
text: `🎫 *Nowy Ticket #${ticket.id}*\n*Tytuł:* ${title}\n*Priorytet:* ${priority}\n*Zgłosił:* <@${userId}>`
}
},
{
type: 'actions',
elements: [
{
type: 'button',
text: { type: 'plain_text', text: '✅ Przyjmij' },
style: 'primary',
action_id: 'accept_ticket',
value: ticket.id
},
{
type: 'button',
text: { type: 'plain_text', text: '❌ Odrzuć' },
style: 'danger',
action_id: 'reject_ticket',
value: ticket.id
}
]
}
]
});
});
6. AI-Powered Bots - integracja z GPT-4 i Claude
Kontekstowy AI Asystent w Discord
To właśnie odróżnia dobrego bota od wyjątkowego - pamięć konwersacji i prawdziwa inteligencja:
import OpenAI from 'openai';
import { Collection } from 'discord.js';
const openai = new OpenAI({ apiKey: process.env.OPENAI_KEY });
// Przechowuj historię konwersacji per user (Redis)
const conversations = new Collection<string, OpenAI.ChatCompletionMessageParam[]>();
export async function aiChat(
userId: string,
userMessage: string,
systemPrompt: string
): Promise<string> {
// Pobierz historię lub zainicjuj nową
const history = conversations.get(userId) ?? [];
// System prompt definiuje "osobowość" bota
const messages: OpenAI.ChatCompletionMessageParam[] = [
{
role: 'system',
content: systemPrompt || `Jesteś pomocnym asystentem na serwerze Discord.
Odpowiadaj zwięźle (max 300 słów), używaj emoji gdzie stosowne.
Jeśli pytanie wykracza poza zakres serwera, grzecznie przekieruj.`
},
...history.slice(-10), // Ostatnie 10 wiadomości (context window)
{ role: 'user', content: userMessage }
];
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages,
max_tokens: 500,
temperature: 0.7
});
const aiReply = response.choices[0].message.content ?? 'Nie udało się wygenerować odpowiedzi.';
// Zapisz do historii
history.push(
{ role: 'user', content: userMessage },
{ role: 'assistant', content: aiReply }
);
conversations.set(userId, history);
// Wyczyść historię po 30 minutach nieaktywności
setTimeout(() => conversations.delete(userId), 30 * 60 * 1000);
return aiReply;
}
// Discord command
bot.on('interactionCreate', async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName !== 'ask') return;
await interaction.deferReply();
const question = interaction.options.getString('question', true);
const serverConfig = await getServerConfig(interaction.guildId!);
const response = await aiChat(
interaction.user.id,
question,
serverConfig.aiSystemPrompt
);
await interaction.editReply(response);
});
Image Generation Bot (DALL-E 3 + Discord)
import { AttachmentBuilder } from 'discord.js';
async function generateImage(prompt: string): Promise<Buffer> {
const response = await openai.images.generate({
model: 'dall-e-3',
prompt,
size: '1024x1024',
quality: 'standard',
n: 1
});
const imageUrl = response.data[0].url!;
const imageResponse = await fetch(imageUrl);
return Buffer.from(await imageResponse.arrayBuffer());
}
// Slash command
// /imagine prompt:futuristic city at night, neon lights, cyberpunk style
export async function execute(interaction: ChatInputCommandInteraction) {
await interaction.deferReply();
const prompt = interaction.options.getString('prompt', true);
// Basic content filter
if (prompt.length > 1000) {
return interaction.editReply('❌ Prompt za długi (max 1000 znaków).');
}
const imageBuffer = await generateImage(prompt);
const attachment = new AttachmentBuilder(imageBuffer, { name: 'generated.png' });
await interaction.editReply({
content: `🎨 Wygenerowano dla: **${prompt}**`,
files: [attachment]
});
}
7. Databases & Caching - MongoDB, Redis, PostgreSQL
Kiedy używać której bazy?
MongoDB:
✓ Flexible schema (różne konfiguracje per serwer)
✓ Nested documents (user inventory w jednym document)
✓ Easy horizontal scaling
→ Używaj dla: User data, server config, logs, inventory
Redis:
✓ In-memory = microsecond latency
✓ TTL (auto-expiry) dla cooldownów
✓ Pub/Sub dla multi-shard botów
→ Używaj dla: Cooldowns, rate limits, sessions, cache
PostgreSQL:
✓ ACID transactions (payments!)
✓ Complex queries z JOINs
✓ Strong consistency
→ Używaj dla: Financial transactions, audit logs
Economy System w MongoDB + Redis
// Pełny economy system: balance, daily, transfer
export class EconomyService {
private db: Collection;
private redis: Redis;
constructor(db: Collection, redis: Redis) {
this.db = db;
this.redis = redis;
}
async getBalance(userId: string, guildId: string): Promise<number> {
// Cache first (Redis)
const cached = await this.redis.get(`balance:${guildId}:${userId}`);
if (cached) return parseInt(cached);
// Fallback to MongoDB
const user = await this.db.findOne({ userId, guildId });
const balance = user?.balance ?? 0;
// Cache na 60 sekund
await this.redis.setex(`balance:${guildId}:${userId}`, 60, balance.toString());
return balance;
}
async claimDaily(userId: string, guildId: string): Promise<{ success: boolean; amount?: number; timeLeft?: number }> {
const cooldownKey = `daily:${guildId}:${userId}`;
const ttl = await this.redis.ttl(cooldownKey);
if (ttl > 0) {
return { success: false, timeLeft: ttl };
}
const DAILY_AMOUNT = 100;
const COOLDOWN = 86400; // 24h w sekundach
// Atomic update w MongoDB
await this.db.updateOne(
{ userId, guildId },
{
$inc: { balance: DAILY_AMOUNT, totalEarned: DAILY_AMOUNT },
$setOnInsert: { createdAt: new Date() }
},
{ upsert: true }
);
// Invalidate cache
await this.redis.del(`balance:${guildId}:${userId}`);
// Set cooldown
await this.redis.setex(cooldownKey, COOLDOWN, '1');
return { success: true, amount: DAILY_AMOUNT };
}
async transfer(
fromUserId: string,
toUserId: string,
guildId: string,
amount: number
): Promise<{ success: boolean; error?: string }> {
const balance = await this.getBalance(fromUserId, guildId);
if (balance < amount) {
return { success: false, error: 'Niewystarczające środki' };
}
if (amount <= 0) {
return { success: false, error: 'Kwota musi być większa niż 0' };
}
// Atomic transfer (MongoDB transactions)
const session = this.db.client.startSession();
try {
await session.withTransaction(async () => {
await this.db.updateOne(
{ userId: fromUserId, guildId },
{ $inc: { balance: -amount } },
{ session }
);
await this.db.updateOne(
{ userId: toUserId, guildId },
{ $inc: { balance: amount }, $setOnInsert: { createdAt: new Date() } },
{ upsert: true, session }
);
});
// Invalidate caches
await Promise.all([
this.redis.del(`balance:${guildId}:${fromUserId}`),
this.redis.del(`balance:${guildId}:${toUserId}`)
]);
return { success: true };
} finally {
await session.endSession();
}
}
}
8. Payment Integration - Stripe w botach Discord/Telegram
Premium Bot Subscriptions z Stripe
Jeden z najpopularniejszych modeli monetyzacji botów - subscription za premium features:
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: '2024-04-10'
});
// Tworzy checkout session dla premium subscription
export async function createPremiumCheckout(
discordUserId: string,
guildId: string,
tier: 'basic' | 'pro' | 'enterprise'
): Promise<string> {
const PRICE_IDS = {
basic: 'price_BASIC_ID',
pro: 'price_PRO_ID',
enterprise: 'price_ENTERPRISE_ID'
};
const session = await stripe.checkout.sessions.create({
mode: 'subscription',
payment_method_types: ['card'],
line_items: [{ price: PRICE_IDS[tier], quantity: 1 }],
success_url: `${process.env.SITE_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.SITE_URL}/cancel`,
metadata: {
discordUserId,
guildId,
tier
},
subscription_data: {
metadata: { discordUserId, guildId }
}
});
return session.url!;
}
// Webhook handler - aktywuje premium po zapłacie
export async function handleStripeWebhook(
rawBody: Buffer,
signature: string
): Promise<void> {
const event = stripe.webhooks.constructEvent(
rawBody,
signature,
process.env.STRIPE_WEBHOOK_SECRET!
);
switch (event.type) {
case 'checkout.session.completed': {
const session = event.data.object as Stripe.Checkout.Session;
const { discordUserId, guildId, tier } = session.metadata!;
await activatePremium(discordUserId, guildId, tier);
await notifyUserInDiscord(discordUserId, tier);
break;
}
case 'customer.subscription.deleted': {
const subscription = event.data.object as Stripe.Subscription;
const { discordUserId, guildId } = subscription.metadata;
await deactivatePremium(discordUserId, guildId);
break;
}
}
}
9. Skalowanie i hosting production botów
Gdzie hostować bota?
Small Bot (1-100 serwerów):
→ Railway.app: $5/miesiąc, auto-deploy z GitHub, zero config
→ Fly.io: Free tier dostępny, great dla małych botów
→ Render: Free tier (z sleep po 15 min nieaktywności)
Medium Bot (100-1000 serwerów):
→ Railway Pro: $20/miesiąc, persistent storage
→ DigitalOcean Droplet: $6-12/miesiąc, pełna kontrola
→ Hetzner VPS: €3.29/miesiąc, najlepszy stosunek ceny do jakości w EU
Large Bot (1000+ serwerów):
→ Discord Sharding (wymagane powyżej 2500 serwerów)
→ Kubernetes (k8s): Auto-scaling, zero downtime deploys
→ Redis Cluster: Distributed state dla wielu shardów
Sharding - skalowanie Discord bota
// src/shard-manager.ts
import { ShardingManager } from 'discord.js';
import path from 'path';
const manager = new ShardingManager(
path.join(__dirname, 'bot.js'),
{
token: process.env.DISCORD_TOKEN!,
totalShards: 'auto', // Discord oblicza optymalną liczbę
respawn: true // Auto-restart crashed shards
}
);
manager.on('shardCreate', (shard) => {
console.log(`🔷 Shard #${shard.id} uruchomiony`);
shard.on('ready', () =>
console.log(`✅ Shard #${shard.id} gotowy`)
);
shard.on('disconnect', () =>
console.warn(`⚠️ Shard #${shard.id} rozłączony - próba reconnect...`)
);
});
manager.spawn();
PM2 Configuration (production process manager)
// ecosystem.config.json
{
"apps": [
{
"name": "discord-bot",
"script": "dist/index.js",
"instances": 1,
"autorestart": true,
"watch": false,
"max_memory_restart": "512M",
"env": {
"NODE_ENV": "production"
},
"log_date_format": "YYYY-MM-DD HH:mm:ss Z",
"error_file": "logs/error.log",
"out_file": "logs/out.log",
"exp_backoff_restart_delay": 100
}
]
}
10. Case Studies - prawdziwe projekty
Case Study #1: Gaming Community Bot (Discord)
Klient: Community gamingowe, 15,000 memberów
Problem:
- Moderacja przez 3 osoby pracujące w różnych strefach czasowych
- Brak automatycznego systemu levelowania i nagród
- Wysoki churn - nowi użytkownicy nie widzieli powodu do pozostania
Rozwiązanie (stack: Discord.js, MongoDB, Redis):
System moderacji:
→ Auto-ban za spam (5+ wiadomości / 5 sekund)
→ Auto-timeout za badwords (3 strikes system)
→ Raid protection (flood nowych joinów = lockdown)
→ Mod logs w dedykowanym kanale
Economy & Gamification:
→ XP za aktywność (wiadomości, voice time)
→ Role rewards: Newbie → Regular → VIP → Legend
→ Daily rewards (100-500 coins)
→ Shop: custom roles, kanały, emotki
Onboarding:
→ Welcome DM z tutorialem
→ Verify system (role po przeczytaniu regulaminu)
→ First-message reward (bonus coins)
Wyniki po 30 dniach:
Metryki przed: Metryki po:
Czas odpowiedzi mod: 45 min → 0.2 sekundy (auto-mod)
Daily active users: 234 → 891 (+281%)
Churn rate: 68% → 31% (-54%)
Mod team hours: 12h/dzień → 2h/dzień (-83%)
Case Study #2: E-commerce Customer Support (Telegram)
Klient: Sklep online, 2,000 zamówień/miesiąc
Problem:
- Klienci pytają o status zamówienia przez email (odpowiedź: 24-48h)
- Customer service overwhelmed przed Black Friday
- Brak automatycznych powiadomień o statusie
Rozwiązanie (stack: Telegraf, PostgreSQL, Stripe webhooks):
// Order tracking bot
bot.command('status', async (ctx) => {
const orderNumber = ctx.message.text.split(' ')[1];
if (!orderNumber) {
return ctx.reply('Podaj numer zamówienia: /status ORD-123456');
}
const order = await db.query(
'SELECT * FROM orders WHERE order_number = $1 AND telegram_user_id = $2',
[orderNumber, ctx.from.id.toString()]
);
if (!order.rows[0]) {
return ctx.reply('❌ Nie znaleziono zamówienia lub nie masz do niego dostępu.');
}
const o = order.rows[0];
const statusEmoji = {
pending: '⏳',
processing: '🔄',
shipped: '📦',
delivered: '✅',
cancelled: '❌'
}[o.status] ?? '❓';
await ctx.reply(
`${statusEmoji} *Zamówienie ${o.order_number}*\n\n` +
`Status: ${o.status}\n` +
`Produkt: ${o.product_name}\n` +
`Data zamówienia: ${o.created_at.toLocaleDateString('pl-PL')}\n` +
(o.tracking_number ? `Śledzenie: \`${o.tracking_number}\`` : ''),
{ parse_mode: 'Markdown' }
);
});
Wyniki:
Tickety email: 1,240/miesiąc → 89/miesiąc (-93%)
Czas odpowiedzi: 24-48h → instant
Customer satisfaction: 3.2/5 → 4.7/5
Support team cost: $2,400/mies → $600/mies (-75%)
Case Study #3: HR Bot (Slack)
Klient: Firma tech, 80 pracowników
Problem:
- Urlopy zgłaszane przez email do HR (chaos)
- Brak visibility kto jest dostępny
- Onboarding nowych pracowników: papierologia, manuale
Rozwiązanie (stack: Bolt.js, PostgreSQL, Google Calendar API):
Leave Management:
/urlop start:2026-06-01 end:2026-06-07 type:wypoczynek
→ Modal do potwierdzenia
→ Auto-notification do managera (button: Akceptuj/Odrzuć)
→ Google Calendar event po akceptacji
→ Aktualizacja channel topic: "Jan (urlop 1-7 cze)"
Team Availability Dashboard:
/kto-jest - rich embed z listą kto jest/nie ma dziś
/zespol-week - plan tygodnia z dostępnością
New Employee Onboarding:
/onboarding @newjoiner
→ Automatyczne zaproszenia do channelów
→ DM z linkami do dokumentów
→ Lista checklisty (confirm each step)
→ Przypomnienia po 1, 7, 30 dniach
Wyniki:
HR admin time: 12h/tydzień → 2h/tydzień (-83%)
Urlopy przez email: 0 (100% przez Slack)
Onboarding time: 3 dni → 4 godziny (-94%)
Manager satisfaction: "Nareszcie porządek"
11. Pełny ekosystem: Multi-Platform Bot Architecture
Dlaczego warto myśleć multi-platform od początku?
Dobrze zaprojektowany bot to platforma, nie tylko kod na jedną usługę. Oto jak buduję architekturę, która pozwala na łatwe dodawanie nowych platform:
// Core Bot Service (platform-agnostic)
interface BotMessage {
userId: string;
platformUserId: string;
platform: 'discord' | 'telegram' | 'slack' | 'whatsapp';
content: string;
metadata?: Record<string, unknown>;
}
interface BotResponse {
text: string;
attachments?: Attachment[];
buttons?: Button[];
metadata?: Record<string, unknown>;
}
// Business logic jest NIEZALEŻNA od platformy
class CommandRouter {
async route(message: BotMessage): Promise<BotResponse> {
if (message.content.startsWith('/help')) {
return this.handleHelp(message);
}
if (message.content.startsWith('/order')) {
return this.handleOrder(message);
}
return this.handleAI(message);
}
}
// Platform adapters tłumaczą na specyficzne API
class DiscordAdapter {
async sendResponse(channelId: string, response: BotResponse) {
const embed = new EmbedBuilder().setDescription(response.text);
await channel.send({ embeds: [embed] });
}
}
class TelegramAdapter {
async sendResponse(chatId: number, response: BotResponse) {
await this.bot.telegram.sendMessage(chatId, response.text, {
parse_mode: 'Markdown'
});
}
}
// Dodanie nowej platformy = nowy adapter. Business logic bez zmian.
class WhatsAppAdapter { /* ... */ }
class TeamsAdapter { /* ... */ }
Roadmapa: Od pierwszego bota do platformy
Faza 1 (Tydzień 1-2): MVP Bot
→ Jeden Discord bot, podstawowe komendy
→ MongoDB dla user data
→ Deploy na Railway
Faza 2 (Tydzień 3-4): Feature Rich
→ Economy system
→ AI integration (GPT-4)
→ Auto-moderation
→ Premium subscriptions (Stripe)
Faza 3 (Miesiąc 2): Multi-Platform
→ Telegram bot (ten sam core, nowy adapter)
→ Slack bot
→ Shared database, shared business logic
Faza 4 (Miesiąc 3+): Platform & Scale
→ Sharding (jeśli 1000+ Discord servers)
→ Dashboard admin (Next.js)
→ Analytics (ile komend dziennie, revenue, etc.)
→ API dla external integrations
Podsumowanie - Bot Development to nie tylko Discord
Przez ostatnie lata boty stały się prawdziwą infrastrukturą biznesową. Nie chodzi już tylko o "bota, który wita nowych memberów". Chodzi o:
- 🔧 Automatyzacje oszczędzające dziesiątki godzin pracy tygodniowo
- 💰 Systemy payments przetwarzające tysiące dolarów dziennie
- 🤖 AI asystentów zastępujących działy customer support
- 📊 Analytics platformy dające wgląd w community behavior
- 🌐 Multi-platform ecosystemy działające jednocześnie na Discord, Telegram, Slack
Każdy projekt jest inny. Czasem potrzebujesz prostego moderation bota w 2 godziny. Czasem zaawansowanej platformy z AI, payments i multi-platform support budowanej przez tygodnie.
Kluczowe lekcje z moich projektów:
- Zawsze zacznij od architektury - trudno przepisać bota gdy ma 10,000 użytkowników
- Redis jest obowiązkowy - baza danych nie wytrzyma rate limitów bez cachingu
- Webhooks > Polling - dla production zawsze webhooks (mniejsze latency, mniej zasobów)
- Graceful shutdown - bot musi umieć się zamknąć bez utraty danych
- Monitoring i alerty - wiedz o problemach zanim użytkownicy zgłoszą
Szukasz custom bota?
Jeśli masz projekt, który wymaga automatyzacji - czy to Discord community, sklep online na Telegramie, czy workflow w Slacku - chętnie porozmawiam.
Tworzę boty od podstaw, z pełnym customizacją, production-ready architekturą i wsparciem post-launch.
Artykuł napisany na podstawie doświadczeń z dziesiątek projektów bot development. Stack użyty w projektach: Discord.js v14, Telegraf v4, Bolt.js, Node.js, TypeScript, MongoDB, Redis, PostgreSQL, Stripe, OpenAI GPT-4.
Powiązane artykuły
KSeF Excel Template: Validator Faktur dla Polskich Firm | Automatyczna Walidacja e-Faktur 2026
# KSeF Excel Template: Jak przestałem tracić 3 godziny dziennie na walidację faktur **Krajowy System e-Faktur (KSeF) to obowiązek**, nie opcja. Od stycznia 20...
NextGen Terminal & File Sync: VS Code Extensions That Transform Your Developer Workflow
# NextGen Terminal & File Sync: How I Built VS Code Extensions That Actually Solve Real Developer Problems **Ever opened VS Code at 2 AM** staring at that def...
Multi-Modal AI Revolution 2025: Vision, Audio & Language - Building Next-Gen AI Systems
# Multi-Modal AI Revolution 2025: Vision, Audio & Language - Building Next-Gen AI Systems **Multi-Modal AI is transforming how machines understand the world.*...