SB100 / Discord Auto Message Poster

// ==UserScript==
// @namespace    https://openuserjs.org/users/SB100
// @name         Discord Auto Message Poster
// @description  Auto post a message to a discord channel every x ms
// @version      1.0.0
// @author       SB100
// @copyright    2021, SB100 (https://openuserjs.org/users/SB100)
// @license      MIT
// @match        https://discord.com/channels/*
// ==/UserScript==

// ==OpenUserJS==
// @author SB100
// ==/OpenUserJS==

/* jshint esversion: 6 */

let message = '';
let interval = '';
let timer = null;

// get our user token to be able to post messages
function getToken() {
  const iFrame = document.createElement('iframe');
  iFrame.style.display = 'none';
  iFrame.id = 'iFrame';
  document.body.appendChild(iFrame);
  return iFrame.contentWindow.localStorage.token.replace(/"/g, "");
}

// get the current channel we're on
function getChannel() {
  return document.location.pathname.split('/').pop();
}

// send a message to a channel via the api
function sendMessage(token, channel, message) {
  fetch(`https://discord.com/api/v8/channels/${channel}/messages`, {
    "headers": {
      "authorization": token,
      "content-type": "application/json"
    },
    "body": JSON.stringify({
      content: message
    }),
    "method": "POST"
  });
}

// show or hide the settings page. If we're currently posting messages, cancel it
function showOrHideSettings(isShow) {
  const settings = document.getElementById('auto--settings');
  settings.style.display = isShow ? 'block' : 'none';

  // if we open the settings, cancel the auto send
  if (isShow) {
    if (timer !== null) {
      clearInterval(timer);
      timer = null;
    }
  }
}

// save settings, and start posting messages
function saveSettings() {
  message = document.getElementById('auto--text').value.trim();
  interval = parseInt(document.getElementById('auto--interval').value, 10);

  // we have a message
  // we have an interval
  // interval is not spamming message more than 1 a second
  if (message.length > 0 && !isNaN(interval) && interval >= 1000) {
    showOrHideSettings(false);

    const channel = getChannel();
    const token = getToken();

    timer = setInterval(() => {
      sendMessage(token, channel, message)
    }, interval);
  }
}

// create the settings page
function createSettings() {
  const start = document.createElement('input');
  start.type = 'button';
  start.style.padding = '5px';
  start.style.marginRight = '10px';
  start.value = "Let's GO!";
  start.onclick = function () {
    saveSettings();
  }

  const cancel = document.createElement('input');
  cancel.type = 'button';
  cancel.style.padding = '5px';
  cancel.value = 'Cancel';
  cancel.onclick = function () {
    showOrHideSettings(false);
  }

  const buttonDiv = document.createElement('div');
  buttonDiv.style.padding = '10px';

  buttonDiv.appendChild(start);
  buttonDiv.appendChild(cancel);

  const div = document.createElement('div');
  div.id = 'auto--settings';
  div.innerHTML = `
      <p style='display: block; padding: 0 10px;'>
        This will post the message you write in the channel that is current up every X ms.
      </p>
      <p style='display: block; padding: 0 10px;'>
        If you switch channel, this script will continue to post in THIS channel!
        Come back to this page and hit "Let's GO!" again if you want to switch channel.
      </p>
      <p style='display: block; padding: 0 10px;'>
        If you want to cancel the auto posting, open this settings menu again, or refresh the page.
      </p>
      <label for='auto--text' style='display: block; padding: 10px'>
        <div style='margin-bottom: 5px'>What shall we say?</div>
        <input id='auto--text' style='padding: 5px; width: 95%' type='text' placeholder='Type something here!' value='' />
      </label>
      <label for='auto--inverval' style='display: block; padding: 10px'>
        <div style='margin-bottom: 5px'>How often shall we say it? (in ms)</div>
        <input id='auto--interval' style='padding: 5px; width: 95%' type='text' placeholder='5000' value='' />
      </label>
    `;

  div.style.display = 'none';
  div.style.position = 'absolute';
  div.style.width = '400px';
  div.style.top = '50%';
  div.style.left = '50%';
  div.style.transform = 'translate(-50%, -50%)';
  div.style.background = '#202225';
  div.style.color = '#fff';
  div.style.padding = '10px';
  div.style.borderRadius = '10px';
  div.style.zIndex = 2;

  div.appendChild(buttonDiv);

  document.body.appendChild(div);
}

// create the settings link
function createSettingsLink() {
  const a = document.createElement('a');
  a.innerHTML = 'Open Auto Message Poster Settings';
  a.src = '#open';

  a.style.display = 'block';
  a.style.position = 'absolute';
  a.style.top = 0;
  a.style.left = '50%';
  a.style.transform = 'translateX(-50%)';
  a.style.background = '#202225';
  a.style.color = '#fff';
  a.style.padding = '10px';
  a.style.zIndex = 2;
  a.onclick = function () {
    showOrHideSettings(true)
  };

  document.body.appendChild(a);
}

// run the script
(function () {
  'use strict';

  document.getElementById('app-mount').style.zIndex = 1;

  createSettingsLink();
  createSettings();
})();