您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automate sending messages to Discord DMs or server channels with customizable delay and count.
// ==UserScript== // @name Airpl4ne Discord Spammer // @name:vi Airpl4ne Discord Spammer // @namespace https://twisk.fun // @version 1.0.1 // @description Automate sending messages to Discord DMs or server channels with customizable delay and count. // @description:vi Tự động gửi tin nhắn đến Discord DMs hoặc kênh với có thể chỉnh delay và số lượng. // @author airpl4ne // @match https://discord.com/* // @grant GM_addStyle // @icon https://images-eds-ssl.xboxlive.com/image?url=4rt9.lXDC4H_93laV1_eHHFT949fUipzkiFOBH3fAiZZUCdYojwUyX2aTonS1aIwMrx6NUIsHfUHSLzjGJFxxsG72wAo9EWJR4yQWyJJaDaK1XdUso6cUMpI9hAdPUU_FNs11cY1X284vsHrnWtRw7oqRpN1m9YAg21d_aNKnIo-&format=source // @license MIT // ==/UserScript== // never use it for illegal purposes. // We do not take any responsibility. // if you need help , join our discord : https://discord.gg/m3EV55SpYw // please rate good if this tool is helpful to u! big thanks!<3 (function() { 'use strict'; // css GM_addStyle(` #message-sender-panel { position: fixed; top: 50px; right: 20px; background: #2f3136; color: #dcddde; padding: 15px; border-radius: 8px; z-index: 10000; box-shadow: 0 2px 10px rgba(0,0,0,0.3); font-family: 'Whitney', sans-serif; width: 320px; user-select: none; transition: all 0.3s ease; } #message-sender-panel:hover { box-shadow: 0 4px 15px rgba(0,0,0,0.4); } #panel-header { display: flex; justify-content: space-between; align-items: center; cursor: move; margin-bottom: 10px; } #panel-header h3 { margin: 0; font-size: 16px; font-weight: 600; } #close-btn { background: none; border: none; color: #b9bbbe; cursor: pointer; font-size: 18px; } #close-btn:hover { color: #dcddde; } #message-sender-panel label { display: block; margin: 5px 0 2px; font-size: 12px; color: #b9bbbe; } #message-sender-panel input, #message-sender-panel select, #message-sender-panel textarea { background: #40444b; border: none; border-radius: 3px; color: #dcddde; padding: 8px; width: 100%; box-sizing: border-box; font-size: 14px; margin-bottom: 10px; } #message-sender-panel textarea { resize: vertical; min-height: 50px; } #message-sender-panel button { background: #5865f2; color: white; border: none; border-radius: 3px; padding: 8px; cursor: pointer; font-size: 14px; width: 100%; margin: 5px 0; transition: background 0.2s; } #message-sender-panel button:hover { background: #4752c4; } #message-sender-panel button:disabled { background: #72767d; cursor: not-allowed; } #stop-btn { background: #ed4245; } #stop-btn:hover { background: #da373c; } #status { margin-top: 10px; font-size: 12px; color: #43b581; } .error { color: #f04747 !important; } .hidden { display: none; } `); // create css function createPanel() { const panel = document.createElement('div'); panel.id = 'message-sender-panel'; panel.innerHTML = ` <div id="panel-header"> <h3>Airpl4ne Spammer</h3> <button id="close-btn">×</button> </div> <label for="target-type">Target Type:</label> <select id="target-type"> <option value="dm">DM (User ID)</option> <option value="channel">Server Channel (Channel ID)</option> </select> <div id="dm-input"> <label for="user-id">User ID:</label> <input type="text" id="user-id" placeholder="Enter User ID (e.g., 123456789012345678)"> </div> <div id="channel-input" class="hidden"> <label for="channel-id">Channel ID:</label> <input type="text" id="channel-id" placeholder="Enter Channel ID (e.g., 987654321098765432)"> </div> <label for="message-content">Message:</label> <textarea id="message-content" placeholder="Enter message (supports multi-line)"></textarea> <div style="display: flex; justify-content: space-between;"> <div style="width: 48%;"> <label for="delay">Delay (ms):</label> <input type="number" id="delay" value="1000" min="500"> </div> <div style="width: 48%;"> <label for="count">Count:</label> <input type="number" id="count" value="1" min="1"> </div> </div> <button id="start-btn">Start Sending</button> <button id="stop-btn" class="hidden">Stop Sending</button> <div id="status"></div> `; document.body.appendChild(panel); // event document.getElementById('start-btn').addEventListener('click', startSending); document.getElementById('stop-btn').addEventListener('click', stopSending); document.getElementById('close-btn').addEventListener('click', () => panel.remove()); document.getElementById('target-type').addEventListener('change', toggleInputs); // drag makeDraggable(panel); toggleInputs(); // Initial setup } // inputs function toggleInputs() { const type = document.getElementById('target-type').value; document.getElementById('dm-input').classList.toggle('hidden', type !== 'dm'); document.getElementById('channel-input').classList.toggle('hidden', type !== 'channel'); } // element drag function makeDraggable(element) { const header = document.getElementById('panel-header'); let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; header.onmousedown = dragMouseDown; function dragMouseDown(e) { e.preventDefault(); pos3 = e.clientX; pos4 = e.clientY; document.onmouseup = closeDragElement; document.onmousemove = elementDrag; } function elementDrag(e) { e.preventDefault(); pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; element.style.top = (element.offsetTop - pos2) + "px"; element.style.left = (element.offsetLeft - pos1) + "px"; } function closeDragElement() { document.onmouseup = null; document.onmousemove = null; } } // discord auth function getAuthToken() { let token = localStorage.getItem('token'); if (!token) { updateStatus('Error: No authorization token found. Please log in to Discord.', true); return null; } return token.replace(/"/g, ''); } // status function updateStatus(message, isError = false) { const statusDiv = document.getElementById('status'); statusDiv.textContent = message; statusDiv.className = isError ? 'error' : ''; } // vali id function validateId(id) { return /^\d{17,19}$/.test(id); } // api async function sendMessage(channelId, message, authToken) { const url = `https://discord.com/api/v10/channels/${channelId}/messages`; const payload = { content: message, tts: false, nonce: Date.now().toString() + Math.floor(Math.random() * 1000).toString() }; try { const response = await fetch(url, { method: 'POST', headers: { 'Authorization': authToken, 'Content-Type': 'application/json', 'User-Agent': navigator.userAgent }, body: JSON.stringify(payload) }); if (response.ok) { return true; } else { const error = await response.json(); updateStatus(`Error: ${error.message || 'Failed to send message'}`, true); return false; } } catch (error) { updateStatus(`Error: ${error.message}`, true); return false; } } // sendinh let isSending = false; let sentCount = 0; async function startSending() { if (isSending) return; const type = document.getElementById('target-type').value; let targetId = type === 'dm' ? document.getElementById('user-id').value.trim() : document.getElementById('channel-id').value.trim(); const message = document.getElementById('message-content').value.trim(); const delay = parseInt(document.getElementById('delay').value); const count = parseInt(document.getElementById('count').value); const authToken = getAuthToken(); if (!authToken) return; if (!message) { updateStatus('Error: Please enter a message.', true); return; } if (!targetId) { updateStatus(`Error: Please enter a ${type === 'dm' ? 'User ID' : 'Channel ID'}.`, true); return; } if (!validateId(targetId)) { updateStatus('Error: Invalid ID format (must be 17-19 digits).', true); return; } if (delay < 500) { updateStatus('Warning: Delay set to minimum 500ms to avoid rate limits.', true); document.getElementById('delay').value = 500; } let channelId = targetId; if (type === 'dm') { channelId = await getDMChannelId(targetId, authToken); if (!channelId) return; } isSending = true; sentCount = 0; document.getElementById('start-btn').disabled = true; document.getElementById('stop-btn').classList.remove('hidden'); updateStatus(`Sending messages... (0/${count})`); for (let i = 0; i < count && isSending; i++) { const success = await sendMessage(channelId, message, authToken); if (!success) break; sentCount++; updateStatus(`Sending messages... (${sentCount}/${count})`); if (i < count - 1) { await new Promise(resolve => setTimeout(resolve, delay)); } } isSending = false; document.getElementById('start-btn').disabled = false; document.getElementById('stop-btn').classList.add('hidden'); updateStatus(`Finished sending ${sentCount} message(s).`); } // stop function stopSending() { isSending = false; updateStatus(`Stopped after sending ${sentCount} message(s).`); document.getElementById('start-btn').disabled = false; document.getElementById('stop-btn').classList.add('hidden'); } //get id async function getDMChannelId(userId, authToken) { const url = 'https://discord.com/api/v10/users/@me/channels'; const payload = { recipient_id: userId }; try { const response = await fetch(url, { method: 'POST', headers: { 'Authorization': authToken, 'Content-Type': 'application/json', 'User-Agent': navigator.userAgent }, body: JSON.stringify(payload) }); if (response.ok) { const data = await response.json(); return data.id; } else { const error = await response.json(); updateStatus(`Error creating DM channel: ${error.message || error.code}`, true); return null; } } catch (error) { updateStatus(`Error: ${error.message}`, true); return null; } } // bye bye! if (window.location.href.includes('discord.com')) { createPanel(); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址