Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
node_modules
json.sqlite
package-lock.json
package.json
17 changes: 17 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}\\index.js"
}
]
}
24 changes: 18 additions & 6 deletions config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
module.exports = {
token: "YOUR_DISCORD_BOT_TOKEN",
channel: "XXXXXXXXXXXXXXXXXX",
messageTemplate: "Hello @everyone, **{author}** just now uploaded a video **{title}**!\n{url}",
channel_id: "YOUTUBE_CHANNEL_ID",
watchInterval: 30000
}
token: "your discord bot token",
messageTemplate:
"Hello everyone, **{author}** just now uploaded a video **{title}**!\n{url}",
//dont change messageTemplate
channel_id: [
{
channel: "discord channel id 1",
youtube_channel_id: "advanced settings (in pc) -> youtube channel id",
},
{
channel: "discord channel id 2",
youtube_channel_id: "youtube channel id 2",
},
// ... more channels if you want same logic
],
watchInterval: 10000,
youtubeApiKey: "Token from google cloud platform",
};
78 changes: 48 additions & 30 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,52 @@
const Discord = require("discord.js");
const client = new Discord.Client();
client.db = require("quick.db");
client.request = new (require("rss-parser"))();
client.config = require("./config.js");

client.on("ready", () => {
console.log("I'm ready!");
handleUploads();
const { Client, GatewayIntentBits } = require("discord.js");
const axios = require("axios");
const config = require("./config");

const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
});

function handleUploads() {
if (client.db.fetch(`postedVideos`) === null) client.db.set(`postedVideos`, []);
setInterval(() => {
client.request.parseURL(`https://www.youtube.com/feeds/videos.xml?channel_id=${client.config.channel_id}`)
.then(data => {
if (client.db.fetch(`postedVideos`).includes(data.items[0].link)) return;
else {
client.db.set(`videoData`, data.items[0]);
client.db.push("postedVideos", data.items[0].link);
let parsed = client.db.fetch(`videoData`);
let channel = client.channels.cache.get(client.config.channel);
if (!channel) return;
let message = client.config.messageTemplate
.replace(/{author}/g, parsed.author)
.replace(/{title}/g, Discord.Util.escapeMarkdown(parsed.title))
.replace(/{url}/g, parsed.link);
channel.send(message);
}
});
}, client.config.watchInterval);
// Object to store last video IDs for each channel (avoiding global variable)
const lastVideoIds = {};

async function checkYouTube() {
try {
for (const channelConfig of config.channel_id) {
const { channel, youtube_channel_id } = channelConfig;
const lastVideoIdKey = `lastVideoId_${youtube_channel_id}`;

const response = await axios.get(
`https://www.googleapis.com/youtube/v3/search?key=${config.youtubeApiKey}&channelId=${youtube_channel_id}&part=snippet,id&order=date&maxResults=1`
);

const video = response.data.items[0];

if (
!lastVideoIds[lastVideoIdKey] ||
video.id.videoId !== lastVideoIds[lastVideoIdKey]
) {
lastVideoIds[lastVideoIdKey] = video.id.videoId; // Store last video ID for each channel

const discordChannel = await client.channels.fetch(channel);
const message = config.messageTemplate
.replace("{author}", video.snippet.channelTitle)
.replace("{title}", video.snippet.title)
.replace(
"{url}",
`https://www.youtube.com/watch?v=${video.id.videoId}`
);
discordChannel.send(message);
}
}
} catch (error) {
console.error("Error fetching YouTube data:", error);
}
}

client.login(client.config.token);
client.once("ready", () => {
console.log("Bot is online!");
checkYouTube();
setInterval(checkYouTube, config.watchInterval);
});

client.login(config.token);
24 changes: 5 additions & 19 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,12 @@
"description": "Simple and easy to use discord bot to notify members whenever a video is posted on a YouTube channel.",
"main": "index.js",
"scripts": {
"test": "node index.js"
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Snowflake107/youtube-notification-bot.git"
},
"keywords": [
"youtube",
"discord.js",
"notification-bot"
],
"author": "Snowflake07",
"license": "MIT",
"bugs": {
"url": "https://github.com/Snowflake07/youtube-notification-bot/issues"
},
"homepage": "https://github.com/Snowflake07/youtube-notification-bot#readme",
"author": "",
"license": "ISC",
"dependencies": {
"discord.js": "^12.0.2",
"quick.db": "^7.0.0-b22",
"rss-parser": "^3.7.5"
"axios": "^1.7.3",
"discord.js": "^14.15.3"
}
}
141 changes: 122 additions & 19 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,122 @@
# Youtube Notification Bot
Simple and easy to use discord bot to notify members whenever a video is posted on a YouTube channel.

