Search code examples
c#.netyoutubeyoutube-api

Programmatically unsubscribe a YouTube user C#


Here is my code for a mass unsubscriber I am making; currently everything works - other than the unsubscribe feature.. (Typical huh)

public void UnSubUsers()
{
    string feedUrl = "http://gdata.youtube.com/feeds/api/users/" + username.Text + "/subscriptions";
    YouTubeQuery query = new YouTubeQuery(feedUrl);
    subFeed = service.GetSubscriptions(query);
    YouTubeRequestSettings yts = new YouTubeRequestSettings("Unsubscriber", DEVKEY, username.Text, password.Text);
    YouTubeRequest request = new YouTubeRequest(yts);
    int i = 0;
    int x = 0;
    x = (listBox1.Items.Count);
    for (i=0;i<x ;i++ )
    {
        string uname = listBox1.Items[i].ToString();
        uname=uname.Substring(42);
        uname = uname.Remove(uname.LastIndexOf("/"));
        Subscription s = new Subscription();
        s.Type = SubscriptionEntry.SubscriptionType.channel;
        s.UserName = uname;
        //MessageBox.Show(uname); //Displays the username so that we know if it is correct
        try
        {
            s.AtomEntry.EditUri = "http://gdata.youtube.com/feeds/api/users/" + username.Text + "/subscriptions";
            s.SubscriptionEntry.EditUri = "http://gdata.youtube.com/feeds/api/users/" + username.Text + "/subscriptions";
            request.Delete(s);
        }
        catch (ArgumentNullException e)
        {
            MessageBox.Show(e.ToString(), "Error");
        }
        catch (GDataRequestException e)
        {
            MessageBox.Show(e.ToString(), "Error");
        }
    }
}

(Also available at http://pastebin.com/LnKMYCJp)

When the code "reaches" request.Delete(s) it gives me this error:

Google.GData.Client.GDataRequestException: Execution of request failed: http://gdata.youtube.com/feeds/api/users/iWinterHD/subscriptions --->System.Net.WebException: The remote server returned an error: (400) Bad Request.
    at System.Net.HttpWebRequest.GetResponse()
    at Google.GData.Client.GDataRequest.Execute()
    --- End of inner exception stack trace ---
    at Google.GData.Client.GDataRequest.Execute()
    at Google.GData.Client.GDataGAuthRequest.Execute(Int32 retryCounter)
    at Google.GData.Client.GDataGAuthRequest.Execute()
    at Google.GData.Client.Service.Delete(Uri uriTarget, String eTag)
    at Google.GData.Client.FeedRequest1.Delete[Y](Y entry)
    at Unsubscriber.SubForm.UnSubUsers() in C:\Users\iWinterHD\documents\visual studio 2010\Projects\Unsubscriber\Unsubscriber\SubForm.cs:line 112

Does anybody know how to fix this, I have been trying to get this working for around 2 hours and I am still getting this error, no matter what I try

When i used fiddler to find out info about the connection this was the header:

DELETE /feeds/api/users/iWinterHD/subscriptions HTTP/1.1
Content-Type: application/atom+xml; charset=UTF-8
User-Agent: G-Unsubscriber/GDataGAuthRequestFactory-CS-Version=2.1.0.0--IEnumerable
X-GData-Key: key=DEVELOPER_KEY
Authorization: GoogleLogin auth=DQAAAMgAAAAfAWmos6z7rpaY8JrK2RNK4Urf7Riu_putKeGgV1KFH5OEmAYA2t5w0DWXbVQJnizQiPmLSl-4D0eCozYn5jVp4DWs4Rpao3udc3eTIC9wibBGRe640m7zZjl96UnFMyf-fJDk0VrTIcAw74S7_WhwBaRDjLS77EOWfERw066NmcYO-2QB_6WZ4Y0o3Y4haVn_pRokm8ckyuTRWJf6cES1yVlZ4fP5diUySVsH7EaHLiUcAquUl7GWCMdF_JbjRVVxvgeMW1zV757JW8l841uk
GData-Version: 2.0
Host: gdata.youtube.com
Connection: Keep-Alive

However the Google Developers example is this:

DELETE /feeds/api/users/default/subscriptions/SUBSCRIPTION_ID HTTP/1.1
Host: gdata.youtube.com
Content-Type: application/atom+xml
Authorization: Bearer ACCESS_TOKEN
GData-Version: 2
X-GData-Key: key=DEVELOPER_KEY

Hopefully that gives a little heads up :)


Solution

  • After searching through all the variables for around 4 hours i ended up stumbling upon the ID variable, which i later discovered needed to be passed to the final URL in order to remove the subscription WITH that ID, I tested it and it worked perfectly!

         public void ListSubs()
                 {
                     string feedUrl = "http://gdata.youtube.com/feeds/api/users/" + username.Text + "/subscriptions";
                     YouTubeQuery query = new YouTubeQuery(feedUrl);
                     try
                     {
    
                         subFeed = service.GetSubscriptions(query);
    
                         foreach (SubscriptionEntry entry in subFeed.Entries)
                         {
                             string id = entry.Id.AbsoluteUri;
                             id = id.Substring(id.LastIndexOf(":")+1);
                             listBox1.Items.Add(id);
                             string usrname = entry.Content.Src.Content;
                             usrname = usrname.Substring(42);
                             usrname = usrname.Remove(usrname.LastIndexOf("/"));
                             listBox2.Items.Add(usrname);
                         }
                     }
                     catch(GDataRequestException e)
                     {
                         MessageBox.Show(e.ToString(), "Error:");
                     }
    
                 }
    
        public void UnSubUsers()
                {
                    YouTubeRequestSettings yts = new YouTubeRequestSettings("Unsubscriber", DEVELOPER_KEY, username.Text, password.Text);
                    YouTubeRequest request = new YouTubeRequest(yts);
                    int i = 0;
                    int x = 0;
                    x = (listBox1.Items.Count);
                    for (i=0;i<x ;i++ )
                    {
                        string uname = listBox1.Items[i].ToString();
                        yts = new YouTubeRequestSettings("Unsubscriber", DEVELOPER_KEY, username.Text, password.Text);
                        request = new YouTubeRequest(yts);
                        Subscription s = new Subscription();
                        s.Type = SubscriptionEntry.SubscriptionType.channel;
                        s.UserName = uname;
                        s.Id = listBox1.Items[i].ToString()
                        try
                        {
                            s.AtomEntry.EditUri = "http://gdata.youtube.com/feeds/api/users/" + username.Text + "/subscriptions" + "/" + listBox1.Items[i].ToString();
                            request.Delete(s);
                        }
                        catch (ArgumentNullException e)
                        {
    
                        }
                        catch (GDataRequestException e)
                        {
    
                        }
                    }
                }
    

    I had to add the subscription ID to the URL i was using to delete the subscription, here is my code to add the subscription ID to the listbox i originally used to store usernames, it turns out you can't pass usernames to the Delete method, but this works just as well because i added a second listbox to find the usernames of the subscription IDs

        string id = entry.Id.AbsoluteUri;
        id = id.Substring(id.LastIndexOf(":")+1);
        listBox1.Items.Add(id);
    

    This code gets the subscription ID from the entry variable, you then add the subscription ID to the EditUri variable:

        s.AtomEntry.EditUri = "http://gdata.youtube.com/feeds/api/users/" + username.Text + "/subscriptions" + "/" + listBox1.Items[i].ToString();
        request.Delete(s);
    

    My mass unsubscriber is now complete!

    Many thanks to @JamieDixon for all his wonderful help!