Check if the image exists to .setImage In Embed - discord

First of all sorry for the bad English
I'm trying to do a "tweet" system. I check if the link is true and has an image but if you put something like https://askhdkjahs.png the program thinks is an image and put in the embed giving an error
I need handle the error and put a default image or reply saying 'the image give a error'
thats my code
if (comando === `${prefix}atwt`) {
msg.delete({ timeout: 100 });
if (!argumento[0]) {
msg.reply('pon algo').then(msg => {
msg.delete({ timeout: 10000 });
}).catch(console.error);
}
else if(argumento !== null && argumento !== '') {
const TweetAnon = new Discord.MessageEmbed()
.setAuthor('Anonimo!', 'https://i.imgur.com/wSTFkRM.png')
.setColor('BLUE')
.setTimestamp();
const url = argumento[0].toString();
if (url.match(/^https.*\.(png|jpeg|jpg|gif|bmp)$/i)) {
TweetAnon.setImage(argumento[0]);
TweetAnon.setDescription(`**${argumento.slice(1).join(' ')}**`);
}
else{
TweetAnon.setDescription(`**${argumento.join(' ')}**`);
}
const msgEmbed = await msg.channel.send(TweetAnon).catch(TweetAnon.setImage('https://i.imgur.com/wSTFkRM.png'));
await msgEmbed.react('👍');
await msgEmbed.react('👎');
await msgEmbed.react('🔄');
}
}
I see something like that and I tried but doesn't work
if (comando === `${prefix}atwt`) {
const url = argumento[0].toString();
const TweetAnon = new Discord.MessageEmbed()
.setAuthor('Anonimo!', 'https://cdn.discordapp.com/attachments/769965806850670634/854834517709422602/anon.png')
.setColor('BLUE')
.setTimestamp();
msg.delete({ timeout: 100 });
try {
if (!url.match(/^https.*\.(png|jpeg|jpg|gif|bmp)$/i)) {
throw new Error('Invalid URL');
}
TweetAnon.setImage(argumento[0]);
TweetAnon.setDescription(`**${argumento.slice(1).join(' ')}**`);
}
catch (error) {
TweetAnon.setImage('https://i.imgur.com/wSTFkRM.png');
}
// else
// TweetAnon.setDescription(`**${argumento.join(' ')}**`);
// }
const msgEmbed = await msg.channel.send(TweetAnon).catch(err => console.log(err));
await msgEmbed.react('👍');
await msgEmbed.react('👎');
await msgEmbed.react('🔄');
}

You could check if the image exists like this:
function imageExists(image_url){
var http = new XMLHttpRequest();
http.open('HEAD', image_url, false);
http.send();
return http.status != 404;
}
Usage:
if(imageExists(argumento[0])){
TweetAnon.setImage(argumento[0]);
}

Related

Sharpjs throws error: Input file is missing

I have a discord bot
Code:
const Discord = require('discord.js');
const sharp = require('sharp');
const client = new Discord.Client({ intents: ["Guilds", "GuildMessages", "MessageContent"] });
client.on("ready", () => {
console.log(`Logged in as ${client.user.tag}`)
})
client.on('messageCreate', async message => {
if (!message.content.startsWith('!rights') || message.author.bot) return;
console.log("invoked");
// get image link or image attachment
let imageUrl = '';
if (message.attachments.size > 0) {
imageUrl = message.attachments.first().url;
} else {
return message.reply('Please provide an image link or attach an image to the message.');
}
// open image using sharp
let image;
try {
image = await sharp(imageUrl);
} catch (error) {
return message.reply('Invalid image URL or file type.');
}
// add text to image
const text = 'Hello World';
image = await image.composite([{
input: Buffer.from(text),
gravity: 'center'
}])
// send edited image in message
const buffer = await image.toBuffer();
console.log("Sending");
message.channel.send(new Discord.MessageAttachment(buffer));
});
the error says that the image I passed which is a discord image link is missing
I tried different images but the issue is still the same

trying to update user profile but get error with image I can't update it

