How to call a function when a YouTube user uploads a video?

此生再无相见时 提交于 2019-12-12 14:24:44

问题


I'm trying to make a simple chatbot which will send a message whenever a certain channel uploads a video, ideally with the video's name and a hyperlink to the video.

YouTube's API is very strange, I haven't the slightest idea how to approach this.

This is what I have so far:

using System;
using System.Linq;
using Google.Apis.Services;
using Google.Apis.YouTube.v3;

YouTubeService service = new YouTubeService(new BaseClientService.Initializer() {
    ApiKey = apiKey,
    ApplicationName = "GoodApp"
});

var getChannel = service.Channels.List("snippet");
getChannel.Id = channelId;

var response = getChannel.Execute();

var channel = response[0]; //now what?

回答1:


Using the YouTube PubSubHubbub service you can get push notifications when a channel uploads new videos, changes a video's title, or changes a video's description. Quote from that page about setting it up:

  1. Set up a callback server that can handle incoming Atom feed notifications.
  2. Use the Google hub to subscribe to receive push notifications:
    • Set the mode to subscribe. (Or set the mode to unsubscribe to cancel a subscription.)
    • Set the callback URL to the URL that you set up in step 1.
    • Set the topic URL to https://www.youtube.com/xml/feeds/videos.xml?channel_id=CHANNEL_ID, where CHANNEL_ID is the YouTube channel ID for which you want to retrieve push notifications.
  3. Process notifications sent to your callback server. [...]

Unfortunately a callback server is more than a few lines of code, and it depends on what kind of server you're running. If you know PHP, AppEngine, or Go, the subscriber repositories on PubSubHubbub may be helpful, otherwise search engines seem to have good results for me.




回答2:


I gave up on Google's .NET API because it seems too arcane for my simple mind.

Instead, I decided to access the API directly from the web using RestSharp, and parse the response using JSON.

I then set a System.Timers.Timer to check every 5 minutes (the channel uploads every 30 minutes, but will vary timings) for videos that it has not already checked.

RestClient restClient = new RestClient("https://www.googleapis.com/youtube/v3/");
DateTime lastTimeChecked = DateTime.Now;
Timer timer = new Timer(60 * 5 * 1000);

refreshTimer.Elapsed += CheckVideos;
refreshTimer.Start();

public static void CheckVideos(object source = null, ElapsedEventArgs e = null) {
    var request = new RestRequest(String.Format(
        "search?part=snippet&channelId={0}&maxResults=4&order=date&type=video&key={1}", 
        channelId, 
        apiKey
    ), Method.GET);

    request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };

    var queryResult = restClient.Execute(request);

    YouTubeResponse response = JsonConvert.DeserializeObject<YouTubeResponse>(queryResult.Content);

    foreach (var video in response.items.Reverse<Item>()) {
        if (video.snippet.publishedAt > lastCheckTime) { //actual code to compare is much longer...
            SendMessage(String.Format("Video {0} was uploaded!", video.snippet.title));
        }
    }

    LastCheckTime = DateTime.Now;
}

This is nowhere near perfect, it often will drop videos if the timing of the video's upload is unlucky. Obviously, an event-based solution would be optimal.



来源:https://stackoverflow.com/questions/37913009/how-to-call-a-function-when-a-youtube-user-uploads-a-video

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!