·12 min read
Building a Discord Bot That Shows YouTube Channel Banners
Step by step guide to building a Discord bot with discord.js that displays YouTube channel banners, avatars, and subscriber counts using the banner.yt API.
DiscordBotAPIJavaScriptTutorial
Discord Bot for YouTube Channel Banners
This tutorial walks through building a Discord bot that lets users run a command like /banner mrbeast and get back the channel banner, avatar, and stats as a rich embed.
What you need
- Node.js 18 or newer
- A Discord bot token (from discord.com/developers)
- discord.js v14
- The banner.yt API (no key required)
Project setup
mkdir yt-banner-bot && cd yt-banner-bot
npm init -y
npm install discord.js
index.js
const { Client, GatewayIntentBits, EmbedBuilder, SlashCommandBuilder } = require('discord.js');
const { REST, Routes } = require('discord.js');
const TOKEN = process.env.DISCORD_TOKEN;
const CLIENT_ID = process.env.CLIENT_ID;
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.on('ready', () => {
console.log('Bot ready as', client.user.tag);
});
client.on('interactionCreate', async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName !== 'banner') return;
const query = interaction.options.getString('channel');
await interaction.deferReply();
try {
// Search for the channel first
const searchRes = await fetch(
`https://banner.yt/api/search?q=${encodeURIComponent(query)}`
);
const { results } = await searchRes.json();
if (!results || results.length === 0) {
return interaction.editReply('Could not find that channel.');
}
const topResult = results[0];
const { channelId, title } = topResult;
// Get full channel data
const channelRes = await fetch(`https://banner.yt/api/channel/${channelId}`);
const channel = await channelRes.json();
const bannerUrl = `https://banner.yt/api/banner/${channelId}?format=jpeg`;
const avatarUrl = `https://banner.yt/api/banner/${channelId}?type=avatar&format=jpeg`;
const embed = new EmbedBuilder()
.setTitle(channel.title || title)
.setURL(`https://www.youtube.com/channel/${channelId}`)
.setDescription(channel.description?.slice(0, 100) || '')
.setImage(bannerUrl)
.setThumbnail(avatarUrl)
.addFields(
{ name: 'Subscribers', value: formatNumber(channel.subscriberCount), inline: true },
{ name: 'Total Views', value: formatNumber(channel.viewCount), inline: true },
{ name: 'Channel ID', value: channelId, inline: false },
)
.setColor(0xFF0000)
.setFooter({ text: 'banner.yt' });
await interaction.editReply({ embeds: [embed] });
} catch (err) {
await interaction.editReply('Something went wrong, try again.');
}
});
function formatNumber(n) {
if (!n) return 'N/A';
const num = parseInt(n, 10);
if (num >= 1_000_000) return (num / 1_000_000).toFixed(1) + 'M';
if (num >= 1_000) return (num / 1_000).toFixed(1) + 'K';
return num.toString();
}
// Register slash command
const commands = [
new SlashCommandBuilder()
.setName('banner')
.setDescription('Get a YouTube channel banner')
.addStringOption(opt =>
opt.setName('channel').setDescription('Channel name or ID').setRequired(true)
),
].map(c => c.toJSON());
const rest = new REST().setToken(TOKEN);
rest.put(Routes.applicationCommands(CLIENT_ID), { body: commands })
.then(() => console.log('Commands registered'))
.catch(console.error);
client.login(TOKEN);
Running the bot
DISCORD_TOKEN=your_token CLIENT_ID=your_client_id node index.js
Now any server member can type /banner MrBeast and the bot will reply with the banner image, avatar, subscriber count, and view count in a clean embed.
Add more commands
You can extend this to add a /avatar command, a /stats command for just the numbers, or even a /compare command that shows two channels side by side.