UNPKG

devbotsvotes

Version:

A powerful and feature-rich package for monitoring votes and retrieving information for bots listed on the dev-botlist platform.

214 lines (185 loc) 7.11 kB
const axios = require('axios'); const EventEmitter = require('events'); class VoteNotifier extends EventEmitter { /** * Create a new instance of VoteNotifier * @param {Object} options Configuration options * @param {string} options.botID The ID of the bot to monitor * @param {string} options.token Unique token for authenticating API requests * @param {number} [options.pollingInterval=30000] Interval for API requests (in ms) * @param {boolean} [options.autoRetry=true] Automatically retry on API errors * @param {boolean} [options.debug=false] Enable debug mode for logging */ constructor(options = {}) { super(); if (!options.botID || !options.token) { throw new Error('Both botID and token are required!'); } this.apiUrl = 'https://dev-botlist.com/api'; this.botID = options.botID; this.token = options.token; this.pollingInterval = options.pollingInterval || 30000; this.autoRetry = options.autoRetry !== undefined ? options.autoRetry : true; this.debug = options.debug || false; this.lastCheckedTime = Date.now(); this.lastVoteIds = new Set(); this.isRunning = false; } /** * Log debug messages if debug mode is enabled * @param {string} message Message to log */ logDebug(message) { if (this.debug) { console.log(`[VoteNotifier DEBUG] ${message}`); } } /** * Start monitoring for new votes */ start() { if (this.isRunning) { this.logDebug('Monitoring is already running.'); return; } this.logDebug(`Monitoring started for bot ${this.botID}.`); this.isRunning = true; this.checkVotes(); this.timer = setInterval(() => this.checkVotes(), this.pollingInterval); } /** * Stop monitoring for votes */ stop() { if (!this.isRunning) { this.logDebug('Monitoring is not running.'); return; } this.logDebug(`Monitoring stopped for bot ${this.botID}.`); clearInterval(this.timer); this.isRunning = false; } /** * Send an authenticated API request * @param {string} endpoint API endpoint * @param {Object} params Query parameters * @returns {Promise<Object>} Response data */ async apiRequest(endpoint, params = {}) { try { const response = await axios.get(`${this.apiUrl}/${endpoint}`, { headers: { Authorization: `Bearer ${this.token}` }, params, }); return response.data; } catch (error) { console.error(`[VoteNotifier] API request failed: ${error.message}`); throw error; } } /** * Check the API for new votes */ async checkVotes() { try { const data = await this.apiRequest(`bots/${this.botID}/votes`, { since: this.lastCheckedTime }); const votes = data.votes || []; this.logDebug(`Found ${votes.length} new votes.`); votes.forEach((vote) => { if (!this.lastVoteIds.has(vote._id)) { this.emit('vote', { botID: this.botID, userID: vote.user, voteDate: vote.Date, voteID: vote._id, }); this.lastVoteIds.add(vote._id); } }); this.lastCheckedTime = Date.now(); } catch (error) { console.error(`[VoteNotifier] Error checking votes: ${error.message}`); if (this.autoRetry) { setTimeout(() => this.checkVotes(), this.pollingInterval); } } } /** * Get all votes for the bot * @returns {Promise<Array>} List of all votes */ async getAllVotes() { const data = await this.apiRequest(`bots/${this.botID}`); return data.votes || []; } /** * Check if a user has voted within the last 12 hours * @param {string} userID The ID of the user to check * @returns {Promise<{ hasVoted: boolean, timeRemaining: string }>} Vote status and time remaining */ async hasUserVoted(userID) { try { // Abruf der Votes über die API const data = await this.apiRequest(`bots/${this.botID}/votes`); // Validierung der API-Antwort if (!data || !Array.isArray(data.votes)) { throw new Error('Votes data is not an array.'); } // Suche nach einem Vote des Benutzers const userVote = data.votes.find((vote) => vote.user === userID); if (!userVote) { // Kein Vote gefunden return { hasVoted: false, timeRemaining: null, voteDate: null }; } // Zeitstempel des letzten Votes const lastVoteTime = new Date(userVote.Date).getTime(); const timeSinceLastVote = Date.now() - lastVoteTime; const voteWindowMs = 12 * 60 * 60 * 1000; // 12 Stunden in Millisekunden // Berechnung der verbleibenden Zeit const timeRemainingMs = Math.max(0, voteWindowMs - timeSinceLastVote); const hoursRemaining = Math.floor(timeRemainingMs / (60 * 60 * 1000)); const minutesRemaining = Math.floor((timeRemainingMs % (60 * 60 * 1000)) / (60 * 1000)); const secondsRemaining = Math.floor((timeRemainingMs % (60 * 1000)) / 1000); return { hasVoted: timeSinceLastVote <= voteWindowMs, timeRemaining: `${hoursRemaining}h ${minutesRemaining}m ${secondsRemaining}s`, voteDate: userVote.Date, }; } catch (error) { console.error('[VoteNotifier] Error in hasUserVoted:', error.message); return { hasVoted: false, timeRemaining: null, voteDate: null }; } } /** * Get bot information * @returns {Promise<Object>} Information about the bot */ async getBotInfo() { return this.apiRequest(`bots/${this.botID}`); } /** * Check if the bot is certified * @returns {Promise<boolean>} True if the bot is certified */ async isCertified() { const botInfo = await this.getBotInfo(); return botInfo.certificate === 'Certified'; } /** * Get the top votes for the bot * @returns {Promise<Array>} Top votes with details */ async getTopVotes() { const votes = await this.getAllVotes(); return votes.slice(0, 5); // Return top 5 votes } /** * Update configuration dynamically * @param {Object} newConfig Updated configuration */ updateConfig(newConfig) { Object.assign(this, newConfig); this.logDebug('Configuration updated.'); } } module.exports = VoteNotifier;