-
-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathindex.js
129 lines (120 loc) · 5.2 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
const config = require("./config.json"),
Discord = require("discord.js"),
Parser = require("rss-parser"),
parser = new Parser(),
Youtube = require("simple-youtube-api"),
youtube = new Youtube(config.youtubeKey);
const startAt = Date.now();
const lastVideos = {};
const client = new Discord.Client();
client.login(config.token).catch(console.log);
client.on("ready", () => {
console.log(`[!] Ready to listen ${config.youtubers.length} youtubers!`);
check();
setInterval(check, 20*1000);
});
/**
* Format a date to a readable string
* @param {Date} date The date to format
*/
function formatDate(date) {
let monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];
let day = date.getDate(), month = date.getMonth(), year = date.getFullYear();
return `${day} ${monthNames[parseInt(month, 10)]} ${year}`;
}
/**
* Call a rss url to get the last video of a youtuber
* @param {string} youtubeChannelName The name of the youtube channel
* @param {string} rssURL The rss url to call to get the videos of the youtuber
* @returns The last video of the youtuber
*/
async function getLastVideo(youtubeChannelName, rssURL){
console.log(`[${youtubeChannelName}] | Getting videos...`);
let content = await parser.parseURL(rssURL);
console.log(`[${youtubeChannelName}] | ${content.items.length} videos found`);
let tLastVideos = content.items.sort((a, b) => {
let aPubDate = new Date(a.pubDate || 0).getTime();
let bPubDate = new Date(b.pubDate || 0).getTime();
return bPubDate - aPubDate;
});
console.log(`[${youtubeChannelName}] | The last video is "${tLastVideos[0] ? tLastVideos[0].title : "err"}"`);
return tLastVideos[0];
}
/**
* Check if there is a new video from the youtube channel
* @param {string} youtubeChannelName The name of the youtube channel to check
* @param {string} rssURL The rss url to call to get the videos of the youtuber
* @returns The video || null
*/
async function checkVideos(youtubeChannelName, rssURL){
console.log(`[${youtubeChannelName}] | Get the last video..`);
let lastVideo = await getLastVideo(youtubeChannelName, rssURL);
// If there isn't any video in the youtube channel, return
if(!lastVideo) return console.log("[ERR] | No video found for "+lastVideo);
// If the date of the last uploaded video is older than the date of the bot starts, return
if(new Date(lastVideo.pubDate).getTime() < startAt) return console.log(`[${youtubeChannelName}] | Last video was uploaded before the bot starts`);
let lastSavedVideo = lastVideos[youtubeChannelName];
// If the last video is the same as the last saved, return
if(lastSavedVideo && (lastSavedVideo.id === lastVideo.id)) return console.log(`[${youtubeChannelName}] | Last video is the same as the last saved`);
return lastVideo;
}
/**
* Get the youtube channel id from an url
* @param {string} url The URL of the youtube channel
* @returns The channel ID || null
*/
function getYoutubeChannelIdFromURL(url) {
let id = null;
url = url.replace(/(>|<)/gi, "").split(/(\/channel\/|\/user\/)/);
if(url[2]) {
id = url[2].split(/[^0-9a-z_-]/i)[0];
}
return id;
}
/**
* Get infos for a youtube channel
* @param {string} name The name of the youtube channel or an url
* @returns The channel info || null
*/
async function getYoutubeChannelInfos(name){
console.log(`[${name.length >= 10 ? name.slice(0, 10)+"..." : name}] | Resolving channel infos...`);
let channel = null;
/* Try to search by ID */
let id = getYoutubeChannelIdFromURL(name);
if(id){
channel = await youtube.getChannelByID(id);
}
if(!channel){
/* Try to search by name */
let channels = await youtube.searchChannels(name);
if(channels.length > 0){
channel = channels[0];
}
}
console.log(`[${name.length >= 10 ? name.slice(0, 10)+"..." : name}] | Title of the resolved channel: ${channel.raw ? channel.raw.snippet.title : "err"}`);
return channel;
}
/**
* Check for new videos
*/
async function check(){
console.log("Checking...");
config.youtubers.forEach(async (youtuber) => {
console.log(`[${youtuber.length >= 10 ? youtuber.slice(0, 10)+"..." : youtuber}] | Start checking...`);
let channelInfos = await getYoutubeChannelInfos(youtuber);
if(!channelInfos) return console.log("[ERR] | Invalid youtuber provided: "+youtuber);
let video = await checkVideos(channelInfos.raw.snippet.title, "https://www.youtube.com/feeds/videos.xml?channel_id="+channelInfos.id);
if(!video) return console.log(`[${channelInfos.raw.snippet.title}] | No notification`);
let channel = client.channels.cache.get(config.channel);
if(!channel) return console.log("[ERR] | Channel not found");
channel.send({ content:
config.message
.replace("{videoURL}", video.link)
.replace("{videoAuthorName}", video.author)
.replace("{videoTitle}", video.title)
.replace("{videoPubDate}", formatDate(new Date(video.pubDate)))
});
console.log("Notification sent !");
lastVideos[channelInfos.raw.snippet.title] = video;
});
}