discord | discord request | discord bot configuration | Search

The code is a Discord bot implementation that initializes variables and functions for handling WebSocket connections, sending heartbeats, and processing gateway messages. The gatewayMessage function is the main entry point for processing messages from the WebSocket server, and it updates the sequence number, logs messages, and performs different actions based on the op value of the gateway message.

Run example

npm run import -- "discord gateway"

discord gateway

const {TOKEN, DEFAULT_APPLICATION} = importer.import("discord configuration")
const systemUsage = importer.import("system usage report")

const INSTANCES = {}
const SESSIONS = {}
var indentifyTimer
var privateChannels = {}
var interactions = {}
const interactionsCommands = {}
var cancelConnection // if gateway doesn't respond properly, close web socket
var heartbeat
var resources
var seq = 0

function sendHeartbeat(ws, reconnect) {
  if(!ws) return
  console.log('Sending heartbeat')
  ws.send(JSON.stringify({
    op: 1,
    d: seq
  }))
  cancelConnection = setTimeout(gatewayClose.bind(null, ws, reconnect), 4000)
}

function gatewayMessage(ws, reconnectGateway, interactionResponse, message) {
  var msgBuff = new Buffer.from(message)
  var gateway = JSON.parse(msgBuff.toString('utf-8'))
  if(gateway.s) seq = gateway.s
  if(gateway.d && gateway.d.seq) seq = gateway.d.seq
  
  console.log('Gateway message', gateway)
  
  if(gateway.op == 10) {
    ws.identified = true
    heartbeat = setInterval(sendHeartbeat.bind(null, ws, reconnectGateway), gateway.d.heartbeat_interval)
    resources = setInterval(systemUsage, 1000)
    ws.send(JSON.stringify({
      op: 2,
      intents: [
        'DIRECT_MESSAGES', 'DIRECT_MESSAGE_REACTIONS', 
        'GUILD_MESSAGES', 'GUILD_MESSAGE_REACTIONS', 
        'GUILDS', 'THREAD_UPDATE', 'THREAD_CREATE',
        'THREAD_DELETE', 'THREAD_LIST_SYNC', 'THREAD_MEMBER_UPDATE',
        'THREAD_MEMBERS_UPDATE', 'MESSAGE_CREATE', 'MESSAGE_UPDATE',
        'GUILD_PRESENCES',
      ],
      d: {
        token: TOKEN,
        properties: {
          "$os": "linux",
          "$browser": "nodejs",
          "$device": "quake3"
        }
      }
    }))
    return
  } else if (gateway.op === 7) { // should reconnect
    console.log('Reconnecting...')
    gatewayClose(ws, reconnectGateway)
    return
  } else if (gateway.op === 0 || gateway.op === 9) {
    if(gateway.t == 'MESSAGE_CREATE') {
      // guild ID can only be null if it is a personal message
      if(typeof gateway.d.guild_id == 'undefined') {
        privateChannels[gateway.d.channel_id] = Date.now()
        if(gateway.d.author.id != DEFAULT_APPLICATION) {
          interactionsCommands['promptPrivate'](gateway.d)
        }
      } else if(gateway.d.content.includes('@' + DEFAULT_APPLICATION)
        && typeof interactionsCommands['promptMention'] != 'undefined'
      ) {
        interactionsCommands['promptMention'](gateway.d)
      }
    }
    if(gateway.t == 'INTERACTION_CREATE') {
      if(typeof interactions[gateway.d.channel_id] == 'undefined')
        interactions[gateway.d.channel_id] = []
      interactions[gateway.d.channel_id].push(gateway.d)
      if(typeof interactionsCommands[gateway.d.data.name] != 'undefined') {
        Promise.resolve(interactionsCommands[gateway.d.data.name](gateway.d))
      }
      interactionResponse(gateway.d.id, gateway.d.token)
    }
    if(gateway.t == 'EMBEDDED_ACTIVITY_UPDATE_V2') {
      if(typeof INSTANCES[gateway.d['instance_id']] == 'undefined') {
        INSTANCES[gateway.d['instance_id']] = []
      }
      INSTANCES[gateway.d['instance_id']] = INSTANCES[gateway.d['instance_id']].filter(i => gateway.d.participants.includes(i[0]))
    
      if(typeof interactionsCommands['startActivity'] != 'undefined'
        && typeof interactionsCommands['endActivity'] != 'undefined'
      ) {
        if(gateway.d.participants.length) {
          Promise.resolve(interactionsCommands['startActivity'](gateway.d))
        } else {
          Promise.resolve(interactionsCommands['endActivity'](gateway.d))
        }
      }
    }
    return
  } else if (gateway.op === 11) {
    clearTimeout(cancelConnection)
    return
  }
  console.log('Unrecognized gateway', gateway)
}

