initial commit

This commit is contained in:
KrazyDev
2021-10-06 12:45:40 +05:30
commit f376de0d98
8 changed files with 2490 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
node_modules
.env
json.sqlite

87
README.md Normal file
View File

@@ -0,0 +1,87 @@
# Installations
```
npm i discord-youtube-notifications
```
# What?
An module to easily recive Youtube uploads notification.
# Why?
- Easy to use.
- Active Support on [discord server](https://discord.gg/XYnMTQNTFh).
- No API key needed.
# Note
- At least Node JS `14` is `required`.
- The feeds thing of youtube takes some time to update, so the notifications might be bit slow.
# How ?
- ## Basic NOtifications
```js
const youtube = require('discord-youtube-notifications');
const Notifier = new youtube.notifier(client);
const youtube_channel_id = "UCSqcbw8r8TZKYUhx4mufvNg";
const discord_channel_id = "732883841395720213";
Notifier.addNotifier(youtube_channel_id, discord_channel_id);
```
- ## Custom Message
```js
const youtube = require('discord-youtube-notifications');
const Notifier = new youtube.notifier(client, {
// If you do not add message parameter in addNotifier than this message is used
message: "Hello @everyone, **{author}** just publish a cool video called **{title}**\nGo show your support\n\nurl : {url}"
});
const youtube_channel_id = "UCSqcbw8r8TZKYUhx4mufvNg";
const discord_channel_id = "732883841395720213";
Notifier.addNotifier(youtube_channel_id, discord_channel_id);
// A different message
Notifier.addNotifier("Another Channel ID", discord_channel_id, "Hello guys, A nerd called **{author}** just publish a shit video called **{title}**\nGo dislike it\n\nurl : {url}");
```
- ## Advanced options
```js
const youtube = require('discord-youtube-notifications');
const Notifier = new youtube.notifier(client, {
// Default message
message: "Hello @everyone, **{author}** just publish a cool video called **{title}**\nGo show your support\n\nurl : {url}",
// Time interval to check for new uploads
updateTime:60000, // in milliseconds,
// Give the mongo URI if you wanna save data in mongoose otherwise quick.db is used
mongoURI:"mongo+srv://something",
// Auto send the embed to the provided channel
autoSend:true, // if false you will get A "upload" event
});
```
- ## Listening to events
```js
Notifier.on("upload", (client, data) => {
// Do something with your data
});
// Example Data
const data = {
youtube: "UCSqcbw8r8TZKYUhx4mufvNg", // The Youtube channel ID
channel: channelID, // The discord channel ID
lastVideo: last.link || "", // Latest video link
message: "new upload", // Custom message
author: "Krazy Developer", // The name of youtube channel
title: "How to code", // title of the video
title: "https://www.youtube.com/watch?v=CmK5JLt0GQ4", // Link of the video
}
```
# Support
for support or issues or queries contace me on my [discord server](https://discord.gg/XYnMTQNTFh).

2221
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

26
package.json Normal file
View File

@@ -0,0 +1,26 @@
{
"name": "discord-youtube-notifications",
"version": "1.0.0",
"description": "An module to get youtube notifications.",
"main": "src/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"youtube",
"notification",
"notifier",
"discord",
"bot"
],
"author": "shisui",
"license": "MIT",
"dependencies": {
"discord.js": "^13.2.0",
"mongoose": "^6.0.6",
"node-cron": "^3.0.0",
"quick.db": "^7.1.3",
"rss-parser": "^3.12.0",
"yt-channel-info": "^2.2.0"
}
}

87
src/index.js Normal file
View File

@@ -0,0 +1,87 @@
const quick = require('quick.db');
const mongoose = require('mongoose');
const channel = require('./models/channel');
const lastVideo = require('./utility/lastVideo');
const checker = require('./utility/checker');
const EventEmitter = require('events');
class notifier extends EventEmitter {
/** The variable which stores the update time interval
* @var {Number} _updateTime
*/
_updateTime = 60000;
_channels = [];
constructor(client, { autoSend = true, mongoURI = "quick.db", message = "**{author}** uploaded a new video, Go check it out\n\nLink : {url}", updateTime = 60000 } = {}) {
super();
if (!client) throw new Error("No client was provided")
if (typeof (updateTime) !== "number" || updateTime < 1000) throw new TypeError("Update time should be a number and at least 60000");
if (typeof (message) !== "string") throw new TypeError("The default message should be a string");
if (typeof (autoSend) !== "boolean") throw new TypeError("The autoSend property should be a boolean");
this.client = client;
this._mongoURI = mongoURI;
this._message = message;
this._updateTime = updateTime
this.autoSend = autoSend;
if (mongoURI.toLowerCase() === "quick.db") {
this._quickSetup();
setInterval(() => this._load(), this._updateTime);
} else {
this._mongoSetup();
setInterval(() => this._load(), this._updateTime);
}
}
async _mongoSetup() {
await mongoose.connect(this._mongoURI).catch(e => { throw new Error("Invalid Mongo URI was provided, type quick.db or don't provide the uri at all, If you want to work without mongo") });
this._channels = await channel.find() || [];
}
_quickSetup() {
if (!quick.has("channels")) quick.set("channels", [])
this._channels = quick.get("channels") || [];
}
_load() {
this?._channels?.forEach(v => {
checker.bind(this)(v);
})
}
async addNotifier(youtubeId, channelID, message) {
if (this._channels.some(v => v.youtube === youtubeId)) throw new Error("This channel already exist");
const last = await lastVideo({ youtube: youtubeId });
if (last === false) throw new Error("Channel not found");
this._channels.push({
youtube: youtubeId,
channel: channelID,
lastVideo: last.link || "",
message: message || this._message
})
this._mongoURI === "quick.db" ? quick.push("channels", this._channels[this._channels.length - 1]) : await channel.create(this._channels[this._channels.length - 1]);
return this;
}
async removeNotifier(youtubeId) {
this._channels = this._channels.filter(v => v.youtube !== youtubeId);
this._mongoURI === "quick.db" ? quick.set("channels", this._channels) : await channel.findOneAndDelete({ youtube: youtubeId });
return this;
}
}
module.exports = {
notifier,
channelModel: channel,
}

20
src/models/channel.js Normal file
View File

@@ -0,0 +1,20 @@
const { Schema, model } = require("mongoose");
const channelSchema = new Schema({
youtube: {
type: String,
required: true,
unique: true
},
channel: {
type: String,
},
lastVideo: {
type: String,
},
message: {
type: String,
},
})
module.exports = model("youtube", channelSchema)

35
src/utility/checker.js Normal file
View File

@@ -0,0 +1,35 @@
const lastVideo = require('./lastVideo');
const quick = require('quick.db');
const Channel = require('../models/channel');
module.exports = function (channel) {
lastVideo(channel).then(async v => {
const data = channel.lastVideo;
if (data !== v.link && v && v.link) {
this._channels = this._channels.filter(v => v.youtube !== channel.youtube)
this._mongoURI === "quick.db" ? quick.set('channels', this._channels) : await Channel.findOneAndUpdate({ youtube: channel.youtube }, { lastVideo: v.link });
channel.lastVideo = v.link;
this._channels.push(channel)
channel.author = v.author;
channel.title = v.title;
if (!this.autoSend) return this.emit("upload", this.client, channel);
(await this.client.channels.fetch(channel.channel))?.send({
embeds: [{
description: channel.message.replace(/{author}/g, v.author)
.replace(/{title}/g, v.title)
.replace(/{url}/g, v.link)
}]
}).catch(e => {
console.warn(`[ Youtube Notifier ] : I was unable to send message channel : ${channel.channel} for youtube channel ${channel.youtube}`);
})
}
})
}

11
src/utility/lastVideo.js Normal file
View File

@@ -0,0 +1,11 @@
const parser = new (require('rss-parser'))();
module.exports = (youtubeChannel) => {
return new Promise(res => {
parser.parseURL("https://www.youtube.com/feeds/videos.xml?channel_id=" + youtubeChannel.youtube).then(v => {
res(v.items[0] || {});
}).catch(e => {
res(false);
})
})
}