I'm trying to update user profile using react native expo I can only update all properties except image is giving me this Error :
[Unhandled promise rejection: FirebaseError: Function DocumentReference.update() called with invalid data. Unsupported field value: undefined (found in field userImg in document users ? please help
const [image, setImage] = useState(null);
const [uploading,setUploading] = useState(false)
const [ userData, setUserData] = useState(null);
useEffect(()=>{
const getUserData = async ()=>{
db.collection("users")
.doc(auth.currentUser?.uid)
.get()
.then(snap => {
setUserData(snap.data());
});
}
getUserData();
},[])
const updateProfile = async()=>{
let imgUrl = await uploadImage();
if(imgUrl == null && userData.userImg){
imgUrl = userData.userImg
}
db.collection("users")
.doc(auth.currentUser.uid)
.update({
name: userData.name,
userName: userData.userName,
email: userData.email,
phone: userData.phone,
address: userData.address,
userImg:userData.mgUrl
})
}
I can upload the image successfully but I can't fetch it from storage to fire store
const uploadImage = async ()=>{
if(image == null){
return null;
}
const blob = await new Promise((resolve, reject)=>{
const xhr = new XMLHttpRequest();
xhr.onload = function (){
resolve(xhr.response)
};
xhr.onerror = function (){
reject( new TypeError("Network request failed"))
};
xhr.responseType = "blob"
xhr.open("GET",image,true)
xhr.send(null)
});
const ref = firebase.storage().ref().child("images/" + new Date().toISOString())
const snapshot = ref.put(blob)
snapshot.on(
firebase.storage.TaskEvent.STATE_CHANGED,
()=>{
setUploading(true)
},
(error)=>{
setUploading(false)
console.log(error)
blob.close();
return;
},
()=>{
snapshot.snapshot.ref.getDownloadURL().then((url)=>{
setUploading(false);
// Alert.alert('Profile Updated', 'You profile Updated Successfully..!')
console.log('donwload:', url)
setUserData(url)
blob.close()
return null
})
}
)
}
}
so please help me out between I'm using React Native Expo and thank you so much
To start off, the error [Unhandled promise rejection: FirebaseError: Function DocumentReference.update() called with invalid data. Unsupported field value: undefined means that one or more fields has a null value but firebase doesn't allow you to store that.
In your uploadImage function you're able to upload your image fine when the image actually does exist but in cases that it doesn't you're returning null which is where the problem is. Ideally, you can return an empty string which is safe then in cases where you read the image you can just check if the string is empty or not.
Fix
Step 1
Change this
if(image == null){
return null;
}
To this
if(image == null){
return "";
}
Step 2
After you get the download URL your setUserData is replacing all the fields with the URL so consider changing it to
`
setUserData({...userData, imgUrl : url})
Step 3
Also realize that in your update() there is a typo for imgUrl change from
userImg:userData.mgUrl to userImg:userData.imgUrl to properly set the image using the step for line
Hope that fixes It :)
`
Check if below code helps you to upload a Video or Image using firebase.
const uploadImageToFirestore = async (res, type) => {
const uri = res.assets[0].uri;
const filename = uri.substring(uri.lastIndexOf('/') + 1);
const uploadUri = Platform.OS === 'ios' ? uri.replace('file://', '') : uri;
const storage = getStorage(app);
const fileRef = ref(storage, filename);
const img = await fetch(uploadUri);
const bytes = await img.blob();
let metadata;
if (type == 'video') {
if (filename.includes("mov") || filename.includes("MOV")) {
metadata = {
contentType: 'video/quicktime'
}
} else {
metadata = {
contentType: 'video/mp4',
};
}
} else {
metadata = {
contentType: 'image/jpeg',
};
}
uploadBytes(fileRef, bytes, metadata).then(async (uploadTask) => {
console.log('task', uploadTask)
getDownloadURL(uploadTask.ref).then((url) => {
if (type == 'video') {
setVideoData(url);
} else {
setImageData(url);
}
});
}).catch((err) => {
alert('Error while uploading Image!')
console.log(err);
});
}

RangeError [MESSAGE_CONTENT_TYPE]: Message content must be a non-empty string

client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
const { commandName } = interaction;
if (commandName === 'denick') {
await interaction.deferReply();
const data = fetch('http://api.antisniper.net/account/api_disabled/counts')
.then(response => response.json());
interaction.editReply({ content: data });
}
});
ERROR:
if (typeof data !== 'string') throw new error(errorMessage);
RangeError [MESSAGE_CONTENT_TYPE]: Message content must be a non-empty string.
Great question, this is less of a discord.js question, rather a how to format a .then.
You can either carry on in the function after .then or use an async/await.
First method:
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
const { commandName } = interaction;
if (commandName === 'denick') {
await interaction.deferReply();
const data = fetch('http://api.antisniper.net/account/api_disabled/counts')
.then(async response => {
var jsonResponse = await response.json();
var jsonToString = JSON.stringify(jsonResponse)
interaction.editReply({ content: data });
});
}
});
As you can see above, I've shifted everything after the .then function. I've also done an await response.json() and a stringify. Missing either of those will send an error(either the error you got or [Object object]).
The second method:
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
const { commandName } = interaction;
if (commandName === 'denick') {
await interaction.deferReply();
const data = await fetch('http://api.antisniper.net/account/api_disabled/counts');
var jsonResponse = await data.json();
var jsonToString = JSON.stringify(jsonResponse)
interaction.editReply({ content: data });
}
});
I've removed the .then function and replaced it with an await. The rest is the same.
Either methods should be able to work, if it helped, please remember to mark the question as correct, if there's any problems, please comment!
Edit:
To only show the winstreak_data_hidden data, simply use the returned jsonResponse as a object.
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
const { commandName } = interaction;
if (commandName === 'denick') {
await interaction.deferReply();
const data = await fetch('http://api.antisniper.net/account/api_disabled/counts');
var jsonResponse = await data.json();
var hiddenWinStreakData = jsonResponse.winstreak_data_hidden;
if(hiddenWinStreakData){
interaction.editReply({ content: hiddenWinStreakData });
}
}
});
I've done a simple if statement to avoid discord throwing errors, you can also do an else statement after to say that the user doesn't have hidden win streak data. Hope this helped!

