- // ==UserScript==
- // @name Discord DM Sender with Input Box and Toggle
- // @namespace http://tampermonkey.net/
- // @version 2.2
- // @description Send DM messages via Discord API with toggle visibility, customizable button names, and instructions. Supports "Shift + Enter" for new line and "Enter" for sending messages.
- // @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 isBoxVisible = GM_getValue('isBoxVisible', true);
- let isTokenVisible = GM_getValue('isTokenVisible', true);
- let areChannelsVisible = GM_getValue('areChannelsVisible', true);
- let channelId = '';
-
- const initialWidth = '280px';
- const initialHeight = '500px';
-
- 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';
- container.style.display = isBoxVisible ? 'block' : 'none';
- document.body.appendChild(container);
-
- makeElementDraggable(container);
-
- const hideTokenButton = document.createElement('button');
- hideTokenButton.innerText = isTokenVisible ? 'Hide Token' : 'View Token';
- hideTokenButton.style.marginBottom = '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';
- hideTokenButton.addEventListener('click', () => {
- isTokenVisible = !isTokenVisible;
- GM_setValue('isTokenVisible', isTokenVisible);
- tokenBox.style.display = isTokenVisible ? 'block' : 'none';
- hideTokenButton.innerText = isTokenVisible ? 'Hide Token' : 'View Token';
- });
- container.appendChild(hideTokenButton);
-
- 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';
- tokenBox.style.display = isTokenVisible ? 'block' : 'none';
- tokenBox.value = GM_getValue('tokenBoxValue', '');
- tokenBox.addEventListener('input', () => {
- GM_setValue('tokenBoxValue', tokenBox.value);
- });
- container.appendChild(tokenBox);
-
- const toggleChannelsButton = document.createElement('button');
- toggleChannelsButton.innerText = areChannelsVisible ? 'Hide Channel IDs' : 'View Channel IDs';
- toggleChannelsButton.style.marginTop = '10px';
- toggleChannelsButton.style.width = '100%';
- toggleChannelsButton.style.backgroundColor = '#575757';
- toggleChannelsButton.style.color = '#ffffff';
- toggleChannelsButton.style.border = 'none';
- toggleChannelsButton.style.borderRadius = '3px';
- toggleChannelsButton.style.cursor = 'pointer';
- toggleChannelsButton.addEventListener('click', () => {
- areChannelsVisible = !areChannelsVisible;
- GM_setValue('areChannelsVisible', areChannelsVisible);
- channelBoxes.forEach((channelBox) => {
- channelBox.style.display = areChannelsVisible ? 'block' : 'none';
- });
- toggleChannelsButton.innerText = areChannelsVisible ? 'Hide Channel IDs' : 'View Channel IDs';
- });
- container.appendChild(toggleChannelsButton);
-
- const channelBoxes = [];
- const channelBoxPlaceholders = [
- '荒らし雑談用匿名BOTのDMチャンネルIDを入力',
- '情勢雑談用BOTの匿名BOTのDMチャンネルIDを入力',
- '依頼支部用匿名BOTのDMチャンネルIDを入力'
- ];
-
- channelBoxPlaceholders.forEach((placeholder, index) => {
- const channelBox = document.createElement('textarea');
- channelBox.placeholder = placeholder;
- channelBox.style.width = '100%';
- channelBox.style.height = '40px';
- channelBox.style.resize = 'none';
- channelBox.style.backgroundColor = '#000000';
- channelBox.style.color = '#00FF00';
- channelBox.style.display = areChannelsVisible ? 'block' : 'none';
- channelBox.value = GM_getValue(`channelBox${index + 1}Value`, '');
- channelBox.addEventListener('input', () => {
- GM_setValue(`channelBox${index + 1}Value`, channelBox.value);
- });
- channelBoxes.push(channelBox);
- container.appendChild(channelBox);
- });
-
- const inputBox = document.createElement('textarea');
- inputBox.placeholder = 'Enter message (⚠️:初回はcaptchaにかかる事がある為、初回送信時はbotに1回手動でDMを送ってから使用してください。DMチャンネルIDはBOT IDではありません)';
- inputBox.style.width = '100%';
- inputBox.style.height = '100px';
- inputBox.style.resize = 'none';
- inputBox.style.backgroundColor = '#000000';
- inputBox.style.color = '#00FF00';
- inputBox.style.marginTop = '10px';
- inputBox.value = GM_getValue('inputBoxValue', '');
- inputBox.addEventListener('input', () => {
- GM_setValue('inputBoxValue', inputBox.value);
- });
- inputBox.addEventListener('keydown', (event) => {
- if (event.key === 'Enter' && !event.shiftKey) {
- event.preventDefault();
-
- 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;
- }
-
- sendMessage(channelId, message, token).then((success) => {
- if (success) {
- inputBox.value = '';
- GM_setValue('inputBoxValue', '');
- } else {
- alert('Failed to send message');
- }
- });
- }
- });
- container.appendChild(inputBox);
-
- const selectChannelsLabel = document.createElement('div');
- selectChannelsLabel.innerText = 'Select channels';
- selectChannelsLabel.style.marginTop = '10px';
- selectChannelsLabel.style.marginBottom = '5px';
- selectChannelsLabel.style.fontSize = '14px';
- selectChannelsLabel.style.textAlign = 'left';
- container.appendChild(selectChannelsLabel);
-
- const buttonContainer = document.createElement('div');
- buttonContainer.style.display = 'flex';
- buttonContainer.style.justifyContent = 'space-between';
-
- const buttonNames = ['荒らし雑談', '情勢雑談', '依頼支部'];
-
- channelBoxes.forEach((channelBox, index) => {
- const channelButton = document.createElement('button');
- channelButton.innerText = buttonNames[index];
- channelButton.style.width = '30%';
- channelButton.style.backgroundColor = '#575757';
- channelButton.style.color = '#ffffff';
- channelButton.style.border = 'none';
- channelButton.style.borderRadius = '3px';
- channelButton.style.cursor = 'pointer';
- channelButton.addEventListener('click', () => {
- channelId = channelBox.value.trim();
- updateButtonStyles(channelButton);
- });
- buttonContainer.appendChild(channelButton);
- });
-
- function updateButtonStyles(activeButton) {
- Array.from(buttonContainer.children).forEach((button) => {
- button.style.backgroundColor = button === activeButton ? '#047500' : '#575757';
- });
- }
-
- container.appendChild(buttonContainer);
-
- const sendButton = document.createElement('button');
- sendButton.innerText = 'Send DM';
- sendButton.style.marginTop = '10px';
- sendButton.style.width = '100%';
- sendButton.style.backgroundColor = '#575757';
- sendButton.style.color = '#ffffff';
- sendButton.style.border = 'none';
- sendButton.style.borderRadius = '3px';
- sendButton.style.cursor = 'pointer';
- sendButton.addEventListener('click', async () => {
- 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;
- }
-
- const success = await sendMessage(channelId, message, token);
- if (success) {
- inputBox.value = '';
- GM_setValue('inputBoxValue', '');
- } else {
- alert('Failed to send message');
- }
- });
- container.appendChild(sendButton);
-
- const toggleImage = document.createElement('img');
- toggleImage.src = 'https://i.imgur.com/FL6WD8a.png';
- toggleImage.style.position = 'fixed';
- toggleImage.style.width = '30px';
- toggleImage.style.height = '30px';
- toggleImage.style.cursor = 'pointer';
- toggleImage.style.zIndex = '1001';
- toggleImage.style.left = '75px';
- toggleImage.style.bottom = '222px';
- document.body.appendChild(toggleImage);
-
- toggleImage.addEventListener('click', () => {
- isBoxVisible = !isBoxVisible;
- GM_setValue('isBoxVisible', isBoxVisible);
- container.style.display = isBoxVisible ? 'block' : 'none';
- });
-
- function makeElementDraggable(el) {
- el.onmousedown = function(event) {
- if (event.target.tagName === 'TEXTAREA') return;
-
- event.preventDefault();
-
- let shiftX = event.clientX - el.getBoundingClientRect().left;
- let shiftY = event.clientY - el.getBoundingClientRect().top;
-
- function moveAt(pageX, pageY) {
- const newLeft = Math.min(Math.max(0, pageX - shiftX), window.innerWidth - el.offsetWidth);
- const newTop = Math.min(Math.max(0, pageY - shiftY), window.innerHeight - el.offsetHeight);
-
- el.style.left = `${newLeft}px`;
- el.style.top = `${newTop}px`;
- }
-
- function stopDragging() {
- document.removeEventListener('mousemove', onMouseMove);
- document.removeEventListener('mouseup', stopDragging);
- }
-
- function onMouseMove(event) {
- moveAt(event.pageX, event.pageY);
- }
-
- document.addEventListener('mousemove', onMouseMove);
- document.addEventListener('mouseup', stopDragging);
- };
-
- 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,
- 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)}`;
- }
- })();