Added Functionality for Notification and Live Detection
This commit is contained in:
+122
-6
@@ -1,17 +1,133 @@
|
|||||||
const { Events, ActivityType } = require('discord.js');
|
const { Events, ActivityType, EmbedBuilder } = require('discord.js');
|
||||||
|
const { mClient, tClient, dClient } = require('../index');
|
||||||
|
|
||||||
|
// Global Maps and Sets
|
||||||
|
const channelList = new Map(); // Stores channel names and their subscribers
|
||||||
|
const isLive = new Set(); // Stores channels that are live
|
||||||
|
const isOffline = new Set(); // Stores channels that are offline
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: Events.ClientReady,
|
name: Events.ClientReady,
|
||||||
once: true,
|
once: true,
|
||||||
async execute(client) {
|
async execute(client) {
|
||||||
console.log(`Ready! Logged in as ${client.user.tag}`)
|
console.log(`Ready! Logged in as ${client.user.tag}`);
|
||||||
|
|
||||||
|
// Set bot presence
|
||||||
client.user.setPresence({
|
client.user.setPresence({
|
||||||
activities: [{
|
activities: [{
|
||||||
name: 'Notyfing',
|
name: 'Notifications for you',
|
||||||
type: ActivityType.Streaming,
|
type: ActivityType.Streaming,
|
||||||
url: 'https://twitch.tv/desq_blocki'
|
url: 'https://twitch.tv/desq_blocki',
|
||||||
}],
|
}],
|
||||||
status: 'online'
|
status: 'online',
|
||||||
})
|
});
|
||||||
|
|
||||||
|
// Main interval loop
|
||||||
|
setInterval(async () => {
|
||||||
|
await updateCache();
|
||||||
|
await notifySubscribers();
|
||||||
|
}, 5000); // Every 5 seconds
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update the cache from the database and clean up stale data
|
||||||
|
async function updateCache() {
|
||||||
|
const db = mClient.db('notifyme');
|
||||||
|
const channelsColl = db.collection('channels');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const channels = await channelsColl.find({}).toArray();
|
||||||
|
const dbChannelNames = new Set(channels.map(channel => channel.name));
|
||||||
|
|
||||||
|
// Update channelList
|
||||||
|
channelList.clear();
|
||||||
|
channels.forEach(channel => channelList.set(channel.name, channel.subscribers));
|
||||||
|
|
||||||
|
// Remove stale entries from isLive and isOffline
|
||||||
|
cleanUpSet(isLive, dbChannelNames);
|
||||||
|
cleanUpSet(isOffline, dbChannelNames);
|
||||||
|
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
// console.log({
|
||||||
|
// isLive: Array.from(isLive),
|
||||||
|
// isOffline: Array.from(isOffline),
|
||||||
|
// channels: Array.from(channelList.entries()),
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error updating cache:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notify subscribers about live status changes
|
||||||
|
async function notifySubscribers() {
|
||||||
|
for (const [channelName, subscribers] of channelList) {
|
||||||
|
try {
|
||||||
|
const streamData = await tClient.getStreams({ channel: channelName });
|
||||||
|
|
||||||
|
if (streamData?.data[0]) {
|
||||||
|
// Stream is live
|
||||||
|
if (!isLive.has(channelName)) {
|
||||||
|
await notifyLive(channelName, subscribers, streamData.data[0]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Stream is offline
|
||||||
|
if (isLive.has(channelName)) {
|
||||||
|
console.log(`${channelName} went offline!`);
|
||||||
|
isLive.delete(channelName);
|
||||||
|
}
|
||||||
|
isOffline.add(channelName);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error notifying for ${channelName}:`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify subscribers that a channel has gone live
|
||||||
|
async function notifyLive(channelName, subscribers, streamData) {
|
||||||
|
const liveData = {
|
||||||
|
streamer: streamData.user_name,
|
||||||
|
game: streamData.game_name,
|
||||||
|
title: streamData.title,
|
||||||
|
thumbnail: streamData.thumbnail_url.replace('-{width}x{height}', ''),
|
||||||
|
tags: streamData.tags,
|
||||||
|
};
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle(`${escapeMarkdown(liveData.streamer)} is live!`)
|
||||||
|
.setDescription(`They're playing ${liveData.game}`)
|
||||||
|
.addFields({ name: '\u200B', value: `${liveData.title}` })
|
||||||
|
.setImage(liveData.thumbnail)
|
||||||
|
.setURL(`https://twitch.tv/${channelName}`)
|
||||||
|
.setFooter({ text: liveData.tags.map(tag => `#${tag}`).join(' ') });
|
||||||
|
|
||||||
|
for (const subscriber of subscribers) {
|
||||||
|
try {
|
||||||
|
const user = await dClient.users.fetch(subscriber);
|
||||||
|
await user.send({ embeds: [embed] });
|
||||||
|
console.log(`${user.username} notified that ${channelName} went live!`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error notifying ${subscriber}:`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isLive.add(channelName);
|
||||||
|
isOffline.delete(channelName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to clean up stale data in a set
|
||||||
|
function cleanUpSet(set, validEntries) {
|
||||||
|
for (const entry of set) {
|
||||||
|
if (!validEntries.has(entry)) {
|
||||||
|
set.delete(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escape special markdown characters
|
||||||
|
function escapeMarkdown(input) {
|
||||||
|
return input.replace(/([*_#\[!\]()`>+\-.|])/g, '\\$1');
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user