function gatewayClose(ws, reconnect) {
  console.log('Discord disconnected')
  if(indentifyTimer)
    clearInterval(indentifyTimer)
  if(heartbeat)
    clearInterval(heartbeat)
  if(resources)
    clearInterval(resources)
  if(ws.readyState == 1)
    ws.close()
  if(reconnect) {
    setTimeout(reconnect, 1000)
  }
  if(typeof interactionsCommands['endActivity'] != 'undefined') {
    Promise.resolve(interactionsCommands['endActivity']())
  }
  ws.identified = false
  return
}

module.exports = {
  gatewayClose,
  gatewayMessage,
  privateChannels,
  interactions,
  interactionsCommands,
  INSTANCES,
  SESSIONS,
}

What the code could have been:

const {
  TOKEN,
  DEFAULT_APPLICATION,
} = importer.import('discord configuration');

const {
  getSystemUsage,
} = importer.import('system usage report');

const INSTANCES = {};
const SESSIONS = {};
const privateChannels = {};
const interactions = {};
const interactionsCommands = {};

let indentifyTimer;
let cancelConnection;
let heartbeat;
let resources;
let seq = 0;

/**
 * Sends a heartbeat to Discord
 * @param {Object} ws WebSocket object
 * @param {Boolean} reconnect Whether to reconnect after sending heartbeat
 */
function sendHeartbeat(ws, reconnect) {
  if (!ws) return;
  console.log('Sending heartbeat');
  ws.send(JSON.stringify({
    op: 1,
    d: seq,
  }));
  cancelConnection = setTimeout(() => gatewayClose(ws, reconnect), 4000);
}

/**
 * Handles a message received from Discord
 * @param {Object} ws WebSocket object
 * @param {Boolean} reconnectGateway Whether to reconnect to the gateway
 * @param {Function} interactionResponse Function to respond to interactions
 * @param {Object} message Message received from Discord
 */
function gatewayMessage(ws, reconnectGateway, interactionResponse, message) {
  const msgBuffer = Buffer.from(message);
  const gateway = JSON.parse(msgBuffer.toString('utf-8'));
  if (gateway.s) seq = gateway.s;
  if (gateway.d && gateway.d.seq) seq = gateway.d.seq;

  console.log('Gateway message', gateway);

  switch (gateway.op) {
    case 10:
      ws.identified = true;
      heartbeat = setInterval(() => sendHeartbeat(ws, reconnectGateway), gateway.d.heartbeat_interval);
      resources = setInterval(getSystemUsage, 1000);
      ws.send(JSON.stringify({
        op: 2,
        intents: [
          'DIRECT_MESSAGES',
          'DIRECT_MESSAGE_REACTIONS',
          'GUILD_MESSAGES',
          'GUILD_MESSAGE_REACTIONS',
          'GUILDS',
          'THREAD_UPDATE',
          'THREAD_CREATE',
          'THREAD_DELETE',
          'THREAD_LIST_SYNC',
          'THREAD_MEMBER_UPDATE',
          'THREAD_MEMBERS_UPDATE',
          'MESSAGE_CREATE',
          'MESSAGE_UPDATE',
          'GUILD_PRESENCES',
        ],
        d: {
          token: TOKEN,
          properties: {
            '$os': 'linux',
            '$browser': 'nodejs',
            '$device': 'quake3',
          },
        },
      }));
      break;

    case 7:
      console.log('Reconnecting...');
      gatewayClose(ws, reconnectGateway);
      break;

    case 0:
    case 9:
      if (gateway.t === 'MESSAGE_CREATE') {
        const { guild_id, channel_id, author, content } = gateway.d;
        if (typeof guild_id === 'undefined') {
          privateChannels[channel_id] = Date.now();
          if (author.id!== DEFAULT_APPLICATION && interactionsCommands.promptPrivate) {
            interactionsCommands.promptPrivate(gateway.d);
          }
        } else if (content.includes(`@${DEFAULT_APPLICATION}`) && interactionsCommands.promptMention) {
          interactionsCommands.promptMention(gateway.d);
        }
      }

      if (gateway.t === 'INTERACTION_CREATE') {
        const { channel_id, data } = gateway.d;
        if (!interactions[channel_id]) interactions[channel_id] = [];
        interactions[channel_id].push(gateway.d);
        if (interactionsCommands[data.name]) {
          Promise.resolve(interactionsCommands[data.name](gateway.d));
        }
        interactionResponse(gateway.d.id, gateway.d.token);
      }

      if (gateway.t === 'EMBEDDED_ACTIVITY_UPDATE_V2') {
        const { instance_id, participants } = gateway.d;
        if (!INSTANCES[instance_id]) INSTANCES[instance_id] = [];
        INSTANCES[instance_id] = INSTANCES[instance_id].filter(i => participants.includes(i[0]));

        if (interactionsCommands.startActivity && interactionsCommands.endActivity) {
          if (participants.length) {
            Promise.resolve(interactionsCommands.startActivity(gateway.d));
          } else {
            Promise.resolve(interactionsCommands.endActivity(gateway.d));
          }
        }
      }
      break;

    case 11:
      clearTimeout(cancelConnection);
      break;

    default:
      console.log('Unrecognized gateway', gateway);
      break;
  }
}

