Add more tracking to embed
This commit is contained in:
parent
d1802a291d
commit
bcdfb07eb0
144
main.js
144
main.js
|
@ -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([
|
||||||
|
{ name: '💰 Current Price', value: `**\`$${priceHistory.currentPrice}\`**`, inline: false },
|
||||||
|
{ 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()
|
.setTimestamp()
|
||||||
.setImage(process.env.IMAGE_URL)
|
.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() {
|
||||||
|
|
Loading…
Reference in New Issue