# Packages Used
- **[discord.js](https://npmjs.com/package/discord.js "View on npmjs")**
- **[quick.db](https://npmjs.com/package/quick.db "View on npmjs")**
- **[rss-parser](https://npmjs.com/package/rss-parser "View on npmjs")**

# config.js

```js
module.exports = {
token: "YOUR_DISCORD_BOT_TOKEN", // discord bot token
channel: "DISCORD_CHANNEL_ID", // channel id of a channel to send message
messageTemplate: "Hello @everyone, **{author}** just now uploaded a video **{title}**!\n{url}", // message to send on discord
channel_id: "YOUTUBE_CHANNEL_ID", // youtube channel id
watchInterval: 30000 // Check every 30 seconds
};
```
Absolutely! Here's the updated README with the changes incorporated:

## Discord YouTube Notification Bot

First, delete `package.json` if it exists, and run `npm init` to create a basic one. This bot checks your configured YouTube channels every **15 seconds** for new uploads or live streams and sends notifications to the corresponding Discord channels. It utilizes the YouTube Data API and the `discord.js` library.

## Table of Contents

- [Installation](#installation)
- [Configuration](#configuration)
- [Running the Bot](#running-the-bot)
- [Code Explanation](#code-explanation)
- [Dependencies](#dependencies)

## Installation

1. **Clone the Repository (if applicable):**

```bash
git clone https://github.com/your-username/discord-youtube-notification-bot.git
cd discord-youtube-notification-bot
```

2. **Initialize `package.json`:**

```bash
npm init -y
```

This creates a basic `package.json` file for your project.

3. **Install Required Packages:**

```bash
npm install discord.js axios
```

4. **Get YouTube Data API Key:**

- Go to the [Google Cloud Console](https://console.cloud.google.com/).
- Create a new project (if needed).
- Enable the YouTube Data API v3 for your project.
- Create an API key.

## Configuration

1. **Create `config.js` File:**

In the root directory of your project, create a file named `config.js` and add the following configuration:

```javascript
module.exports = {
token: "YOUR_DISCORD_BOT_TOKEN",
channel_id: [
{
channel: "YOUR_DISCORD_CHANNEL_ID_1",
youtube_channel_id: "YOUR_YOUTUBE_CHANNEL_ID_1",
// optional: messageTemplate: "Custom template for channel 1"
},
{
channel: "YOUR_DISCORD_CHANNEL_ID_2",
youtube_channel_id: "YOUR_YOUTUBE_CHANNEL_ID_2",
},
// ... add more channel configurations
],
watchInterval: 15000, // 15 seconds in milliseconds
youtubeApiKey: "YOUR_YOUTUBE_API_KEY",
};
```

- `token`: Your Discord bot token (from Developer Portal).
- `channel_id`: An array of objects containing configuration for each monitored channel.
- `channel`: ID of the Discord channel for notifications.
- `youtube_channel_id`: ID of the YouTube channel to monitor.
- `messageTemplate` (optional): Custom message template for this channel.
- `watchInterval`: The interval (in milliseconds) for checking new uploads (default: 15 seconds).
- `youtubeApiKey`: Your YouTube Data API key.

## Running the Bot

1. **Run the Bot:**

```bash
node index.js
```

If everything is set up correctly, you should see the following output:

```bash
Bot is online!
```

2. **Bot Operation:**

- The bot checks for new uploads on your configured YouTube channels every 15 seconds.
- If a new video is found for any channel, it sends a notification to the corresponding Discord channel with a customized message template (if provided).

## Code Explanation

### `config.js`

This file houses the configuration for your bot, including Discord bot token, channel configurations (with Discord and YouTube channel IDs, optional custom message templates), watch interval, and YouTube API key.

### `index.js`

This is the main file for the bot. It performs the following:

- Initializes the Discord client.
- Iterates through each channel configuration in `config.js`.
- For each channel, fetches the latest video from the YouTube channel using the YouTube Data API.
- Compares the fetched video ID with the last fetched video ID stored separately for each channel (using a unique key).
- Sends a notification to the specified Discord channel if a new video is found, using the corresponding message template (if provided).

### Key Functions:

- `checkYouTube(config)`: Fetches the latest video from YouTube channels, compares IDs, and sends notifications if needed.
- `client.once('ready', ...)`: Runs when the bot is ready. Starts the initial check and sets up an interval for periodic checks.

## Dependencies

- **discord.js**: Library to interact with the Discord API.
- \*\*