API Reference
This section documents the internal APIs and interfaces used in BarStrad-Bot.
Core Classes
Bot Class
Main bot class that handles Discord integration and command processing.
class Bot {
private client: Client;
private menu: Menu;
private notificationService: DiscordNotificationService;
constructor();
initialize(): Promise<void>;
handleMessage(message: Message): Promise<void>;
}
Methods:
initialize()
- Initializes the Discord client and connects to the serverhandleMessage(message)
- Processes incoming Discord messages and executes commands
Menu Class
Manages menu data loading, language switching, and display formatting.
class Menu {
private data: MenuData;
private currentLanguage: string;
constructor();
setLanguage(language: string): void;
getCurrentLanguage(): string;
getMenuDisplay(): string;
getItem(index: number): MenuItem | null;
getTotalItems(): number;
}
Methods:
setLanguage(language)
- Changes the active menu language ('bg' or 'en')getCurrentLanguage()
- Returns the currently active languagegetMenuDisplay()
- Returns formatted menu string for Discord displaygetItem(index)
- Retrieves menu item by index numbergetTotalItems()
- Returns total number of menu items across all categories
DiscordNotificationService
Handles webhook notifications for order processing.
class DiscordNotificationService {
private webhookUrl: string;
constructor(webhookUrl: string);
sendOrderNotification(order: OrderData): Promise<void>;
sendErrorNotification(error: string): Promise<void>;
}
Methods:
sendOrderNotification(order)
- Sends order confirmation to Discord webhooksendErrorNotification(error)
- Sends error notifications to Discord webhook
Data Models
MenuData Interface
Represents the complete menu structure.
interface MenuData {
categories: MenuCategory[];
}
MenuCategory Interface
Represents a menu category with items.
interface MenuCategory {
name: string;
items: MenuItem[];
}
MenuItem Interface
Represents an individual menu item.
interface MenuItem {
name: string;
price: number;
description?: string;
available?: boolean;
}
OrderData Interface
Represents an order placed by a customer.
interface OrderData {
itemNumber: number;
itemName: string;
customerName: string;
price: number;
timestamp: Date;
language: string;
}
Environment Configuration
Environment Interface
Defines the environment configuration structure.
interface Environment {
production: boolean;
discordBotToken: string;
discordWebhookUrl: string;
debug: boolean;
}
Command Processing
Command Types
The bot recognizes the following command patterns:
type CommandType = 'menu' | 'menu-en' | 'order' | 'help';
interface Command {
type: CommandType;
parameters: string[];
message: Message;
}
Command Handlers
Each command type has a dedicated handler:
interface CommandHandler {
handle(command: Command): Promise<string>;
}
Menu Command Handler:
class MenuCommandHandler implements CommandHandler {
async handle(command: Command): Promise<string> {
// Returns formatted menu display
}
}
Order Command Handler:
class OrderCommandHandler implements CommandHandler {
async handle(command: Command): Promise<string> {
// Processes order and sends notifications
}
}
Error Handling
Custom Error Types
class BotError extends Error {
constructor(message: string, public code: string) {
super(message);
this.name = 'BotError';
}
}
class MenuError extends BotError {
constructor(message: string) {
super(message, 'MENU_ERROR');
}
}
class OrderError extends BotError {
constructor(message: string) {
super(message, 'ORDER_ERROR');
}
}
class WebhookError extends BotError {
constructor(message: string) {
super(message, 'WEBHOOK_ERROR');
}
}
Utility Functions
Menu Formatting
function formatMenuItem(item: MenuItem, index: number): string {
return `${index}. ${item.name} - ${item.price.toFixed(2)} лв.`;
}
function formatMenuCategory(category: MenuCategory, startIndex: number): string {
const header = `**${category.name}**\n`;
const items = category.items
.map((item, index) => formatMenuItem(item, startIndex + index))
.join('\n');
return header + items;
}
Order Processing
function parseOrderCommand(content: string): OrderData | null {
const match = content.match(/^!order (\d+) (.+)$/);
if (!match) return null;
return {
itemNumber: parseInt(match[1]),
customerName: match[2].trim(),
timestamp: new Date()
};
}
function validateOrder(order: OrderData, menu: Menu): boolean {
const totalItems = menu.getTotalItems();
return order.itemNumber >= 1 && order.itemNumber <= totalItems;
}
Discord Integration
Client Configuration
const clientConfig: ClientOptions = {
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent
]
};
Event Handlers
interface EventHandlers {
ready: () => void;
messageCreate: (message: Message) => Promise<void>;
error: (error: Error) => void;
}
Webhook Integration
Webhook Message Format
interface WebhookMessage {
content?: string;
embeds?: WebhookEmbed[];
username?: string;
avatar_url?: string;
}
interface WebhookEmbed {
title?: string;
description?: string;
color?: number;
fields?: WebhookEmbedField[];
timestamp?: string;
}
interface WebhookEmbedField {
name: string;
value: string;
inline?: boolean;
}
File System Operations
Menu File Loading
function loadMenuFile(language: string): MenuCategory[] {
const filePath = path.join(__dirname, 'data', `menu-items.${language}.json`);
try {
const fileContent = fs.readFileSync(filePath, 'utf-8');
return JSON.parse(fileContent);
} catch (error) {
throw new MenuError(`Failed to load menu file: ${error.message}`);
}
}
Constants
Application Constants
const Constants = {
// Command prefixes
COMMAND_PREFIX: '!',
// Supported languages
SUPPORTED_LANGUAGES: ['bg', 'en'],
DEFAULT_LANGUAGE: 'bg',
// Menu display limits
MAX_MESSAGE_LENGTH: 2000,
ITEMS_PER_MESSAGE: 50,
// Order processing
MAX_CUSTOMER_NAME_LENGTH: 100,
MIN_CUSTOMER_NAME_LENGTH: 2,
// Response messages
MESSAGES: {
MENU_LOADED: '✅ Menu loaded successfully',
ORDER_PROCESSED: '✅ Order processed successfully',
INVALID_COMMAND: '❌ Invalid command format',
ITEM_NOT_FOUND: '❌ Item not found',
ORDER_FAILED: '❌ Failed to process order'
}
};
Logging
Logger Interface
interface Logger {
info(message: string, meta?: any): void;
warn(message: string, meta?: any): void;
error(message: string, error?: Error): void;
debug(message: string, meta?: any): void;
}
Console Logger Implementation
class ConsoleLogger implements Logger {
info(message: string, meta?: any): void {
console.log(`ℹ️ ${new Date().toISOString()} - ${message}`, meta || '');
}
warn(message: string, meta?: any): void {
console.warn(`⚠️ ${new Date().toISOString()} - ${message}`, meta || '');
}
error(message: string, error?: Error): void {
console.error(`❌ ${new Date().toISOString()} - ${message}`, error || '');
}
debug(message: string, meta?: any): void {
if (process.env.DEBUG === 'true') {
console.debug(`🐛 ${new Date().toISOString()} - ${message}`, meta || '');
}
}
}
Performance Monitoring
Performance Metrics
interface PerformanceMetrics {
commandProcessingTime: number;
menuLoadTime: number;
webhookResponseTime: number;
memoryUsage: NodeJS.MemoryUsage;
}
class PerformanceMonitor {
private metrics: PerformanceMetrics;
startTimer(operation: string): () => number;
recordMetric(name: string, value: number): void;
getMetrics(): PerformanceMetrics;
}
Configuration Management
Configuration Interface
interface BotConfiguration {
discord: {
token: string;
webhookUrl: string;
commandPrefix: string;
};
menu: {
defaultLanguage: string;
supportedLanguages: string[];
dataPath: string;
};
logging: {
level: string;
enabled: boolean;
};
performance: {
enableMetrics: boolean;
metricsInterval: number;
};
}
Testing Utilities
Mock Objects
class MockMessage implements Partial<Message> {
content: string;
author: User;
channel: TextChannel;
constructor(content: string, author: User, channel: TextChannel) {
this.content = content;
this.author = author;
this.channel = channel;
}
}
class MockDiscordClient implements Partial<Client> {
user: ClientUser | null = null;
login(token: string): Promise<string> {
return Promise.resolve(token);
}
on(event: string, listener: Function): this {
return this;
}
}
Test Helpers
function createTestMenu(): Menu {
const menu = new Menu();
// Set up test data
return menu;
}
function createTestOrder(itemNumber: number, customerName: string): OrderData {
return {
itemNumber,
customerName,
timestamp: new Date(),
language: 'bg',
itemName: `Test Item ${itemNumber}`,
price: 10.50
};
}
This API reference provides a comprehensive overview of the BarStrad-Bot internal structure. For implementation details, refer to the source code and development documentation.