Skip to main content
Glama
gateway.ts•2.47 kB
import { GatewayIntentBits, type GatewayDispatchEvents } from '@discordjs/core'; import { WebSocketManager } from '@discordjs/ws'; import { EventEmitter } from 'node:events'; import { REST } from '@discordjs/rest'; type AnyEvent = { t: string; d: any; s: number | null; op: number; shard?: number }; export interface GatewayFilters { eventTypes?: string[]; // e.g., ["MESSAGE_CREATE","MESSAGE_UPDATE"] guildIds?: string[]; channelIds?: string[]; } export class GatewayManager extends EventEmitter { #wsm: WebSocketManager; #queue: AnyEvent[] = []; #filters: GatewayFilters = {}; #max = 1000; constructor(token: string, intents: number){ super(); const rest = new REST({ version: '10' }).setToken(token); this.#wsm = new WebSocketManager({ token, intents, shardCount: 1, rest }); this.#wsm.on('event', (data: AnyEvent) => { try { const ev = data; if (!this.#passes(ev)) return; this.#queue.push(ev); // Fix memory leak: remove excess events from the beginning of the queue if (this.#queue.length > this.#max) { this.#queue.splice(0, this.#queue.length - this.#max); } this.emit('event', ev); } catch (error) { console.error('Gateway event processing error:', error); // Emit error event so consumers can handle it this.emit('error', error); } }); } start(){ this.#wsm.connect(); } stop(){ this.#wsm.destroy(); this.#queue = []; this.removeAllListeners(); } setFilters(f: GatewayFilters){ this.#filters = f; } getEvents(max = 50){ return this.#queue.splice(0, Math.min(max, this.#queue.length)); } info(){ // WebSocketManager doesn't expose a status property directly // We'll use a simple connected flag for now return { connected: true }; } #passes(ev: AnyEvent): boolean { const f = this.#filters; if (f.eventTypes && f.eventTypes.length && !f.eventTypes.includes(ev.t)) return false; // Filter by guild/channel if IDs are present in payload (best-effort) const guildId = ev?.d?.guild_id ?? ev?.d?.guild?.id ?? null; if (f.guildIds && f.guildIds.length && guildId && !f.guildIds.includes(guildId)) return false; const channelId = ev?.d?.channel_id ?? ev?.d?.id ?? null; if (f.channelIds && f.channelIds.length && channelId && !f.channelIds.includes(channelId)) return false; return true; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/GustyCube/discord-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server