/* This program is free software. It comes without any warranty, to * the extent permitted by applicable law. You can redistribute it * and/or modify it under the terms of the Do What The Fuck You Want * To Public License, Version 2, as published by Sam Hocevar. See * http://www.wtfpl.net/ for more details. */ import 'dotenv/config.js'; import fs from 'node:fs'; import path from 'node:path'; import { ActivityType, GatewayIntentBits } from 'discord.js'; import { baseGasPricesObservable$ } from './blockchain'; import { deployCommands } from './deploy'; import { DiscordClient } from './discordClient'; import { createGasAlertChecker } from './gasAlertChecker'; import redisClient from './redis'; import { GasPrices } from '../types/gasPrices'; const token = process.env.DISCORD_BOT_TOKEN || ""; // Create a new Discord client const client = new DiscordClient({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages] }); const doAlerts = createGasAlertChecker(client); const setDiscordStatus = ({ average, fast, slow }: GasPrices) => { if (client.user) { client.user.setActivity( `⚡ ${fast} ⦚🚶 ${average} ⦚ 🐢 ${slow}` , { type: ActivityType.Watching }); } } // Load bot commands const commandsPath = path.join(__dirname, 'commands'); const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js')); for (const file of commandFiles) { const filePath = path.join(commandsPath, file); const command = require(filePath); // Set a new item in the Collection with the key as the command name and the value as the exported module if ('data' in command && 'execute' in command) { client.commands.set(command.data.name, command); } else { console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`); } } // Load bot events const eventsPath = path.join(__dirname, 'events'); const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js')); for (const file of eventFiles) { const filePath = path.join(eventsPath, file); const event = require(filePath); if (event.once) { client.once(event.name, (...args) => event.execute(...args)); } else if (event.name == 'messageCreate') { client.on(event.name, (...args) => event.execute(client, ...args)); } else { client.on(event.name, (...args) => event.execute(...args)); } } deployCommands(); console.log('Booting up discord bot') // Log in to Discord client.login(token) .then(async () => { // Connect to redis await redisClient.connect() .catch((reason) => console.log("Error connecting to redis!\n", reason)) }) .then(() => { // Start listening to blockchain baseGasPricesObservable$.subscribe({ next: async (averageGasPrices) => { setDiscordStatus(averageGasPrices); await redisClient.set('current-prices', JSON.stringify(averageGasPrices)) await doAlerts(averageGasPrices); }, error: (err) => console.error(err), complete: () => console.log("Blockchain data stream closed") }) }) .catch( (err) => console.log(`Bot runtime error! ${err}`) );