UNPKG

aifordiscord-api

Version:

An advanced npm package for Discord bots providing AI-enhanced random content, memes, jokes, and utilities with comprehensive documentation.

632 lines 24.6 kB
"use strict"; /** * Main AIForDiscord class - Advanced AI-enhanced Discord bot utilities */ Object.defineProperty(exports, "__esModule", { value: true }); exports.AIForDiscord = void 0; const cache_1 = require("./utils/cache"); const ratelimit_1 = require("./utils/ratelimit"); const openai_1 = require("./services/openai"); const api_1 = require("./services/api"); /** * AIForDiscord - Advanced AI-enhanced random content generator for Discord bots * * @example * ```typescript * import { AIForDiscord } from 'aifordiscord-api'; * * const random = new AIForDiscord({ * openaiApiKey: 'your-openai-key', * enableCache: true, * enableAI: true * }); * * // Get a meme * const meme = await random.getMeme(); * message.channel.send(meme.url); * ``` */ class AIForDiscord { /** * Create a new AIForDiscord instance * @param options Configuration options */ constructor(options = {}) { this.options = { openaiApiKey: options.openaiApiKey || process.env.OPENAI_API_KEY || '', enableCache: options.enableCache ?? true, cacheTimeout: options.cacheTimeout || 300000, // 5 minutes enableRateLimit: options.enableRateLimit ?? true, rateLimitRequests: options.rateLimitRequests || 100, rateLimitWindow: options.rateLimitWindow || 60000, // 1 minute enableAI: options.enableAI ?? true, contentFilter: options.contentFilter ?? true }; this.cache = new cache_1.SimpleCache(this.options.cacheTimeout); this.rateLimiter = new ratelimit_1.RateLimiter(this.options.rateLimitRequests, this.options.rateLimitWindow); this.aiService = new openai_1.AIService(this.options.openaiApiKey); this.apiService = new api_1.APIService(); } /** * Get a random meme from Reddit */ async getMeme() { const cacheKey = `meme_random_${Date.now()}`; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('meme')) { throw new Error('Rate limit exceeded for meme requests'); } try { const data = await this.apiService.fetchMeme(); const result = { title: data.title, url: data.url, postLink: data.postLink, subreddit: data.subreddit, author: data.author, nsfw: data.nsfw, spoiler: data.spoiler, ups: data.ups }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 5000); // Cache for 5 seconds only } return result; } catch (error) { throw new Error(`Failed to get meme: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get random advice with optional AI enhancement */ async getAdvice() { const cacheKey = `advice_random_${Date.now()}`; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('advice')) { throw new Error('Rate limit exceeded for advice requests'); } try { const data = await this.apiService.fetchAdvice(); let advice = data.slip.advice; // Enhance with AI if enabled if (this.options.enableAI && this.aiService.isEnabled()) { try { advice = await this.aiService.enhanceAdvice(advice); } catch (aiError) { console.warn('AI enhancement failed, using original advice:', aiError instanceof Error ? aiError.message : String(aiError)); } } const result = { advice, slip_id: data.slip.slip_id }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 180000); // Cache for 3 minutes } return result; } catch (error) { throw new Error(`Failed to get advice: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get a random neko (cat girl) image */ async getNeko() { const cacheKey = `neko_random_${Date.now()}`; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('neko')) { throw new Error('Rate limit exceeded for neko requests'); } try { const data = await this.apiService.fetchNeko(); const result = { url: data.url }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 120000); // Cache for 2 minutes } return result; } catch (error) { throw new Error(`Failed to get neko image: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get a random joke with optional AI enhancement */ async getRandomJoke() { const cacheKey = `joke_random_${Date.now()}`; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('joke')) { throw new Error('Rate limit exceeded for joke requests'); } try { const data = await this.apiService.fetchJoke(); let jokeText = data.type === 'twopart' ? `${data.setup} ${data.delivery}` : data.joke; // Enhance with AI if enabled if (this.options.enableAI && this.aiService.isEnabled()) { try { const enhanced = await this.aiService.enhanceJoke(jokeText); if (data.type === 'twopart') { // Try to split enhanced joke back into setup and delivery const parts = enhanced.split(/[.!?]\s+/); if (parts.length >= 2) { data.setup = parts.slice(0, -1).join('. ') + '.'; data.delivery = parts[parts.length - 1]; } else { data.joke = enhanced; data.type = 'single'; } } else { data.joke = enhanced; } } catch (aiError) { console.warn('AI enhancement failed, using original joke:', aiError instanceof Error ? aiError.message : String(aiError)); } } const result = { setup: data.setup, delivery: data.delivery, joke: data.joke, category: data.category, type: data.type, safe: data.safe, id: data.id }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 300000); // Cache for 5 minutes } return result; } catch (error) { throw new Error(`Failed to get joke: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get a name-based joke with AI enhancement */ async getNameJoke(firstName, lastName) { if (!firstName || typeof firstName !== 'string') { throw new Error('First name is required and must be a string'); } const cacheKey = `name_joke_${firstName}_${lastName || ''}`; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('name_joke')) { throw new Error('Rate limit exceeded for name joke requests'); } try { // Get a base joke first const baseJoke = await this.apiService.fetchJoke(); let jokeText = baseJoke.type === 'twopart' ? `${baseJoke.setup} ${baseJoke.delivery}` : baseJoke.joke; const fullName = lastName ? `${firstName} ${lastName}` : firstName; let enhanced = false; // Enhance with AI to incorporate the name if (this.options.enableAI && this.aiService.isEnabled()) { try { jokeText = await this.aiService.enhanceJoke(jokeText, fullName); enhanced = true; } catch (aiError) { console.warn('AI enhancement failed, using template approach:', aiError instanceof Error ? aiError.message : String(aiError)); // Fallback: simple name substitution jokeText = jokeText.replace(/someone|person|guy|girl|man|woman/gi, firstName); } } else { // Simple template approach without AI jokeText = jokeText.replace(/someone|person|guy|girl|man|woman/gi, firstName); } const result = { joke: jokeText, name: fullName, enhanced }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 600000); // Cache for 10 minutes } return result; } catch (error) { throw new Error(`Failed to get name joke: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get a random anime image based on action type */ async getAnimeImgURL(type) { if (!type || typeof type !== 'string') { throw new Error('Type is required and must be a string'); } const cacheKey = `anime_${type}`; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('anime')) { throw new Error('Rate limit exceeded for anime image requests'); } try { const data = await this.apiService.fetchAnimeImage(type.toLowerCase()); const result = { url: data.url, type: type.toLowerCase() }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 180000); // Cache for 3 minutes } return result; } catch (error) { throw new Error(`Failed to get anime image: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get a random fact with optional AI enhancement */ async getFact() { const cacheKey = 'fact_random'; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('fact')) { throw new Error('Rate limit exceeded for fact requests'); } try { const data = await this.apiService.fetchFact(); let fact = data.text; let enhanced = false; // Enhance with AI if enabled if (this.options.enableAI && this.aiService.isEnabled()) { try { fact = await this.aiService.enhanceFact(fact); enhanced = true; } catch (aiError) { console.warn('AI enhancement failed, using original fact:', aiError instanceof Error ? aiError.message : String(aiError)); } } const result = { fact, source: data.source_url || 'Unknown', enhanced }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 900000); // Cache for 15 minutes } return result; } catch (error) { throw new Error(`Failed to get fact: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get information about an NPM package */ async getNPM(packageName) { if (!packageName || typeof packageName !== 'string') { throw new Error('Package name is required and must be a string'); } const cacheKey = `npm_${packageName}`; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('npm')) { throw new Error('Rate limit exceeded for NPM requests'); } try { const data = await this.apiService.fetchNPMInfo(packageName); const result = { name: data.name, version: data['dist-tags']?.latest || 'Unknown', description: data.description || 'No description available', author: typeof data.author === 'string' ? data.author : data.author?.name || 'Unknown', license: data.license || 'Unknown', homepage: data.homepage || data.repository?.url || 'Unknown', repository: data.repository?.url || 'Unknown', lastModified: data.time?.modified || 'Unknown' }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 1800000); // Cache for 30 minutes } return result; } catch (error) { throw new Error(`Failed to get NPM info: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get a random inspirational quote */ async getQuote() { const cacheKey = 'quote_random'; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('quote')) { throw new Error('Rate limit exceeded for quote requests'); } try { const data = await this.apiService.fetchQuote(); const result = { quote: data.content, author: data.author, category: data.tags?.[0] || 'General' }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 600000); // Cache for 10 minutes } return result; } catch (error) { throw new Error(`Failed to get quote: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get a random dog image */ async getDogImage() { const cacheKey = 'dog_random'; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('dog')) { throw new Error('Rate limit exceeded for dog image requests'); } try { const data = await this.apiService.fetchDogImage(); const result = { url: data.message, breed: data.breed || 'Unknown' }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 120000); // Cache for 2 minutes } return result; } catch (error) { throw new Error(`Failed to get dog image: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get a random cat image */ async getCatImage() { const cacheKey = 'cat_random'; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('cat')) { throw new Error('Rate limit exceeded for cat image requests'); } try { const data = await this.apiService.fetchCatImage(); const result = { url: data.url, id: data.id }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 120000); // Cache for 2 minutes } return result; } catch (error) { throw new Error(`Failed to get cat image: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get a trivia question */ async getTrivia(category, difficulty) { const cacheKey = `trivia_${category || 'any'}_${difficulty || 'any'}`; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('trivia')) { throw new Error('Rate limit exceeded for trivia requests'); } try { const data = await this.apiService.fetchTrivia(category, difficulty); const question = data.results[0]; const result = { question: question.question, answers: [...question.incorrect_answers, question.correct_answer].sort(() => Math.random() - 0.5), correctAnswer: question.correct_answer, category: question.category, difficulty: question.difficulty }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 300000); // Cache for 5 minutes } return result; } catch (error) { throw new Error(`Failed to get trivia: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get a dad joke */ async getDadJoke() { const cacheKey = 'dad_joke_random'; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('dad_joke')) { throw new Error('Rate limit exceeded for dad joke requests'); } try { const data = await this.apiService.fetchDadJoke(); const result = { joke: data.joke }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 300000); // Cache for 5 minutes } return result; } catch (error) { throw new Error(`Failed to get dad joke: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get a Chuck Norris joke */ async getChuckNorrisJoke() { const cacheKey = 'chuck_norris_joke_random'; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('chuck_joke')) { throw new Error('Rate limit exceeded for Chuck Norris joke requests'); } try { const data = await this.apiService.fetchChuckNorrisJoke(); const result = { joke: data.value }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 300000); // Cache for 5 minutes } return result; } catch (error) { throw new Error(`Failed to get Chuck Norris joke: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get a compliment */ async getCompliment() { const cacheKey = 'compliment_random'; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('compliment')) { throw new Error('Rate limit exceeded for compliment requests'); } try { const data = await this.apiService.fetchCompliment(); const result = { compliment: data.compliment }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 180000); // Cache for 3 minutes } return result; } catch (error) { throw new Error(`Failed to get compliment: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get an affirmation */ async getAffirmation() { const cacheKey = 'affirmation_random'; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('affirmation')) { throw new Error('Rate limit exceeded for affirmation requests'); } try { const data = await this.apiService.fetchAffirmation(); const result = { affirmation: data.affirmation }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 180000); // Cache for 3 minutes } return result; } catch (error) { throw new Error(`Failed to get affirmation: ${error instanceof Error ? error.message : String(error)}`); } } /** * Get GitHub user information */ async getGitHubUser(username) { if (!username || typeof username !== 'string') { throw new Error('Username is required and must be a string'); } const cacheKey = `github_${username}`; if (this.options.enableCache && this.cache.has(cacheKey)) { return this.cache.get(cacheKey); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('github')) { throw new Error('Rate limit exceeded for GitHub requests'); } try { const data = await this.apiService.fetchGitHubUser(username); const result = { username: data.login, name: data.name, bio: data.bio, location: data.location, company: data.company, blog: data.blog, followers: data.followers, following: data.following, publicRepos: data.public_repos, avatarUrl: data.avatar_url, htmlUrl: data.html_url, createdAt: data.created_at }; if (this.options.enableCache) { this.cache.set(cacheKey, result, 900000); // Cache for 15 minutes } return result; } catch (error) { throw new Error(`Failed to get GitHub user: ${error instanceof Error ? error.message : String(error)}`); } } /** * Generate a custom joke using AI on a specific topic */ async generateCustomJoke(topic) { if (!topic || typeof topic !== 'string') { throw new Error('Topic is required and must be a string'); } if (!this.options.enableAI || !this.aiService.isEnabled()) { throw new Error('AI features are disabled or OpenAI API key not provided'); } if (this.options.enableRateLimit && !this.rateLimiter.isAllowed('custom_joke')) { throw new Error('Rate limit exceeded for custom joke requests'); } try { return await this.aiService.generateCustomJoke(topic); } catch (error) { throw new Error(`Failed to generate custom joke: ${error instanceof Error ? error.message : String(error)}`); } } /** * Clear the internal cache */ clearCache() { this.cache.clear(); } /** * Get current configuration */ getConfig() { return { ...this.options }; } /** * Check if AI features are enabled and available */ isAIEnabled() { return this.options.enableAI && this.aiService.isEnabled(); } } exports.AIForDiscord = AIForDiscord; //# sourceMappingURL=aifordiscord.js.map