/**
 * Closes the Discord gateway
 * @param {Object} ws WebSocket object
 * @param {Boolean} reconnect Whether to reconnect after closing the gateway
 */
function gatewayClose(ws, reconnect) {
  console.log('Discord disconnected');
  clearInterval(indentifyTimer);
  clearInterval(heartbeat);
  clearInterval(resources);
  if (ws.readyState === 1) ws.close();
  if (reconnect) {
    setTimeout(reconnect, 1000);
  }
  if (interactionsCommands.endActivity) {
    Promise.resolve(interactionsCommands.endActivity());
  }
  ws.identified = false;
  return;
}

module.exports = {
  gatewayClose,
  gatewayMessage,
  privateChannels,
  interactions,
  interactionsCommands,
  INSTANCES,
  SESSIONS,
};

Breakdown of the Code

Importing Configuration and Functionality

const {TOKEN, DEFAULT_APPLICATION} = importer.import('discord configuration')
const systemUsage = importer.import('system usage report')

Initializing Variables

const INSTANCES = {}
const SESSIONS = {}
var indentifyTimer
var privateChannels = {}
var interactions = {}
const interactionsCommands = {}
var cancelConnection // if gateway doesn't respond properly, close web socket
var heartbeat
var resources
var seq = 0

sendHeartbeat Function

function sendHeartbeat(ws, reconnect) {
  if(!ws) return
  console.log('Sending heartbeat')
  ws.send(JSON.stringify({
    op: 1,
    d: seq
  }))
  cancelConnection = setTimeout(gatewayClose.bind(null, ws, reconnect), 4000)
}

gatewayMessage Function

function gatewayMessage(ws, reconnectGateway, interactionResponse, message) {
  var msgBuff = new Buffer.from(message)
  var gateway = JSON.parse(msgBuff.toString('utf-8'))
  if(gateway.s) seq = gateway.s
  if(gateway.d && gateway.d.seq) seq = gateway.d.seq
  
  console.log('Gateway message', gateway)
  
  if(gateway.op == 10) {
    ws.identified = true
    heartbeat = setInterval(sendHeartbeat.bind(null, ws, reconnectGateway), gateway.d.heartbeat_interval)
    resources = setInterval(systemUsage, 1000)
    ws.send(JSON.stringify({
      op: 2,
      intents: [
        'DIRECT_MESSAGES', 'DIRECT_MESSAGE_REACTIONS', 
        'GUILD_MESSAGES', 'GUILD_MESSAGE_REACTIONS', 
        'GUILDS', 'THREAD_UPDATE', 'THREAD_CREATE',
        'THREAD_DELETE', 'THREAD_LIST_SYNC', 'THREAD_MEMBER_UPDATE',
        'THREAD_MEMBERS_UPDATE', 'MESSAGE_CREATE', 'MESSAGE_UPDATE',
        'GUILD_PRESENCES',
      ],
      d: {
        token: TOKEN,
        properties: {
          "$os": "linux",
          "$browser": "nodejs",
          "$device": "quake3"
        }
      }
    }))
    return
  } else if (gateway.op === 7) { // should reconnect
    console.log('Reconnecting...')
    gatewayClose(ws, reconnectGateway)
    return
  } else if (gateway.op === 0 || gateway.op === 9) {
    if(gateway.t == 'MESSAGE_CREATE') {
      // guild ID can only be null if it is a personal message
      if(typeof gateway.d.guild_id == 'undefined') {
        return
      }
    }
  }
}