Is there any way to obtain user banner on discord using discord.js? User banner is new feature, so I am not sure if there is any way so far. I didn't find anything in docs. Eg. server banner is available on:
.png
.
Something similar for user banner would be great.
Is there any way to obtain user banner on discord using discord.js? User banner is new feature, so I am not sure if there is any way so far. I didn't find anything in docs. Eg. server banner is available on:
https://cdn.discordapp.com/banners/GUILD_ID/GUILD_BANNER.png
.
Something similar for user banner would be great.
Share Improve this question asked Jul 11, 2021 at 8:17 MichalMichal 2,0733 gold badges28 silver badges63 bronze badges 1- There is nothing in the official documentation about getting a users banner, so as of now I do not believe there is a way. However this feature is still in discord BETA so keep an eye out as they may release an endpoint soon. – Tyler2P Commented Jul 11, 2021 at 8:33
4 Answers
Reset to default 9I managed to recover a discord banner after several hours of development, the code below :
( you need to install "node-fetch" => npm i node-fetch )
const fetch = require('node-fetch')
let uid = "user_id"
let response = fetch(`https://discord.com/api/v8/users/${uid}`, {
method: 'GET',
headers: {
Authorization: `Bot ${client.token}`
}
})
let receive = ''
let banner = 'https://cdn.discordapp.com/attachments/829722741288337428/834016013678673950/banner_invisible.gif' // invisible image ( you can change the link if you want )
response.then(a => {
if(a.status !== 404) {
a.json().then(data => {
receive = data['banner']
if(receive !== null) {
let format = 'png'
if(receive.substring(0,2) === 'a_') {
format = 'gif'
}
banner = `https://cdn.discordapp.com/banners/${uid}/${receive}.${format}`
}})
.setTimeout(() => {
// To retrieve the value "banner" we put a timeout otherwise it will return us the first definition of "banner" that is to say the invisible image, I let you modify the code as you wish, good evening to you (and also I just wanted to make it clear I'm French)
// Put the rest of your code here :
}, 1000)
Simple solution
The simplest solution for discord.js v12 I came up with:
async function getUserBannerUrl(userId) {
const user = await client.api.users(userId).get();
return user.banner ? `https://cdn.discordapp.com/banners/${userId}/${user.banner}?size=512` : null;
}
However this doesn't handle mime types well. You don't know what the mime type is unless you read the content-type
header. This may break some things that require you to have a file extension in your URL. That's why I came up with more complex solution.
Complex solution
The code below is dependent on axios
.
const axios = require("axios");
async function getUserBannerUrl(userId, { dynamicFormat = true, defaultFormat = "webp", size = 512 } = {}) {
// Supported image sizes, inspired by 'https://discord.js.org/#/docs/main/stable/typedef/ImageURLOptions'.
if (![16, 32, 64, 128, 256, 512, 1024, 2048, 4096].includes(size)) {
throw new Error(`The size '${size}' is not supported!`);
}
// We don't support gif as a default format,
// because requesting .gif format when the original image is not a gif,
// would result in an error 415 Unsupported Media Type.
// If you want gif support, enable dynamicFormat, .gif will be used when is it available.
if (!["webp", "png", "jpg", "jpeg"].includes(defaultFormat)) {
throw new Error(`The format '${defaultFormat}' is not supported as a default format!`);
}
// We use raw API request to get the User object from Discord API,
// since the discord.js v12's one doens't support .banner property.
const user = await client.api.users(userId).get();
if (!user.banner) return null;
const query = `?size=${size}`;
const baseUrl = `https://cdn.discordapp.com/banners/${userId}/${user.banner}`;
// If dynamic format is enabled we perform a HTTP HEAD request,
// so we can use the content-type header to determine,
// if the image is a gif or not.
if (dynamicFormat) {
const { headers } = await axios.head(baseUrl);
if (headers && headers.hasOwnProperty("content-type")) {
return baseUrl + (headers["content-type"] == "image/gif" ? ".gif" : `.${defaultFormat}`) + query;
}
}
return baseUrl + `.${defaultFormat}` + query;
}
Example usage
Implementing simple !banner
command, that will show the message sender's banner.
client.on("message", async (message) => {
if (message.author.bot) return;
if (message.content == "!banner") {
const bannerUrl = await getUserBannerUrl(message.author.id, { size: 4096 });
if (bannerUrl) {
const embed = new Discord.MessageEmbed()
.setTitle(`${message.author.username}'s banner`)
.setDescription("Look at my banner, how cool is that?")
.setImage(bannerUrl);
message.channel.send(embed);
} else {
message.channel.send("You don't have money to buy Discord Nitro... How sad...");
}
}
});
According to a response to this GitHub issue and the official documentation, there is no current way to read the user bio and banner.
As Tyler stated, the feature is still in beta. Once added, you should be able to serialize the banner image hash on the user object, thus allowing bots to receive the field passively.
You can get the discord user banner with discord-banner npm package
Its so easy to use it and allow you to get it for now without Discord.js v13