twlite / youtube-sr

A dead-simple youtube metadata scraper
https://npmjs.com/package/youtube-sr
MIT License
113 stars 16 forks source link

Multiple errors #13

Closed PasinduDushan closed 3 years ago

PasinduDushan commented 3 years ago

I've been using youtube-sr package for 2 months now and today I've got an error from my bot saying that TypeError: Cannot read property 'title' of null. When I tried again in 20-30 minutes it worked by showing all the song name and all other things but It hasn't played the song, It threw a 429 error. MinigetError: input stream: Status code: 429. It's too many requests so I waited for 20-30 minutes again and tried. When I try again it again showed an error. But this time it showed TypeError: Cannot read property 'searchOne' of undefined. This is the code I used in my bot for playing music.

const { play } = require("../include/play");
const { Client, Collection, MessageEmbed } = require("discord.js");
const { attentionembed } = require("../util/attentionembed");
const ytsr = require("youtube-sr")
const PREFIX = require('../config.json')

module.exports = {
  name: "play",
  aliases: ["p"],
  description: "Plays song from YouTube/Stream",
  cooldown: 2,
  edesc: `Type this command to play some music.\nUsage: play <title | url>`,

async execute(message, args, client) {

    //If not in a guild return
    if (!message.guild) return;
    //define channel
    const { channel } = message.member.voice;
    //get serverqueue
    const serverQueue = message.client.queue.get(message.guild.id);
    //If not in a channel return error
    if (!channel) return attentionembed(message, "Please join a Voice Channel first");
    //If not in the same channel return error
    if (serverQueue && channel !== message.guild.me.voice.channel)
      return attentionembed(message, `You must be in the same Voice Channel as me`);
    //If no args return
    if (!args.length)
      return attentionembed(message, `Usage: play <YouTube URL | Video Name | Soundcloud URL>`);
    //react with approve emoji
    message.react("βœ…").catch(console.error);
    //get permissions and send error if bot doesnt have enough
    const permissions = channel.permissionsFor(message.client.user);
    if (!permissions.has("CONNECT"))
      return attentionembed(message, "I need permissions to join your channel!");
    if (!permissions.has("SPEAK"))
      return attentionembed(message, "I need permissions to speak in your channel");

    //define some url patterns
    const search = args.join(" ");
    const videoPattern = /^(https?:\/\/)?(www\.)?(m\.)?(youtube\.com|youtu\.?be)\/.+$/gi;
    const urlValid = videoPattern.test(args[0]);

    //define Queue Construct
    const queueConstruct = {
      textChannel: message.channel,
      channel,
      connection: null,
      songs: [],
      loop: false,
      volume: 69,
      filters: [],
      realseek: 0,
      playing: true
    };
    //get song infos to null
    let songInfo = null;
    let song = null;
    //try catch for errors
    try {
      //If something is playing
      if (serverQueue) {
        //if its an url
        if (urlValid) { //send searching link
          message.channel.send(new MessageEmbed().setColor("#c219d8")
            .setDescription(`**πŸ’’ Searching πŸ” [\`LINK\`](${args.join(" ")})**`))
        //if not
        }
        else { //send searching TITLE
          message.channel.send(new MessageEmbed().setColor("#c219d8")
            .setDescription(`**πŸ’’ Searching πŸ” \`${args.join(" ")}\`**`))
        }
      } else {
        //If nothing is playing join the channel
        queueConstruct.connection = await channel.join();
        //send join message
        message.channel.send(new MessageEmbed().setColor("#c219d8")
          .setDescription(`**πŸ‘ Joined \`${channel.name}\` πŸ“„ bound \`#${message.channel.name}\`**`)
          .setFooter(`By: ${message.author.username}#${message.author.discriminator}`))
        //if its an url
        if (urlValid) { //send searching link
          message.channel.send(new MessageEmbed().setColor("#c219d8")
            .setDescription(`**πŸ’’ Searching πŸ” [\`LINK\`](${args.join(" ")})**`))
          //if not 
        }
        else { //send searching TITLE
          message.channel.send(new MessageEmbed().setColor("#c219d8")
            .setDescription(`**πŸ’’ Searching πŸ” \`${args.join(" ")}\`**`))
        }
        //Set selfdeaf and serverdeaf true
        queueConstruct.connection.voice.setSelfDeaf(true);
        queueConstruct.connection.voice.setDeaf(true);
      }
    }
    catch {
    }
    //if its a valdi youtube link
    if (urlValid) {
      try {
        songInfo = await ytsr.searchOne(search) ;
        song = {
          title: songInfo.title,
          url: songInfo.url,
          thumbnail: songInfo.thumbnail,
          duration: songInfo.durationFormatted,
       };
      } catch (error) {
        if (error.statusCode === 403) return attentionembed(message, "Max. uses of api Key, please refresh!");
        console.error(error);
        return attentionembed(message, error.message);
      }
    } 
    //else try to find the song via ytsr 
    else {
      try {
       //get the result 
        songInfo = await ytsr.searchOne(search) ;
        song = {
          title: songInfo.title,
          url: songInfo.url,
          thumbnail: songInfo.thumbnail,
          duration: songInfo.durationFormatted,
       };
      } catch (error) {
        console.error(error);
        return attentionembed(message, error);        
      }                                                               
    }
    //get the thumbnail
    let thumb = "https://cdn.discordapp.com/attachments/748095614017077318/769672148524335114/unknown.png"
    if (song.thumbnail === undefined) thumb = "https://cdn.discordapp.com/attachments/748095614017077318/769672148524335114/unknown.png";
    else thumb = song.thumbnail.url;
    //if there is a server queue send that message!
    if (serverQueue) {
      //Calculate the estimated Time
      let estimatedtime = Number(0);
      for (let i = 0; i < serverQueue.songs.length; i++) {
        let minutes = serverQueue.songs[i].duration.split(":")[0];   
        let seconds = serverQueue.songs[i].duration.split(":")[1];    
        estimatedtime += (Number(minutes)*60+Number(seconds));   
      }
      if (estimatedtime > 60) {
        estimatedtime = Math.round(estimatedtime / 60 * 100) / 100;
        estimatedtime = estimatedtime + " Minutes"
      }
      else if (estimatedtime > 60) {
        estimatedtime = Math.round(estimatedtime / 60 * 100) / 100;
        estimatedtime = estimatedtime + " Hours"
      }
      else {
        estimatedtime = estimatedtime + " Seconds"
      }
      //Push the ServerQueue
      serverQueue.songs.push(song);
      //the new song embed
      const newsong = new MessageEmbed()
        .setTitle("βœ… " + song.title)
        .setColor("#c219d8")
        .setThumbnail(thumb)
        .setURL(song.url)
        .setDescription(`\`\`\`Has been added to the Queue.\`\`\``)
        .addField("Estimated time until playing:", `\`${estimatedtime}\``, true)
        .addField("Position in queue", `**\`${serverQueue.songs.length - 1}\`**`, true)
        .setFooter(`Requested by: ${message.author.username}#${message.author.discriminator}`, message.member.user.displayAvatarURL({ dynamic: true }))
      //send the Embed into the Queue Channel
        return serverQueue.textChannel
        .send(newsong)
        .catch(console.error);

    }
    //push the song list by 1 to add it to the queu
    queueConstruct.songs.push(song);
    //set the queue
    message.client.queue.set(message.guild.id, queueConstruct);
    //playing with catching errors
    try {

      //try to play the song
      play(queueConstruct.songs[0], message, client);
    } catch (error) {
      //if an error comes log
      console.error(error);
      //delete the Queue
      message.client.queue.delete(message.guild.id);
      //leave the channel
      await channel.leave();
      //sent an error message
      return attentionembed(message, `Could not join the channel: ${error}`);
    }
  }
};

