class WebhookSpammer { constructor() { this.isRunning = false; this.currentProgress = 0; this.totalMessages = 0; this.sentMessages = 0; this.failedMessages = 0; this.initializeElements(); this.bindEvents(); } initializeElements() { this.webhookUrlsInput = document.getElementById('webhookUrls'); this.messageInput = document.getElementById('message'); this.webhookUsernameInput = document.getElementById('webhookUsername'); this.webhookAvatarInput = document.getElementById('webhookAvatar'); this.repeatCountInput = document.getElementById('repeatCount'); this.sendModeSelect = document.getElementById('sendMode'); this.delayInput = document.getElementById('delay'); this.delayGroup = document.getElementById('delayGroup'); this.sendBtn = document.getElementById('sendBtn'); this.stopBtn = document.getElementById('stopBtn'); this.statusBox = document.getElementById('status'); this.progressContainer = document.querySelector('.progress-container'); this.progressFill = document.getElementById('progressFill'); this.progressText = document.getElementById('progressText'); this.resultsBox = document.getElementById('results'); } bindEvents() { this.sendBtn.addEventListener('click', () => this.startSpamming()); this.stopBtn.addEventListener('click', () => this.stopSpamming()); // Show/hide delay group based on send mode this.sendModeSelect.addEventListener('change', () => this.toggleDelayGroup()); } async startSpamming() { if (this.isRunning) { return; } // التحقق من صحة المدخلات if (!this.validateInputs()) { return; } this.isRunning = true; this.sendBtn.style.display = 'none'; this.stopBtn.style.display = 'block'; // Reset counters this.resetCounters(); // Show progress bar this.showProgress(); // Get data const webhookUrls = this.getWebhookUrls(); if (webhookUrls.length === 0) { this.isRunning = false; this.sendBtn.style.display = 'block'; this.stopBtn.style.display = 'none'; return; } const message = this.messageInput.value.trim(); const repeatCount = parseInt(this.repeatCountInput.value); const sendMode = this.sendModeSelect.value; const delay = parseInt(this.delayInput.value); this.totalMessages = webhookUrls.length * repeatCount; // Start sending if (sendMode === 'parallel') { await this.sendMessagesParallel(webhookUrls, message, repeatCount); } else { await this.sendMessagesSequential(webhookUrls, message, repeatCount, delay); } // Reset button this.isRunning = false; this.sendBtn.style.display = 'block'; this.stopBtn.style.display = 'none'; // Hide progress bar this.hideProgress(); // Show final results this.showFinalResults(); } validateInputs() { const webhookUrls = this.webhookUrlsInput.value.trim(); const message = this.messageInput.value.trim(); const repeatCount = parseInt(this.repeatCountInput.value); const delay = parseInt(this.delayInput.value); if (!webhookUrls) { this.showError('Please enter at least one webhook URL'); return false; } if (!message) { this.showError('Please enter a message to send'); return false; } if (repeatCount < 1 || repeatCount > 100) { this.showError('Repeat count must be between 1 and 100'); return false; } if (delay < 0 || delay > 10000) { this.showError('Delay must be between 0 and 10000 milliseconds'); return false; } return true; } getWebhookUrls() { const urls = this.webhookUrlsInput.value.trim().split('\n'); const validUrls = urls .map(url => url.trim()) .filter(url => url && this.isValidWebhookUrl(url)); if (validUrls.length === 0) { this.showError('No valid webhook URLs found'); return []; } return validUrls; } isValidWebhookUrl(url) { return url.startsWith('https://discord.com/api/webhooks/') || url.startsWith('https://canary.discord.com/api/webhooks/') || url.startsWith('https://ptb.discord.com/api/webhooks/'); } async sendMessagesParallel(webhookUrls, message, repeatCount) { this.updateStatus(`Starting to send ${this.totalMessages} messages to ${webhookUrls.length} webhooks simultaneously...`); // Create array of all messages to be sent const allMessages = []; for (let i = 0; i < webhookUrls.length; i++) { for (let j = 0; j < repeatCount; j++) { allMessages.push({ webhookUrl: webhookUrls[i], webhookIndex: i + 1, messageIndex: j + 1 }); } } // Send all messages at the same time const promises = allMessages.map(async (msgData) => { if (!this.isRunning) return; try { await this.sendSingleMessage(msgData.webhookUrl, message, msgData.webhookIndex, msgData.messageIndex); this.sentMessages++; this.addResult(`Message ${msgData.messageIndex} sent to webhook ${msgData.webhookIndex} successfully`, 'success'); } catch (error) { this.failedMessages++; this.addResult(`Failed to send message ${msgData.messageIndex} to webhook ${msgData.webhookIndex}: ${error.message}`, 'error'); } this.updateProgress(); }); // Wait for all messages to complete await Promise.allSettled(promises); } async sendMessagesSequential(webhookUrls, message, repeatCount, delay) { this.updateStatus(`Starting to send ${this.totalMessages} messages to ${webhookUrls.length} webhooks one by one...`); for (let i = 0; i < webhookUrls.length; i++) { const webhookUrl = webhookUrls[i]; for (let j = 0; j < repeatCount; j++) { if (!this.isRunning) { this.updateStatus('Sending stopped by user'); return; } try { await this.sendSingleMessage(webhookUrl, message, i + 1, j + 1); this.sentMessages++; this.addResult(`Message ${j + 1} sent to webhook ${i + 1} successfully`, 'success'); } catch (error) { this.failedMessages++; this.addResult(`Failed to send message ${j + 1} to webhook ${i + 1}: ${error.message}`, 'error'); } this.updateProgress(); // Delay between messages if (delay > 0 && (i < webhookUrls.length - 1 || j < repeatCount - 1)) { await this.sleep(delay); } } } } async sendSingleMessage(webhookUrl, message, webhookIndex, messageIndex) { // Get custom username and avatar const customUsername = this.webhookUsernameInput.value.trim(); const customAvatar = this.webhookAvatarInput.value.trim(); const payload = { content: message, username: customUsername || `Korlix Bot - ${webhookIndex}`, avatar_url: customAvatar || 'https://cdn.discordapp.com/embed/avatars/0.png' }; const response = await fetch(webhookUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(payload) }); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } } updateStatus(message) { this.statusBox.innerHTML = `

${message}

`; } updateProgress() { this.currentProgress++; const percentage = Math.round((this.currentProgress / this.totalMessages) * 100); this.progressFill.style.width = `${percentage}%`; this.progressText.textContent = `${percentage}%`; this.updateStatus(`Sent ${this.currentProgress} of ${this.totalMessages} messages (${this.sentMessages} success, ${this.failedMessages} failed)`); } showProgress() { this.progressContainer.style.display = 'block'; this.progressFill.style.width = '0%'; this.progressText.textContent = '0%'; } hideProgress() { this.progressContainer.style.display = 'none'; } addResult(message, type = 'info') { const resultItem = document.createElement('div'); resultItem.className = `result-item ${type}`; resultItem.innerHTML = ` ${type === 'success' ? '✅' : type === 'error' ? '❌' : 'ℹ️'} ${message} `; this.resultsBox.appendChild(resultItem); this.resultsBox.scrollTop = this.resultsBox.scrollHeight; } showFinalResults() { const successRate = this.totalMessages > 0 ? Math.round((this.sentMessages / this.totalMessages) * 100) : 0; this.updateStatus(`Sending completed! ${this.sentMessages} messages succeeded, ${this.failedMessages} failed (Success rate: ${successRate}%)`); if (this.failedMessages > 0) { this.addResult(`Note: ${this.failedMessages} messages failed to send. Check webhook URLs validity`, 'warning'); } } showError(message) { this.updateStatus(`خطأ: ${message}`); this.addResult(`خطأ: ${message}`, 'error'); } resetCounters() { this.currentProgress = 0; this.sentMessages = 0; this.failedMessages = 0; // Clear previous results this.resultsBox.innerHTML = '

Starting new sending process...

'; } sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } stopSpamming() { this.isRunning = false; this.sendBtn.style.display = 'block'; this.stopBtn.style.display = 'none'; this.updateStatus('Sending stopped by user'); } toggleDelayGroup() { const sendMode = this.sendModeSelect.value; if (sendMode === 'parallel') { this.delayGroup.style.display = 'none'; } else { this.delayGroup.style.display = 'block'; } } } // تهيئة التطبيق document.addEventListener('DOMContentLoaded', () => { const spammer = new WebhookSpammer(); window.webhookSpammer = spammer; // Store object in window to access from other functions // Save settings on change const inputs = ['webhookUrls', 'message', 'webhookUsername', 'webhookAvatar', 'repeatCount', 'sendMode', 'delay']; inputs.forEach(id => { document.getElementById(id).addEventListener('input', saveSettings); }); // Load saved settings loadSettings(); // Apply show/hide delay group on load spammer.toggleDelayGroup(); }); // Add feature to save settings in local storage function saveSettings() { const settings = { webhookUrls: document.getElementById('webhookUrls').value, message: document.getElementById('message').value, webhookUsername: document.getElementById('webhookUsername').value, webhookAvatar: document.getElementById('webhookAvatar').value, repeatCount: document.getElementById('repeatCount').value, sendMode: document.getElementById('sendMode').value, delay: document.getElementById('delay').value }; localStorage.setItem('webhookSpammerSettings', JSON.stringify(settings)); } function loadSettings() { const saved = localStorage.getItem('webhookSpammerSettings'); if (saved) { const settings = JSON.parse(saved); document.getElementById('webhookUrls').value = settings.webhookUrls || ''; document.getElementById('message').value = settings.message || ''; document.getElementById('webhookUsername').value = settings.webhookUsername || 'Korlix Bot'; document.getElementById('webhookAvatar').value = settings.webhookAvatar || 'https://cdn.discordapp.com/embed/avatars/0.png'; document.getElementById('repeatCount').value = settings.repeatCount || '1'; document.getElementById('sendMode').value = settings.sendMode || 'parallel'; document.getElementById('delay').value = settings.delay || '1000'; // Apply show/hide delay group const spammer = window.webhookSpammer; if (spammer) { spammer.toggleDelayGroup(); } } } // Save settings on change document.addEventListener('DOMContentLoaded', () => { loadSettings(); const inputs = ['webhookUrls', 'message', 'repeatCount', 'delay']; inputs.forEach(id => { document.getElementById(id).addEventListener('input', saveSettings); }); }); // Add feature to import/export settings function exportSettings() { const settings = { webhookUrls: document.getElementById('webhookUrls').value, message: document.getElementById('message').value, webhookUsername: document.getElementById('webhookUsername').value, webhookAvatar: document.getElementById('webhookAvatar').value, repeatCount: document.getElementById('repeatCount').value, sendMode: document.getElementById('sendMode').value, delay: document.getElementById('delay').value }; const dataStr = JSON.stringify(settings, null, 2); const dataBlob = new Blob([dataStr], {type: 'application/json'}); const link = document.createElement('a'); link.href = URL.createObjectURL(dataBlob); link.download = 'korlix-webhook-spammer-settings.json'; link.click(); } function importSettings() { const input = document.createElement('input'); input.type = 'file'; input.accept = '.json'; input.onchange = function(e) { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = function(e) { try { const settings = JSON.parse(e.target.result); document.getElementById('webhookUrls').value = settings.webhookUrls || ''; document.getElementById('message').value = settings.message || ''; document.getElementById('webhookUsername').value = settings.webhookUsername || 'Korlix Bot'; document.getElementById('webhookAvatar').value = settings.webhookAvatar || 'https://cdn.discordapp.com/embed/avatars/0.png'; document.getElementById('repeatCount').value = settings.repeatCount || '1'; document.getElementById('sendMode').value = settings.sendMode || 'parallel'; document.getElementById('delay').value = settings.delay || '1000'; saveSettings(); // Apply show/hide delay group const spammer = window.webhookSpammer; if (spammer) { spammer.toggleDelayGroup(); } alert('Settings imported successfully!'); } catch (error) { alert('Error reading settings file'); } }; reader.readAsText(file); } }; input.click(); }