// ==UserScript==
// @name Discord DM Sender with Input Box
// @namespace http://tampermonkey.net/
// @version 1.7
// @description Send DM messages via Discord API
// @author Your Name
// @match https://discord.com/*
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @license You can modify as long as you credit me
// ==/UserScript==
(function() {
'use strict';
let channelId = '';
const initialWidth = '280px';
const initialHeight = '450px';
const container = document.createElement('div');
container.style.position = 'fixed';
container.style.bottom = '10px';
container.style.left = '10px';
container.style.backgroundColor = '#2f3136';
container.style.color = '#ffffff';
container.style.padding = '10px';
container.style.borderRadius = '5px';
container.style.zIndex = '1000';
container.style.width = initialWidth;
container.style.height = initialHeight;
container.style.maxHeight = '90vh';
container.style.overflow = 'auto';
document.body.appendChild(container);
makeElementDraggable(container);
const tokenBox = document.createElement('textarea');
tokenBox.placeholder = 'Enter your token';
tokenBox.style.width = '100%';
tokenBox.style.height = '40px';
tokenBox.style.resize = 'none';
tokenBox.style.backgroundColor = '#000000';
tokenBox.style.color = '#00FF00';
container.appendChild(tokenBox);
const hideTokenButton = document.createElement('button');
hideTokenButton.innerText = 'Hide Token';
hideTokenButton.style.marginTop = '10px';
hideTokenButton.style.width = '100%';
hideTokenButton.style.backgroundColor = '#575757';
hideTokenButton.style.color = '#ffffff';
hideTokenButton.style.border = 'none';
hideTokenButton.style.borderRadius = '3px';
hideTokenButton.style.cursor = 'pointer';
container.appendChild(hideTokenButton);
hideTokenButton.addEventListener('click', () => {
if (tokenBox.style.display === 'none') {
tokenBox.style.display = 'block';
hideTokenButton.innerText = 'Hide Token';
} else {
tokenBox.style.display = 'none';
hideTokenButton.innerText = 'Show Token';
}
});
const inputBox = document.createElement('textarea');
inputBox.placeholder = 'Enter your secret message to aarr';
inputBox.style.width = '100%';
inputBox.style.height = '100px';
inputBox.style.resize = 'none';
inputBox.style.backgroundColor = '#000000';
inputBox.style.color = '#00FF00';
container.appendChild(inputBox);
const channelBox1 = document.createElement('textarea');
channelBox1.placeholder = '荒らし雑談のBOTのDMチャンネルIDを入力';
channelBox1.style.width = '100%';
channelBox1.style.height = '40px';
channelBox1.style.resize = 'none';
channelBox1.style.backgroundColor = '#000000';
channelBox1.style.color = '#00FF00';
container.appendChild(channelBox1);
const channelBox2 = document.createElement('textarea');
channelBox2.placeholder = '情勢雑談のBOTのDMチャンネルIDを入力';
channelBox2.style.width = '100%';
channelBox2.style.height = '40px';
channelBox2.style.resize = 'none';
channelBox2.style.backgroundColor = '#000000';
channelBox2.style.color = '#00FF00';
container.appendChild(channelBox2);
const channelBox3 = document.createElement('textarea');
channelBox3.placeholder = '依頼支部のBOTのDMチャンネルIDを入力';
channelBox3.style.width = '100%';
channelBox3.style.height = '40px';
channelBox3.style.resize = 'none';
channelBox3.style.backgroundColor = '#000000';
channelBox3.style.color = '#00FF00';
container.appendChild(channelBox3);
const button = document.createElement('button');
button.innerText = 'Send DM';
button.style.marginTop = '10px';
button.style.width = '100%';
button.style.backgroundColor = '#575757';
button.style.color = '#ffffff';
button.style.border = 'none';
button.style.borderRadius = '3px';
button.style.cursor = 'pointer';
container.appendChild(button);
const buttonContainer = document.createElement('div');
buttonContainer.style.marginTop = '10px';
buttonContainer.style.display = 'flex';
buttonContainer.style.justifyContent = 'space-between';
const channelButton1 = document.createElement('button');
channelButton1.innerText = '1荒らし雑談';
channelButton1.style.width = '30%';
channelButton1.style.backgroundColor = '#575757';
channelButton1.style.color = '#ffffff';
channelButton1.style.border = 'none';
channelButton1.style.borderRadius = '3px';
channelButton1.style.cursor = 'pointer';
channelButton1.addEventListener('click', () => {
channelId = channelBox1.value.trim();
updateButtonStyles(channelButton1);
GM_setValue('channelBox1Value', channelId);
});
const channelButton2 = document.createElement('button');
channelButton2.innerText = '2情勢雑談';
channelButton2.style.width = '30%';
channelButton2.style.backgroundColor = '#575757';
channelButton2.style.color = '#ffffff';
channelButton2.style.border = 'none';
channelButton2.style.borderRadius = '3px';
channelButton2.style.cursor = 'pointer';
channelButton2.addEventListener('click', () => {
channelId = channelBox2.value.trim();
updateButtonStyles(channelButton2);
GM_setValue('channelBox2Value', channelId);
});
const channelButton3 = document.createElement('button');
channelButton3.innerText = '3依頼版';
channelButton3.style.width = '30%';
channelButton3.style.backgroundColor = '#575757';
channelButton3.style.color = '#ffffff';
channelButton3.style.border = 'none';
channelButton3.style.borderRadius = '3px';
channelButton3.style.cursor = 'pointer';
channelButton3.addEventListener('click', () => {
channelId = channelBox3.value.trim();
updateButtonStyles(channelButton3);
GM_setValue('channelBox3Value', channelId);
});
buttonContainer.appendChild(channelButton1);
buttonContainer.appendChild(channelButton2);
buttonContainer.appendChild(channelButton3);
container.appendChild(buttonContainer);
function updateButtonStyles(activeButton) {
[channelButton1, channelButton2, channelButton3].forEach(button => {
if (button === activeButton) {
button.style.backgroundColor = '#047500';
} else {
button.style.backgroundColor = '#575757';
}
});
}
inputBox.value = GM_getValue('inputBoxValue', '');
tokenBox.value = GM_getValue('tokenBoxValue', '');
channelBox1.value = GM_getValue('channelBox1Value', '');
channelBox2.value = GM_getValue('channelBox2Value', '');
channelBox3.value = GM_getValue('channelBox3Value', '');
async function sendDM() {
const token = tokenBox.value.trim();
if (!token) {
alert('Token is required');
return;
}
const message = inputBox.value.trim();
if (!message) {
alert('Message cannot be empty');
return;
}
tokenBox.style.display = 'none';
GM_setValue('tokenBoxValue', token);
const success = await sendMessage(channelId, message, token);
if (success) {
inputBox.value = '';
GM_setValue('inputBoxValue', '');
} else {
alert('Failed to send message');
}
}
button.addEventListener('click', sendDM);
inputBox.addEventListener('keydown', (event) => {
if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault();
sendDM();
} else if (event.key === 'Enter' && event.shiftKey) {
event.preventDefault();
const cursorPos = inputBox.selectionStart;
const textBefore = inputBox.value.substring(0, cursorPos);
const textAfter = inputBox.value.substring(cursorPos);
inputBox.value = `${textBefore}\n${textAfter}`;
inputBox.selectionStart = cursorPos + 1;
inputBox.selectionEnd = cursorPos + 1;
}
});
inputBox.addEventListener('input', () => {
GM_setValue('inputBoxValue', inputBox.value);
});
tokenBox.addEventListener('input', () => {
GM_setValue('tokenBoxValue', tokenBox.value);
});
function makeElementDraggable(el) {
el.onmousedown = function(event) {
if (event.target === inputBox || event.target === tokenBox || event.target === channelBox1 || event.target === channelBox2 || event.target === channelBox3) {
return;
}
event.preventDefault();
let shiftX = event.clientX - el.getBoundingClientRect().left;
let shiftY = event.clientY - el.getBoundingClientRect().top;
function moveAt(pageX, pageY) {
el.style.left = Math.min(Math.max(0, pageX - shiftX), window.innerWidth - el.offsetWidth) + 'px';
el.style.top = Math.min(Math.max(0, pageY - shiftY), window.innerHeight - el.offsetHeight) + 'px';
}
function onMouseMove(event) {
moveAt(event.pageX, event.pageY);
}
document.addEventListener('mousemove', onMouseMove);
el.onmouseup = function() {
document.removeEventListener('mousemove', onMouseMove);
el.onmouseup = null;
};
};
el.ondragstart = function() {
return false;
};
}
async function sendMessage(channelId, message, token) {
const nonce = generateNonce();
return new Promise((resolve) => {
GM_xmlhttpRequest({
method: 'POST',
url: `https://discord.com/api/v9/channels/${channelId}/messages`,
headers: {
'Content-Type': 'application/json',
'Authorization': token
},
data: JSON.stringify({
content: message,
flags: 0,
mobile_network_type: "unknown",
nonce: nonce,
tts: false
}),
onload: (response) => {
resolve(response.status === 200);
},
onerror: () => resolve(false)
});
});
}
function generateNonce() {
const now = Date.now();
return `${now}${Math.floor(Math.random() * 1000)}`;
}
})();