Add more tracking to embed

This commit is contained in:
Wizzard 2024-03-14 00:25:18 -04:00
parent d1802a291d
commit bcdfb07eb0
1 changed files with 120 additions and 34 deletions

154
main.js
View File

@ -3,6 +3,14 @@ const { Client, GatewayIntentBits, EmbedBuilder } = require('discord.js');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
let priceHistory = {
currentPrice: 0,
prices: [{
time: Date.now(),
price: 0,
}]
};
const client = new Client({ const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
}); });
@ -15,10 +23,13 @@ let lastPriceMessageId;
client.once('ready', async () => { client.once('ready', async () => {
console.log('Bot is online!'); console.log('Bot is online!');
immediatePriceCheckAndAnnounce() let solanaData = readSolanaData();
const solanaData = readSolanaData(); if (solanaData) {
lastKnownPriceAtStartup = solanaData ? solanaData.price : null; priceHistory = solanaData;
lastPriceMessageId = solanaData ? solanaData.lastPriceMessageId : null; lastKnownPriceAtStartup = solanaData.currentPrice;
lastPriceMessageId = solanaData.lastPriceMessageId;
}
immediatePriceCheckAndAnnounce();
checkPriceContinuously(); checkPriceContinuously();
}); });
@ -35,33 +46,110 @@ async function fetchSolanaPrice() {
} }
} }
async function immediatePriceCheckAndAnnounce() { async function fetchSolanaPriceAndUpdateHistory() {
const currentPrice = await fetchSolanaPrice();
if (currentPrice) {
priceHistory.prices.push({ time: Date.now(), price: currentPrice });
priceHistory.currentPrice = currentPrice;
if (priceHistory.prices.length > 61) {
priceHistory.prices.shift();
}
saveSolanaData(priceHistory);
}
}
function immediatePriceCheckAndAnnounce() {
const solanaData = readSolanaData(); const solanaData = readSolanaData();
const lastKnownPrice = solanaData ? solanaData.price : null; const lastKnownPrice = solanaData ? solanaData.price : null;
const currentPrice = await fetchSolanaPrice(); const currentPrice = fetchSolanaPrice();
}
checkPriceContinuously();
const now = Date.now();
function calculateChanges() {
const latestPrice = parseFloat(priceHistory.currentPrice);
let oneMinChange = { percent: 0, dollar: 0 };
let fiveMinChange = { percent: 0, dollar: 0 };
let oneHourChange = { percent: 0, dollar: 0 };
let oneDayChange = { percent: 0, dollar: 0 };
const now = Date.now();
function findPriceAgo(minutesAgo) {
const targetTime = now - minutesAgo * 60 * 1000;
return priceHistory.prices.reduce((prev, curr) => {
return Math.abs(curr.time - targetTime) < Math.abs(prev.time - targetTime) ? curr : prev;
}, priceHistory.prices[0]);
}
if (priceHistory.prices.length >= 2) {
const oneMinAgoPrice = parseFloat(findPriceAgo(1).price);
oneMinChange.percent = ((latestPrice - oneMinAgoPrice) / oneMinAgoPrice) * 100;
oneMinChange.dollar = latestPrice - oneMinAgoPrice;
}
if (priceHistory.prices.length >= 6) {
const fiveMinAgoPrice = parseFloat(findPriceAgo(5).price);
fiveMinChange.percent = ((latestPrice - fiveMinAgoPrice) / fiveMinAgoPrice) * 100;
fiveMinChange.dollar = latestPrice - fiveMinAgoPrice;
}
if (priceHistory.prices.length >= 61) {
const oneHourAgoPrice = parseFloat(findPriceAgo(60).price);
oneHourChange.percent = ((latestPrice - oneHourAgoPrice) / oneHourAgoPrice) * 100;
oneHourChange.dollar = latestPrice - oneHourAgoPrice;
}
if (priceHistory.prices.length >= 1440) {
const oneDayAgoPrice = parseFloat(findPriceAgo(1440).price);
oneDayChange.percent = ((latestPrice - oneDayAgoPrice) / oneDayAgoPrice) * 100;
oneDayChange.dollar = latestPrice - oneDayAgoPrice;
}
return { oneMinChange, fiveMinChange, oneHourChange, oneDayChange };
}
const { oneMinChange, fiveMinChange, oneHourChange, oneDayChange } = calculateChanges();
async function sendNewPriceMessage(embed) {
const sentMessage = await solanaPriceChannel.send({ embeds: [embed] });
lastPriceMessageId = sentMessage.id;
saveSolanaData({ ...priceHistory, lastPriceMessageId: sentMessage.id });
}
async function sendNewPriceMessage(solanaPriceChannel, embed) {
const sentMessage = await solanaPriceChannel.send({ embeds: [embed] });
lastPriceMessageId = sentMessage.id;
saveSolanaData({ ...priceHistory, lastPriceMessageId: sentMessage.id });
} }
async function checkPriceContinuously() { async function checkPriceContinuously() {
const price = await fetchSolanaPrice(); await fetchSolanaPriceAndUpdateHistory();
if (!price) { const { oneMinChange, fiveMinChange, oneHourChange } = calculateChanges();
console.log('Could not fetch price, will try again in 60 seconds.');
setTimeout(checkPriceContinuously, 60000);
return;
}
console.log(`Current Solana Price: $${price}`);
const solanaPriceChannel = await client.channels.fetch(solanaPriceChannelId);
const embed = new EmbedBuilder() const embed = new EmbedBuilder()
.setColor(0x0099ff) .setColor(0x0099ff)
.setThumbnail('https://solana.com/src/img/branding/solanaLogoMark.png') .setThumbnail('https://solana.com/src/img/branding/solanaLogoMark.png')
.setTitle('Solana (SOL) Price Update') .setTitle('Solana (SOL) Price Update')
.setDescription(`**Current Price: \`$${price}\`**`) .setDescription(`**Current Price: \`$${priceHistory.currentPrice}\`**`)
.addFields({ name: '💰 Current Price', value: `**\`$${price}\`**`, inline: false }) .addFields([
.setTimestamp() { name: '💰 Current Price', value: `**\`$${priceHistory.currentPrice}\`**`, inline: false },
.setImage(process.env.IMAGE_URL) { name: '1 Minute Change', value: `${oneMinChange.percent.toFixed(2)}% (${oneMinChange.dollar.toFixed(2)} USD)`, inline: true },
{ name: '5 Minute Change', value: `${fiveMinChange.percent.toFixed(2)}% (${fiveMinChange.dollar.toFixed(2)} USD)`, inline: true },
{ name: '1 Hour Change', value: `${oneHourChange.percent.toFixed(2)}% (${oneHourChange.dollar.toFixed(2)} USD)`, inline: true },
{ name: '1 Day Change', value: `${oneDayChange.percent.toFixed(2)}% (${oneDayChange.dollar.toFixed(2)} USD)`, inline: true }
])
.setTimestamp()
.setImage(process.env.IMAGE_URL);
const solanaPriceChannel = await client.channels.fetch(solanaPriceChannelId);
if (lastPriceMessageId) { if (lastPriceMessageId) {
try { try {
@ -69,22 +157,19 @@ async function checkPriceContinuously() {
await message.edit({ embeds: [embed] }); await message.edit({ embeds: [embed] });
} catch (error) { } catch (error) {
console.error('Error updating price message, sending a new one:', error); console.error('Error updating price message, sending a new one:', error);
const sentMessage = await solanaPriceChannel.send({ embeds: [embed] }); sendNewPriceMessage(solanaPriceChannel, embed);
lastPriceMessageId = sentMessage.id;
} }
} else { } else {
const sentMessage = await solanaPriceChannel.send({ embeds: [embed] }); console.log('No lastPriceMessageId found, sending a new message.');
lastPriceMessageId = sentMessage.id; sendNewPriceMessage(solanaPriceChannel, embed);
} }
if (lastKnownPriceAtStartup !== null && (parseFloat(price) - lastKnownPriceAtStartup >= 2.5)) { if (lastKnownPriceAtStartup !== null && (parseFloat(priceHistory.currentPrice) - lastKnownPriceAtStartup >= 2.5)) {
const announcementsChannel = await client.channels.fetch(announcementsChannelId); const announcementsChannel = await client.channels.fetch(announcementsChannelId);
await announcementsChannel.send(`@everyone Solana price has increased significantly! Current price: $${price}`); await announcementsChannel.send(`@everyone Solana price has increased significantly! Current price: $${priceHistory.currentPrice}`);
lastKnownPriceAtStartup = parseFloat(price); lastKnownPriceAtStartup = parseFloat(priceHistory.currentPrice);
} }
saveSolanaData({ price: parseFloat(price), lastPriceMessageId });
setTimeout(checkPriceContinuously, 60000); setTimeout(checkPriceContinuously, 60000);
} }
@ -93,7 +178,8 @@ function saveSolanaData(data) {
if (!fs.existsSync(dir)) { if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true }); fs.mkdirSync(dir, { recursive: true });
} }
fs.writeFileSync(solanaDataFile, JSON.stringify(data), 'utf8');
fs.writeFileSync(solanaDataFile, JSON.stringify(data, null, 2), 'utf8');
} }
function readSolanaData() { function readSolanaData() {