Any help will be highly appreciated!

twlite commented 3 years ago

Hello, this lib never throws error with 429 status code. It is from ytdl-core. Also, for TypeError: Cannot read property 'title' of null, the search function returned null. And for TypeError: Cannot read property 'searchOne' of undefined, you need to import youtube-sr like this:

const ytsr = require("youtube-sr").default
PasinduDushan commented 3 years ago

I added it but it still shows that error

twlite commented 3 years ago

Which error?

PasinduDushan commented 3 years ago

I uninstalled and installed the youtube-sr package again and I got this SyntaxError: Unexpected token '.'. Also, my node version is 14

twlite commented 3 years ago

You sure? Try re-starting again. It wont throw errors like SyntaxError: Unexpected token '.' for node.js v14

PasinduDushan commented 3 years ago

This is my full error.

url: item.channel.thumbnails?.default.url,
                                                                 ^

SyntaxError: Unexpected token '.'
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/home/runner/Groover-Data-Access/Music/filter.js:4:14)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/home/runner/Groover-Data-Access/bot.js:80:19)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
(node:13850) UnhandledPromiseRejectionWarning: Error [SHARDING_READY_DIED]: Shard 0's process exited before its Client became ready.
    at Shard.onDeath (/home/runner/Groover-Data-Access/node_modules/discord.js/src/sharding/Shard.js:158:16)
    at Object.onceWrapper (events.js:421:26)
    at Shard.emit (events.js:314:20)
    at Shard.EventEmitter.emit (domain.js:483:12)
    at Shard._handleExit (/home/runner/Groover-Data-Access/node_modules/discord.js/src/sharding/Shard.js:384:10)
    at ChildProcess.emit (events.js:314:20)
    at ChildProcess.EventEmitter.emit (domain.js:483:12)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:276:12)
(node:13850) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:13850) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

And my node version is - v12.21.0 I'm using repl.it to host the bot

twlite commented 3 years ago

Yeah, you just said your node version is v12.21.0. You need node.js v14 or higher to use this library.

PasinduDushan commented 3 years ago

I think repl can't be upgraded to a new node version. Are there any versions of youtube-sr to support node version 12.x

twlite commented 3 years ago

Try v3.x

PasinduDushan commented 3 years ago

ok

PasinduDushan commented 3 years ago

I tried version 3.0.0 and it says this error. TypeError: ytsr.searchOne is not a function

twlite commented 3 years ago

remove require("youtube-sr").default and use require("youtube-sr") only

PasinduDushan commented 3 years ago

It's removed alredy

PasinduDushan commented 3 years ago

It's not working

twlite commented 3 years ago

Going too back might not work. Try using v3.0.4 for now and you need to import it like this require("youtube-sr").default for this version. But it should work for node.js v12. https://www.npmjs.com/package/youtube-sr/v/3.0.4

PasinduDushan commented 3 years ago

Yeah. It's showing all the things. It's throwing 429 but I don't think that it's a problem in youtube-sr

twlite commented 3 years ago

Already told ya 429 error comes from ytdl-core. And, I think this issue is resolved

PasinduDushan commented 3 years ago

I think changing the package haven't worked. Because it's still showing cannot read property 'title' of null

twlite commented 3 years ago

You know searchOne can return null if it can't parse data right? image

PasinduDushan commented 3 years ago

nvm. I got it. I tried on my local machine and it worked by upgrading node version