Paraxo
Paraxo

Reputation: 25

Return Youtube video URL from keyword search with Javascript

Alright , so I'm making a bot in Discord for my server, and something I wanted to implement is a youtube command.
I've been searching all over and looking in the Youtube API and all I can find is their search for what seems like a browser

I'm using nodejs to run it off of my laptop, and my bot runs off of discord.js
I have a similar command that does a MAL and a Urban Dictionary search, but I've found nothing and have no idea how to do the same with youtube

I used to have a command for a python bot that was able to due this, and I've seen other Discord bots able to do it as well, so I know it's obviously possible

Basically what I'm saying is I need to be able to search for and return a youtube video URL (the first search result) from a string of search terms so the usage would look like

>>youtube Tunak Tunak Tun

Would return https://www.youtube.com/watch?v=vTIIMJ9tUc8 , which is the first search result for that keyword(s)

EDIT:
I've found the python command that would do this, but have nigh the skills nor the confidence to try to translate this to JavaScript

elif prefix and cmd=="youtube" and len(args) > 0:
        try:
            yword=args.replace(" ","_")
            ydata= urlreq.urlopen("http://gdata.youtube.com/feeds/api/videos?vq="+yword+"&racy=include&orderby=relevance&max-results=1")
            yread= str(ydata.read())
            if "<openSearch:totalResults>0</openSearch:totalResults>" in yread:
                room.message("I got nothin' for ya by the name of "+args)
            else:
                trash , yclean=yread.split("<media:player url='http://www.youtube.com/watch?v=",1)
                yclean , trash=yclean.split("&amp;",1)
                room.message("http://http://www.youtube.com/watch?v="+yclean,True)
        except:
            room.message("Somethin ain't right")

EDIT2 (Apologies for length) : Alright! I've found something that's gotten me a lot closer! https://www.npmjs.com/package/youtube-search
I've got a command in my bot now that goes something like this:

if (commandIs("yt" , message)){
  search(args.join(' ').substring(4), opts, function(err, results) {
    if(err) return console.log(err);
  message.channel.sendMessage(results);
  console.log(results);
  });
}

So now when I enter >>yt Tunak Tunak Tun I get

[ { id: 'vTIIMJ9tUc8',
link: 'https://www.youtube.com/watch?v=vTIIMJ9tUc8',
kind: 'youtube#video',
publishedAt: '2014-03-21T07:00:01.000Z',
channelId: 'UC3MLnJtqc_phABBriLRhtgQ',
channelTitle: 'SonyMusicIndiaVEVO',
title: 'Daler Mehndi - Tunak Tunak Tun Video',
description: 'Presenting \'Tunak Tunak Tun\' music video sung by the talented Daler Mehndi Song Name - Tunak Tunak Tun Album - Tunak Tunak Tun Singer - Daler Mehndi ...',
thumbnails: { default: [Object], medium: [Object], high: [Object] } } ]

in the console and [object Object] in the discord channel. https://i.sstatic.net/aeTFN.png

So the problem now is I have the link in my reach, but I can not get it to return JUST the link, and I've no idea how to pull it out of that mess.

Upvotes: 2

Views: 7036

Answers (2)

jonofan
jonofan

Reputation: 381

Okay, here's another approach that is working for me, using the google javascript API. Once again, the SO snippet doesn't run it, so I'll link you to the fiddle.

This method requires you to setup a google API key, then enable youtube API access.

I've removed my google API key from the fiddle, so you'll need to set that up. I can PM you mine if you want to test first though.

var apiKey = null //put your API key here

function search() {
	var searchTerm = $('#txtSearch').val()
 
  gapi.client.init({
    'apiKey': apiKey, 
    'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest']
  }).then(function() {
    return gapi.client.youtube.search.list({
      q: searchTerm,
      part: 'snippet'
    });
  }).then(function(response) {
  	var searchResult = response.result;
    $('#search-results').append(JSON.stringify(searchResult, null, 4))
  	console.log(searchResult.items[0])
    var firstVideo = searchResult.items[0]
    firstVideo.url = `https://youtube.com/watch?v=${firstVideo.id.videoId}`
    $('#first-video').text(firstVideo.url).attr('href', firstVideo.url)
    $('#first-video-title').text(firstVideo.snippet.title)
    $('#first-video-description').text(firstVideo.snippet.description)
  });

}


$('#btnSearch').on('click', function() {
  	$('#first-video-title').text("")
    if (!apiKey) {
      $('#first-video-title').text("You need to set an apiKey!")
      return;
    }
  	gapi.load('client', search)
  });
#search-results { white-space: pre; font-family: monospace; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src='https://apis.google.com/js/api.js'></script>

<div id="container">
  <input id="txtSearch" type="text" />
  <button id="btnSearch">
    Search!
  </button>
  <br />
  <p id='first-video-title'> </p>
  <p id='first-video-description'></p>
  <a target="_blank" id="first-video"></a>
  <div id='search-results'>
  
  </div>
</div>

Upvotes: 1

jonofan
jonofan

Reputation: 381

It sounds like your results object is a JSON string. This essentially means that it is a string representation of a javascript object. You can parse this into an object by using JSON.parse().

var objResults = JSON.parse(results);
console.log(objResults);
console.log(objResults.link);

EDIT

Failed to notice that your result is actually an array. You just need to access it like this: console.log(results[0].link). Shouldn't need to JSON.parse()

Upvotes: 3

Related Questions