Skip to main content

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 server
  • handleMessage(message) - Processes incoming Discord messages and executes commands

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 language
  • getMenuDisplay() - Returns formatted menu string for Discord display
  • getItem(index) - Retrieves menu item by index number
  • getTotalItems() - 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 webhook
  • sendErrorNotification(error) - Sends error notifications to Discord webhook

Data Models

Represents the complete menu structure.

interface MenuData {
categories: MenuCategory[];
}

Represents a menu category with items.

interface MenuCategory {
name: string;
items: MenuItem[];
}

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

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

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.