Discord.js v13, #discordjs/voice Play Music Command

This is my code,
The command executes perfectly, The bot joins the voice channel and also sends the name of the song its about to play, but it doesnt play the song in the voice channel.
This is my first time ever asking a question on stackoverflow so dont mind the format and stuff. But I really need help here.
Discord v13 and latest node module.
const ytsearch = require('yt-search');
const Discord = require('discord.js')
const {
joinVoiceChannel,
createAudioPlayer,
createAudioResource,
NoSubscriberBehavior
} = require('#discordjs/voice');
module.exports = {
name: "play",
description: "test command",
async run(client, message, args) {
const voiceChannel = message.member.voice.channel;
if (!voiceChannel) return message.channel.send('Please connect to a voice channel!');
if (!args.length) return message.channel.send('Please Provide Something To Play!')
const connection = await joinVoiceChannel({
channelId: message.member.voice.channel.id,
guildId: message.guild.id,
adapterCreator: message.guild.voiceAdapterCreator
});
const videoFinder = async (query) => {
const videoResult = await ytsearch(query);
return (videoResult.videos.length > 1) ? videoResult.videos[0] : null;
}
const video = await videoFinder(args.join(' '));
if (video) {
const stream = ytdl(video.url, { filter: 'audioonly' });
const player = createAudioPlayer();
const resource = createAudioResource(stream)
await player.play(resource);
connection.subscribe(player);
await message.reply(`:thumbsup: Now Playing ***${video.title}***`)
} else {
message.channel.send('No video results found');
}
}
}```
I would suggest you look at the music bot example at #discordjs/voice.
They do a good job of how to extract the stream from ytdl.
I'm currently still learning how this all works but the part that you will want to look at is in the createAudioResource function.
public createAudioResource(): Promise<AudioResource<Track>> {
return new Promise((resolve, reject) => {
const process = ytdl(
this.url,
{
o: '-',
q: '',
f: 'bestaudio[ext=webm+acodec=opus+asr=48000]/bestaudio',
r: '100K',
},
{ stdio: ['ignore', 'pipe', 'ignore'] },
);
if (!process.stdout) {
reject(new Error('No stdout'));
return;
}
const stream = process.stdout;
const onError = (error: Error) => {
if (!process.killed) process.kill();
stream.resume();
reject(error);
};
process
.once('spawn', () => {
demuxProbe(stream)
.then((probe) => resolve(createAudioResource(probe.stream, { metadata: this, inputType: probe.type })))
.catch(onError);
})
.catch(onError);
});
}

Getting "#ReferenceError: connection is not defined"

I've been using the code from discord.js guide and keep getting this error when I try to make it join
Here's my code:
const Discord = require('discord.js');
const client = new Discord.Client();
const PREFIX = '%';
const request = require('request');
const cheerio = require('cheerio');
var servers = {};
client.on('ready', () => {
console.log('This client is online!');
})
client.on('message', message => {
let args = message.content.substring(PREFIX.length).split(" ");
switch (args[0]) {
case 'image':
var imreq = (args[1])
image(message, imreq);
break;
case 'bruh':
client.on('message', async message => {
// Join the same voice channel of the author of the message
if (message.member.voice.channel) {
const connection = await message.member.voice.channel.join();
}
});
const dispatcher = connection.play('C:\Users\jayja\Downloads\Bruh Sound Effect 2.mp3 ');
dispatcher.on('start', () => {
console.log('audio.mp3 is now playing!');
});
dispatcher.on('finish', () => {
console.log('audio.mp3 has finished playing!');
});
// Always remember to handle errors appropriately!
dispatcher.on('error', console.error);
break;
}
});
function image(message, imreq) {
var options = {
url: "http://results.dogpile.com/serp?qc=images&q=" + imreq,
method: "GET",
headers: {
"Accept": "text/html",
"User-Agent": "Chrome"
}
};
request(options, function(error, response, responseBody) {
if (error) {
return;
}
$ = cheerio.load(responseBody);
var links = $(".image a.link");
var urls = new Array(links.length).fill(0).map((v, i) =>
links.eq(i).attr("href"));
console.log(urls);
if (!urls.length) {
return;
}
// Send result
message.channel.send(urls[Math.floor(Math.random() * urls.length)]);
});
}
client.login(token)
Heres a screenshot of the terminal:
Screenshot
So like I guessed, you don't need to listen to the message event of the client. You already have the message object via the initial command trigger.
if (message.member.voice.channel) {
const connection = await message.member.voice.channel.join();
const dispatcher = connection.play('C:\Users\jayja\Downloads\Bruh Sound Effect 2.mp3 ');
dispatcher.on('start', () => {
console.log('audio.mp3 is now playing!');
});
dispatcher.on('finish', () => {
console.log('audio.mp3 has finished playing!');
});
// Always remember to handle errors appropriately!
dispatcher.on('error', console.error);
}
This should be all you need. You also might find this guide interesting to read.

Resources