Discord DM Sender with Input Box

Send DM messages via Discord API

目前為 2024-12-23 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Discord DM Sender with Input Box
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.5
  5. // @description Send DM messages via Discord API
  6. // @author Your Name
  7. // @match https://discord.com/*
  8. // @grant GM_xmlhttpRequest
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @license You can modify as long as you credit me
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. let channelId = ''; // 初期チャンネルIDを削除
  18.  
  19. const initialWidth = '280px';
  20. const initialHeight = '400px';
  21.  
  22. const container = document.createElement('div');
  23. container.style.position = 'fixed';
  24. container.style.bottom = '10px';
  25. container.style.left = '10px';
  26. container.style.backgroundColor = '#2f3136';
  27. container.style.color = '#ffffff';
  28. container.style.padding = '10px';
  29. container.style.borderRadius = '5px';
  30. container.style.zIndex = '1000';
  31. container.style.width = initialWidth;
  32. container.style.height = initialHeight;
  33. document.body.appendChild(container);
  34.  
  35. makeElementDraggable(container);
  36.  
  37. const tokenBox = document.createElement('textarea');
  38. tokenBox.placeholder = 'Enter your token';
  39. tokenBox.style.width = '100%';
  40. tokenBox.style.height = '40px';
  41. tokenBox.style.resize = 'none';
  42. tokenBox.style.backgroundColor = '#000000';
  43. tokenBox.style.color = '#00FF00';
  44. container.appendChild(tokenBox);
  45.  
  46. const inputBox = document.createElement('textarea');
  47. inputBox.placeholder = 'Enter your secret message to aarr';
  48. inputBox.style.width = '100%';
  49. inputBox.style.height = '100px';
  50. inputBox.style.resize = 'none';
  51. inputBox.style.backgroundColor = '#000000';
  52. inputBox.style.color = '#00FF00';
  53. container.appendChild(inputBox);
  54.  
  55. const channelBox1 = document.createElement('textarea');
  56. channelBox1.placeholder = '荒らし雑談のBOTのDMチャンネルIDを入力';
  57. channelBox1.style.width = '100%';
  58. channelBox1.style.height = '40px';
  59. channelBox1.style.resize = 'none';
  60. channelBox1.style.backgroundColor = '#000000';
  61. channelBox1.style.color = '#00FF00';
  62. container.appendChild(channelBox1);
  63.  
  64. const channelBox2 = document.createElement('textarea');
  65. channelBox2.placeholder = '情勢雑談のBOTのDMチャンネルIDを入力';
  66. channelBox2.style.width = '100%';
  67. channelBox2.style.height = '40px';
  68. channelBox2.style.resize = 'none';
  69. channelBox2.style.backgroundColor = '#000000';
  70. channelBox2.style.color = '#00FF00';
  71. container.appendChild(channelBox2);
  72.  
  73. const channelBox3 = document.createElement('textarea');
  74. channelBox3.placeholder = '依頼支部のBOTのDMチャンネルIDを入力';
  75. channelBox3.style.width = '100%';
  76. channelBox3.style.height = '40px';
  77. channelBox3.style.resize = 'none';
  78. channelBox3.style.backgroundColor = '#000000';
  79. channelBox3.style.color = '#00FF00';
  80. container.appendChild(channelBox3);
  81.  
  82. const button = document.createElement('button');
  83. button.innerText = 'Send DM';
  84. button.style.marginTop = '10px';
  85. button.style.width = '100%';
  86. button.style.backgroundColor = '#575757';
  87. button.style.color = '#ffffff';
  88. button.style.border = 'none';
  89. button.style.borderRadius = '3px';
  90. button.style.cursor = 'pointer';
  91. container.appendChild(button);
  92.  
  93. const buttonContainer = document.createElement('div');
  94. buttonContainer.style.marginTop = '10px';
  95. buttonContainer.style.display = 'flex';
  96. buttonContainer.style.justifyContent = 'space-between';
  97.  
  98. const channelButton1 = document.createElement('button');
  99. channelButton1.innerText = '1荒らし雑談';
  100. channelButton1.style.width = '30%';
  101. channelButton1.style.backgroundColor = '#575757';
  102. channelButton1.style.color = '#ffffff';
  103. channelButton1.style.border = 'none';
  104. channelButton1.style.borderRadius = '3px';
  105. channelButton1.style.cursor = 'pointer';
  106. channelButton1.addEventListener('click', () => {
  107. channelId = channelBox1.value.trim();
  108. updateButtonStyles(channelButton1);
  109. });
  110.  
  111. const channelButton2 = document.createElement('button');
  112. channelButton2.innerText = '2情勢雑談';
  113. channelButton2.style.width = '30%';
  114. channelButton2.style.backgroundColor = '#575757';
  115. channelButton2.style.color = '#ffffff';
  116. channelButton2.style.border = 'none';
  117. channelButton2.style.borderRadius = '3px';
  118. channelButton2.style.cursor = 'pointer';
  119. channelButton2.addEventListener('click', () => {
  120. channelId = channelBox2.value.trim();
  121. updateButtonStyles(channelButton2);
  122. });
  123.  
  124. const channelButton3 = document.createElement('button');
  125. channelButton3.innerText = '3依頼版';
  126. channelButton3.style.width = '30%';
  127. channelButton3.style.backgroundColor = '#575757';
  128. channelButton3.style.color = '#ffffff';
  129. channelButton3.style.border = 'none';
  130. channelButton3.style.borderRadius = '3px';
  131. channelButton3.style.cursor = 'pointer';
  132. channelButton3.addEventListener('click', () => {
  133. channelId = channelBox3.value.trim();
  134. updateButtonStyles(channelButton3);
  135. });
  136.  
  137. buttonContainer.appendChild(channelButton1);
  138. buttonContainer.appendChild(channelButton2);
  139. buttonContainer.appendChild(channelButton3);
  140. container.appendChild(buttonContainer);
  141.  
  142. function updateButtonStyles(activeButton) {
  143. [channelButton1, channelButton2, channelButton3].forEach(button => {
  144. if (button === activeButton) {
  145. button.style.backgroundColor = '#047500';
  146. } else {
  147. button.style.backgroundColor = '#575757';
  148. }
  149. });
  150. }
  151.  
  152. inputBox.value = GM_getValue('inputBoxValue', '');
  153. tokenBox.value = GM_getValue('tokenBoxValue', '');
  154.  
  155. async function sendDM() {
  156. const token = tokenBox.value.trim();
  157. if (!token) {
  158. alert('Token is required');
  159. return;
  160. }
  161.  
  162. const message = inputBox.value.trim();
  163. if (!message) {
  164. alert('Message cannot be empty');
  165. return;
  166. }
  167.  
  168. tokenBox.style.display = 'none';
  169. GM_setValue('tokenBoxValue', token);
  170.  
  171. const success = await sendMessage(channelId, message, token);
  172. if (success) {
  173. inputBox.value = '';
  174. GM_setValue('inputBoxValue', '');
  175. } else {
  176. alert('Failed to send message');
  177. }
  178. }
  179.  
  180. button.addEventListener('click', sendDM);
  181.  
  182. inputBox.addEventListener('keydown', (event) => {
  183. if (event.key === 'Enter' && !event.shiftKey) {
  184. event.preventDefault();
  185. sendDM();
  186. } else if (event.key === 'Enter' && event.shiftKey) {
  187. event.preventDefault();
  188. const cursorPos = inputBox.selectionStart;
  189. const textBefore = inputBox.value.substring(0, cursorPos);
  190. const textAfter = inputBox.value.substring(cursorPos);
  191. inputBox.value = `${textBefore}\n${textAfter}`;
  192. inputBox.selectionStart = cursorPos + 1;
  193. inputBox.selectionEnd = cursorPos + 1;
  194. }
  195. });
  196.  
  197. inputBox.addEventListener('input', () => {
  198. GM_setValue('inputBoxValue', inputBox.value);
  199. });
  200.  
  201. tokenBox.addEventListener('input', () => {
  202. GM_setValue('tokenBoxValue', tokenBox.value);
  203. });
  204.  
  205. function makeElementDraggable(el) {
  206. el.onmousedown = function(event) {
  207. if (event.target === inputBox || event.target === tokenBox || event.target === channelBox1 || event.target === channelBox2 || event.target === channelBox3) {
  208. return;
  209. }
  210.  
  211. event.preventDefault();
  212.  
  213. let shiftX = event.clientX - el.getBoundingClientRect().left;
  214. let shiftY = event.clientY - el.getBoundingClientRect().top;
  215.  
  216. function moveAt(pageX, pageY) {
  217. el.style.left = pageX - shiftX + 'px';
  218. el.style.top = pageY - shiftY + 'px';
  219. }
  220.  
  221. function onMouseMove(event) {
  222. moveAt(event.pageX, event.pageY);
  223. }
  224.  
  225. document.addEventListener('mousemove', onMouseMove);
  226.  
  227. el.onmouseup = function() {
  228. document.removeEventListener('mousemove', onMouseMove);
  229. el.onmouseup = null;
  230. };
  231. };
  232.  
  233. el.ondragstart = function() {
  234. return false;
  235. };
  236. }
  237.  
  238. async function sendMessage(channelId, message, token) {
  239. const nonce = generateNonce();
  240. return new Promise((resolve) => {
  241. GM_xmlhttpRequest({
  242. method: 'POST',
  243. url: `https://discord.com/api/v9/channels/${channelId}/messages`,
  244. headers: {
  245. 'Content-Type': 'application/json',
  246. 'Authorization': token
  247. },
  248. data: JSON.stringify({
  249. content: message,
  250. flags: 0,
  251. mobile_network_type: "unknown",
  252. nonce: nonce,
  253. tts: false
  254. }),
  255. onload: (response) => {
  256. resolve(response.status === 200);
  257. },
  258. onerror: () => resolve(false)
  259. });
  260. });
  261. }
  262.  
  263. function generateNonce() {
  264. const now = Date.now();
  265. return `${now}${Math.floor(Math.random() * 1000)}`;
  266. }
  267. })();