260 lines
8.8 KiB
JavaScript
260 lines
8.8 KiB
JavaScript
const { configDotenv } = require('dotenv');
|
|
const { MongoClient } = require('mongodb');
|
|
const TwitchApi = require("node-twitch").default
|
|
const tClient = new TwitchApi({
|
|
client_id: process.env.TTV_ID,
|
|
client_secret: process.env.TTV_SECRET
|
|
});
|
|
configDotenv
|
|
const mClient = new MongoClient(process.env.MONGO_URL);
|
|
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
|
|
|
|
async function SubscribeChannel(interaction) {
|
|
const channelName = encodeURI(await interaction.options.getString('channel')).toLowerCase()
|
|
const userID = interaction.user.id
|
|
try {
|
|
let streamData = await tClient.getStreams({ channel: channelName })
|
|
//console.log(await tClient.searchChannels({query: `${channelName}`})) // returns too many results and not exact match first
|
|
} catch (error) {
|
|
return interaction.reply({
|
|
content: `**[ERROR]:** Could not validate channel name for *${channelName}*!\r\n${error}`,
|
|
ephemeral: true
|
|
}).then(setTimeout(() => {
|
|
interaction.deleteReply()
|
|
}, 5000))
|
|
}
|
|
|
|
const db = mClient.db('notifyme')
|
|
const channelsColl = db.collection('channels')
|
|
|
|
const find = await channelsColl.find({ channel: channelName }).toArray()
|
|
|
|
if (find[0]) {
|
|
if (find[0].users.includes(userID)) {
|
|
return interaction.reply({
|
|
content: `**[WARNING]:** You are already subscribed to *${channelName}*!`,
|
|
ephemeral: true
|
|
}).then(setTimeout(() => {
|
|
interaction.deleteReply()
|
|
}, 5000))
|
|
}
|
|
}
|
|
|
|
try {
|
|
const res = await channelsColl.findOneAndUpdate({
|
|
channel: channelName
|
|
}, {
|
|
$set: {
|
|
channel: channelName,
|
|
},
|
|
$push: {
|
|
users: userID
|
|
}
|
|
}, {
|
|
upsert: true,
|
|
returnDocument: 'after'
|
|
})
|
|
} catch (error) {
|
|
return interaction.reply({
|
|
content: `**[ERROR]:** There was an issue updating the database!\r\n${error}`,
|
|
ephemeral: true
|
|
}).then(setTimeout(() => {
|
|
interaction.deleteReply()
|
|
}, 5000))
|
|
}
|
|
//console.log(res) // debug
|
|
return interaction.reply({
|
|
content: `**[SUCCESS]:** You are now subscribed to *${channelName}*!`,
|
|
ephemeral: true
|
|
}).then(setTimeout(() => {
|
|
interaction.deleteReply()
|
|
}, 5000))
|
|
}
|
|
|
|
async function UnsubscribeChannel(interaction) {
|
|
const channelName = encodeURI(await interaction.options.getString('channel')).toLowerCase()
|
|
const userID = interaction.user.id
|
|
|
|
const db = mClient.db('notifyme')
|
|
const channelsColl = db.collection('channels')
|
|
|
|
const find = await channelsColl.find({ channel: channelName }).toArray()
|
|
|
|
if (find[0]) {
|
|
if (!find[0].users.includes(userID)) {
|
|
return interaction.reply({
|
|
content: `**[WARNING]:** You were not subscribed to *${channelName}*!`,
|
|
ephemeral: true
|
|
}).then(setTimeout(() => {
|
|
interaction.deleteReply()
|
|
}, 5000))
|
|
}
|
|
}
|
|
|
|
try {
|
|
const res = await channelsColl.findOneAndUpdate({
|
|
channel: channelName
|
|
}, {
|
|
$set: {
|
|
channel: channelName,
|
|
},
|
|
$pull: {
|
|
users: userID
|
|
}
|
|
}, {
|
|
upsert: true,
|
|
returnDocument: 'after'
|
|
})
|
|
} catch (error) {
|
|
return interaction.reply({
|
|
content: `**[ERROR]:** There was an issue with the database!\r\n${error}`,
|
|
ephemeral: true
|
|
}).then(setTimeout(() => {
|
|
interaction.deleteReply()
|
|
}, 5000))
|
|
}
|
|
//console.log(res) // debug
|
|
return interaction.reply({
|
|
content: `**[SUCCESS]:** You are no longer subscribed to *${channelName}*!`,
|
|
ephemeral: true
|
|
}).then(setTimeout(() => {
|
|
interaction.deleteReply()
|
|
}, 5000))
|
|
}
|
|
|
|
async function ListChannel(interaction) {
|
|
const userID = interaction.user.id
|
|
|
|
const db = mClient.db('notifyme')
|
|
const channelsColl = db.collection('channels')
|
|
|
|
const find = await channelsColl.find({ users: userID }).toArray()
|
|
var channelList = []
|
|
find.forEach((document) => {
|
|
channelList.push(document.channel)
|
|
})
|
|
const embed = new EmbedBuilder()
|
|
.setTitle('Lists of Subscribed Channels:')
|
|
.setDescription(channelList.join("\n"))
|
|
|
|
return interaction.reply({
|
|
embeds: [embed],
|
|
ephemeral: true
|
|
})
|
|
}
|
|
|
|
async function InfoChannel(interaction) {
|
|
const channelName = encodeURI(await interaction.options.getString('channel')).toLowerCase()
|
|
try {
|
|
let streamData = await tClient.getStreams({ channel: channelName })
|
|
if (streamData?.data[0]) {
|
|
let liveData = {
|
|
streamer: streamData.data[0].user_name,
|
|
game: streamData.data[0].game_name,
|
|
title: streamData.data[0].title,
|
|
thumbnail: streamData.data[0].thumbnail_url.replace('-{width}x{height}', ''),
|
|
tags: streamData.data[0].tags
|
|
}
|
|
const embed = new EmbedBuilder()
|
|
.setTitle(`${liveData.streamer} is live!`)
|
|
.setDescription(`They're playing ${liveData.game}`)
|
|
.addFields(
|
|
{ name: '\u200B', value: `${liveData.title}` })
|
|
.setImage(liveData.thumbnail)
|
|
.setURL(`https://twitch.tv/${channelName}`)
|
|
let footer = ""
|
|
liveData.tags.forEach((tag) => {
|
|
footer += `${footer?',':''} #${tag}`
|
|
})
|
|
embed.setFooter({
|
|
text: footer
|
|
})
|
|
|
|
return interaction.reply({
|
|
embeds: [embed],
|
|
ephemeral: true
|
|
})
|
|
} else {
|
|
const embed = new EmbedBuilder()
|
|
.setTitle(`${channelName} is currently offline!`)
|
|
.setImage('https://media.discordapp.net/attachments/1061304429724319794/1319800268770250883/no-signal-tv-descendant-network-rainbow-bars-abstract-background-vector.jpg?ex=67674748&is=6765f5c8&hm=d539944a67fccec461b0183a9f0300e19ac485deda7b23090165088567f2c84f&=&format=webp')
|
|
.setURL(`https://twitch.tv/${channelName}`)
|
|
return interaction.reply({
|
|
embeds: [embed],
|
|
ephemeral: true
|
|
})
|
|
}
|
|
//streamData = streamData.
|
|
//console.log(await tClient.searchChannels({query: `${channelName}`})) // returns too many results and not exact match first
|
|
} catch (error) {
|
|
console.error(error)
|
|
return interaction.reply({
|
|
content: `**[ERROR]:** Could not validate channel name for *${channelName}*!\r\n${error}`,
|
|
ephemeral: true
|
|
}).then(setTimeout(() => {
|
|
interaction.deleteReply()
|
|
}, 5000))
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
data: new SlashCommandBuilder()
|
|
.setName('channel')
|
|
.setDescription('channel related commands')
|
|
.addSubcommand(s =>
|
|
s
|
|
.setName('subscribe')
|
|
.setDescription('subscribe to notifications when this channel goes live')
|
|
.addStringOption(o =>
|
|
o
|
|
.setName('channel')
|
|
.setDescription('channel name')
|
|
.setRequired(true)
|
|
)
|
|
)
|
|
.addSubcommand(s =>
|
|
s
|
|
.setName('unsubscribe')
|
|
.setDescription('unsubscribe to notifications when this channel goes live')
|
|
.addStringOption(o =>
|
|
o
|
|
.setName('channel')
|
|
.setDescription('channel name')
|
|
.setRequired(true)
|
|
)
|
|
)
|
|
.addSubcommand(s =>
|
|
s
|
|
.setName('list')
|
|
.setDescription('list your subscribed channels')
|
|
)
|
|
.addSubcommand(s =>
|
|
s
|
|
.setName('info')
|
|
.setDescription('get information on a live channel')
|
|
.addStringOption(o =>
|
|
o
|
|
.setName('channel')
|
|
.setDescription('channel name')
|
|
.setRequired(true)
|
|
)
|
|
),
|
|
async execute(interaction) {
|
|
switch (interaction.options._subcommand) {
|
|
case 'subscribe':
|
|
SubscribeChannel(interaction)
|
|
break;
|
|
case 'unsubscribe':
|
|
UnsubscribeChannel(interaction)
|
|
break;
|
|
case 'list':
|
|
ListChannel(interaction)
|
|
break;
|
|
case 'info':
|
|
InfoChannel(interaction)
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
} |