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 = {
|
||||
name: Events.ClientReady,
|
||||
once: true,
|
||||
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({
|
||||
activities: [{
|
||||
name: 'Notyfing',
|
||||
name: 'Notifications for you',
|
||||
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