Search code examples
python-3.xyoutubeyoutube-apiyoutube-data-apiwebhooks

YouTube Push Notifications via Webhooks & PubSubHubbub (Python3) returning 200 on subscription, but nothing on video upload


I've added a Webhooks listener to a Discord bot, and I'm trying to use that to post notifications to a text channel when a new video is uploaded (trying to eliminate my reliance on MEE6). When I subscribe to notifications at https://pubsubhubbub.appspot.com/subscribe, I get a 200 response, and my server's console prints

66.249.84.174 - - [27/Apr/2021 05:23:51] "GET /webhooks?hub.topic=https://www.youtube.com/xml/feeds/videos.xml%3Fchannel_id%<THE_CHANNEL_ID_I_WANT_NOTIFICATIONS_FOR>&hub.challenge=<A_BUNCH_OF_NUMBERS>&hub.mode=subscribe&hub.lease_seconds=432000 HTTP/1.1" 200 -

However, when a video gets uploaded nothing happens.

I've tried manually triggering a POST request from PostMan to the same endpoint (with the XML body found here https://developers.google.com/youtube/v3/guides/push_notifications as the raw->xml body text), and that seems to hit my console and return a 200, but I'm at a loss as to why I'm not getting any indication when an upload goes up. Code below:

from flask import Flask, Response, request

app = Flask(__name__)

@app.route('/webhooks', methods=['POST'])
def respond():
    print(request.json);
    return Response(status=200)

@app.route('/webhooks')
def index():
    print(('request', request))
    print('args:', request.args)  # display text in console
    print('form:', request.form)
    print('data:', request.data)
    print('json:', request.json)
    print('files:', request.files)
    
    return request.args.get('data', 'none')  # send text to web browser

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=<MY_PORT>)

I'm hosting on PebbleHost, which is why the host is set to 0.0.0.0; there's a separate IP I'm connecting to for the subscriptions, mapped to a dedicated port. I'm quite new to Webhooks, and this is my first time interacting with the YouTube API, so I'm certain there's something really obvious I'm overlooking.


Solution

  • You have to return hub.challenge for confirmation on subscription.

    A Working Example that I made earlier.

    from flask import Flask, request
    import xmltodict
    
    app = Flask(__name__)
    
    
    @app.route("/callback", methods=['POST', 'GET'])
    def callback():
        if request.method == 'POST':
            data = xmltodict.parse(request.data)
            print(data)
            return request.data
        else:
            return request.args.get('hub.challenge')
    
    
    
    app.run('0.0.0.0')