0

I found this Javascript to check how to find out if a YouTube channel is live but I'm getting Blocked by CORS policy and I was wondering how to fix it? Can anyone help me? Source Check if Youtube channel is live at, without using API

var channelid = "UCnB-Fhp5FQfCZNfdAvm27Qw"; // REPLACE WITH YOUR CHANNEL ID

function onlive() {
  // DO SOMETHING IF CHANNEL IS LIVE STREAMING
}

/* REST OF THE CODE */

fetch('https://www.youtube.com/channel/' + channelid).then(function (response) {
    return response.text();
}).then(function (html) {
  if (html.includes("hqdefault_live.jpg")) {
onlive();
  }
}).catch(function (err) {
    console.warn('Something went wrong', err);
});

enter image description here

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
robotron
  • 111
  • 6

3 Answers3

5

Unfortunately, you can't make client requests to https://www.youtube.com and avoid CORS policy, because it is a built-in system on browser for request rejecting someones like you =)

But.

We can avoid CORS policy by making proxy server side request and pretending as client. After that, you can move all logic to your server.

  1. Create index.js file on your localhost with next content

   // Import the required http module
const http = require('http');
const https = require('https');
const url = require('url');

function youtubeRequest(channelId, headers) {
  return new Promise((resolve, reject) => {
    const options = {
      hostname: 'www.youtube.com',
      path: `/channel/${channelId}`,
      method: 'GET',
      headers: headers
    };

    let raw = ''

    const req = https.request(options, (res) => {
      res.on('data', (d) => {
        raw += d;
      });

      res.on('end', () => {
        resolve(raw);
      });
    });

    req.on('error', (error) => {
      console.log(error);
      reject(error);
    });


    req.end();
  });
}

// Define the request handler function
const requestHandler = async (req, res) => {
  const parsedUrl = url.parse(req.url, true);


  // Check if the request method is GET and the path is '/call'
  if (req.method === 'GET' && parsedUrl.pathname === '/isLive') {
    const channelId = parsedUrl.query.channelId;

    if (!channelId) {
      res.writeHead(404, { 'Content-Type': 'application/json' });
      const jsonResponse = { message: 'Channel id is invalid' };
      res.end(JSON.stringify(jsonResponse));

      return;
    }

    try {
      const HTML = await youtubeRequest(channelId, {
        "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        "accept-language": "en,ru-RU;q=0.9,ru;q=0.8,en-US;q=0.7",
        "cache-control": "max-age=0",
      });

      let isLive = false;

      if (HTML.includes("hqdefault_live.jpg")) {
        isLive = true;
      }

      res.writeHead(200, {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept",
        'Content-Type': 'application/json'
      });

      // Send a JSON response
      const jsonResponse = {
        isLive,
        message: isLive ? 'Your channel is live' : 'Your channel disabled'
      };
      res.end(JSON.stringify(jsonResponse));
    } catch (e) {
      console.log(e);
      res.writeHead(500, { 'Content-Type': 'application/json' });

      // Send a JSON response
      const jsonResponse = { message: 'Something went wrong, check your server logs' };
      res.end(JSON.stringify(jsonResponse));
    }
  } else {
    // Send a 404 response for other routes
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('Not found');
  }
};

// Create the server with the request handler
const server = http.createServer(requestHandler);

// Start the server listening on a specified port
const port = 3000;
server.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});
  1. Start it with bash command node index.js. If you havent install NodeJs you can do with official webpage.

After that, your server should be running at http://localhost:3000

  1. Now, you can make client request for http://localhost:3000/isLive?channelId=UCnB-Fhp5FQfCZNfdAvm27Qw

So, use below client javascript for calling your web server

<script>
  var channelid = "UCnB-Fhp5FQfCZNfdAvm27Qw"; // REPLACE WITH YOUR CHANNEL ID
  fetch('http://localhost:3000/isLive?channelId=' + channelid).then(function (response) {
    return response.text();
  }).then(function (response) {
    console.log(response);
  }).catch(function (err) {
    console.warn('Something went wrong', err);
  });
</script>

Now, in browser console, you can see result Screenshot of page

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Loosefer
  • 151
  • 1
  • 3
0

To follow official YouTube guidelines, you should first retrieve recent videos of the given YouTube channel thanks to the uploads playlist using YouTube Data API v3 PlaylistItems: list endpoint, then use its Videos: list endpoint with part=liveStreamingDetails. Only a currently broadcasted livestream will have an actualStartTime entry without having an actualEndTime one.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
0

To check, whether a channel is live (without Youtube API), do the following:

  1. Fetch the content of https://youtube.com/@channel/streams page

  2. Check, does the page contains This channel has no videos. message

You won't be able to send requests from the browser to 3rd party web pages without permission from their owners. As Youtube is not going to change its CORS policy, you must stick with other ways.

  1. Send a request to the domain with a controllable CORS policy, like your own server. It may be a program running on localhost or a serverless lambda function (AWS provides free tier).
  2. Run the browser in a special ignore CORS mode.
  3. Intercept requests and modify CORS policy on the fly. Can be done by installing this extension.
xamgore
  • 1,723
  • 1
  • 15
  • 30