import { ShardingManager } from 'discord.js'; import path from 'path'; import 'dotenv/config'; import * as grpc from '@grpc/grpc-js'; import { kordProto } from '@kord/grpc-contracts'; const manager = new ShardingManager(path.resolve(__dirname, 'index.ts'), { token: process.env.DISCORD_TOKEN, execArgv: ['-r', 'tsx'], // Allow running ts files natively in dev }); manager.on('shardCreate', (shard) => { console.log(`Launched shard ${shard.id}`); shard.on('ready', () => { console.log(`Shard ${shard.id} is ready`); }); shard.on('disconnect', () => { console.warn(`Shard ${shard.id} disconnected`); }); shard.on('reconnecting', () => { console.warn(`Shard ${shard.id} reconnecting`); }); }); // Spawn the required number of shards manager.spawn().then(() => { // --- gRPC Proxy Server Setup --- const server = new grpc.Server(); server.addService((kordProto as any).BotDashboardService.service, { Ping: (call: any, callback: any) => { console.log('Received Ping:', call.request.message); callback(null, { reply: `Pong to ${call.request.message}` }); }, GetGuildChannels: async (call: any, callback: any) => { const guildId = call.request.guildId; try { const results = await manager.broadcastEval( (c, context) => { const guild = c.guilds.cache.get(context.guildId); if (!guild) return null; return guild.channels.cache.map(ch => ({ id: ch.id, name: ch.name, type: `${ch.type}` })); }, { context: { guildId } } ); const channels = results.find(res => res !== null) || []; callback(null, { channels }); } catch (error: any) { callback({ code: grpc.status.INTERNAL, details: error.message }); } } }); server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), (err, port) => { if (err) { console.error('Failed to bind gRPC server:', err); return; } console.log(`gRPC Proxy Server running on port ${port}`); }); });