Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Youtube API - Subscribing to Push Notifications

My final goal is to set up a Webhook whenever a YouTube user uploads a video. After some research I got to this article.

But when I get to the part https://www.youtube.com/xml/feeds/videos.xml?channel_id=CHANNEL_ID, I got Restricted topic error when trying the subscribe to the Google/SuperFeedr hubs. I also got my callback URL working.

The topic I want to subscribe to is this: https://www.youtube.com/xml/feeds/videos.xml?channel_id=UC7T8roVtC_3afWKTOGtLlBA

Which shows nothing upon visiting via a browser.

Am I doing something wrong? I've been struggling for a few hours now, any help is appreciated. Thanks!

UPDATE: I found this, but those feeds doesn't have the rel=”hub” attribute, so probably useless if I want to subscribe it to hub.

like image 510
Poyu Avatar asked Apr 13 '15 17:04

Poyu


People also ask

How do I subscribe to push notifications?

When visitors land on the website they are prompted with an opt-in dialog box asking them to 'Allow' push notifications from a website or 'Block'. Visitors that click 'Allow' are directly added to the website subscriber base.

Do YouTube get notified when you subscribe?

No if your subscriptions are private, Notifications are not send on the that channel u subscribed. Go on youtube > account > your channel > edit channel. Under privacy “keep all my subscriptions private” check whether it is on or off. Is there are a way to hide the number of subscribers I have on YouTube?


3 Answers

  1. you need to send request to subscribe a channel
  2. a callback that varifies the subscription request and get actual data on update

subscribe function:

subscribe.php may look like:

<?php

function subscribeYoutubeChannel($channel_id = null, $subscribe = true) {
    $subscribe_url = 'https://pubsubhubbub.appspot.com/subscribe';
    $topic_url = 'https://www.youtube.com/xml/feeds/videos.xml?channel_id={CHANNEL_ID}';
    $callback_url = 'http://' . $_SERVER['SERVER_NAME'] . str_replace(basename($_SERVER['REQUEST_URI']), '', $_SERVER['REQUEST_URI']) . 'youtube_subscribe_callback.php';

    $data = array(
        'hub.mode' => $subscribe ? 'subscribe' : 'unsubscribe',
        'hub.callback' => $callback_url,
        'hub.lease_seconds'=>60*60*24*365,
        'hub.topic'=> str_replace(array(
            '{CHANNEL_ID}'
        ), array(
            $channel_id
        ), $topic_url)
    );

    $opts = array('http' =>
        array(
            'method'  => 'POST',
            'header'  => 'Content-type: application/x-www-form-urlencoded',
            'content' => http_build_query($data)
        )
    );

    $context  = stream_context_create($opts);

    @file_get_contents($subscribe_url, false, $context);

    return preg_match('200', $http_response_header[0]) === 1;
}

after the request is sent, the pusub service will call youtube_subscribe_callback.php to verify the subscription it will use the GET method and it expects to receive an answer which is "hub_challenge". after that if you upload a video to your test channel youtube_subscribe_callback.php will receive POST request with data.

so youtube_subscribe_callback.php (defined in subscribeYoutubeChannel function) may look like:

 <?php
    if (isset($_GET['hub_challenge'])) {
        echo $_REQUEST['hub_challenge'];
    } else {
    
        $video = parseYoutubeUpdate(file_get_contents('php://input'));
        
    }
    
    function parseYoutubeUpdate($data) {
        $xml = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
        $video_id = substr((string)$xml->entry->id, 9);
        $channel_id = substr((string)$xml->entry->author->uri, 32);
        $published = (string)$xml->entry->published;
    
        return array(
            'video_id'=>$video_id,
            'channel_id'=>$channel_id,
            'published'=>$published
        );
    }
like image 144
salexch Avatar answered Nov 01 '22 15:11

salexch


I wasn't able to subscribe channel by id, but was able to do it by username:

https://www.youtube.com/feeds/videos.xml?user=username

So, you go to this page:

https://pubsubhubbub.appspot.com/subscribe

Insert your callback URL, RSS feed from youtube with username, and mode "subscribe".

Don't forget to reply from your callback URL, so it can confirm subscription, in PHP just print:

echo $_REQUEST["hub_challenge"];

More details here and here.

like image 38
dikirill Avatar answered Nov 01 '22 15:11

dikirill


The process is usually two steps, first you go to the subscribe page, input your callback server url, topic url (which is basically the feed url for the ytb channel you want to listen to, the other fields are optional), the pub server will verify your subscription with a GET request to your callback server, in go it can look like this:

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    challenge := r.URL.Query().Get("hub.challenge")
    if challenge != "" {
        fmt.Fprintf(w, challenge)
    }
})

Then on every new video (or title, desc of an old video is updated), the pub will submit a POST request to your server with an xml in the body looking similar to this:

<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns:yt="http://www.youtube.com/xml/schemas/2015" xmlns="http://www.w3.org/2005/Atom">
  <link rel="hub" href="https://pubsubhubbub.appspot.com" />
  <link rel="self" href="https://www.youtube.com/xml/feeds/videos.xml?channel_id=UCtEorrVfo4GQsN82HsrnKyk" />
  <title>YouTube video feed</title>
  <updated>2018-12-12T06:02:55.950497732+00:00</updated>
  <entry>
    <id>yt:video:_em_FFNUcvs</id>
    <yt:videoId>_em_FFNUcvs</yt:videoId>
    <yt:channelId>UCtEorrVfo4GQsN82HsrnKyk</yt:channelId>
    <title>December 12, 20</title>
    <link rel="alternate" href="https://www.youtube.com/watch?v=_em_FFNUcvs" />
    <author>
      <name>Ak Ram</name>
      <uri>https://www.youtube.com/channel/UCtEorrVfo4GQsN82HsrnKyk</uri>
    </author>
    <published>2018-12-12T05:57:07+00:00</published>
    <updated>2018-12-12T06:02:55.950497732+00:00</updated>
  </entry>
</feed>
like image 42
Akram Saouri Avatar answered Nov 01 '22 15:11

Akram Saouri