Youtube API - Subscribing to Push Notifications

Poyu picture Poyu · Apr 13, 2015 · Viewed 13.9k times · Source

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.

Answer

salexch picture salexch · Jul 14, 2016
  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
        );
    }