This project is read-only.

[Solution] Getting FriendLists

Oct 23, 2011 at 7:56 AM

FGT doesn't yet include functionality for getting friend lists, so here is  the code.

We're going to do two things at the same time here.  First, we want to be able to see the lists for a user.  Second, we want to get the members (friends) using a list ID.

Start by adding this FriendList class under the GraphApi project folder.  (Note the static GetFriendsInList method) :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JSON;
using Facebook_Graph_Toolkit.FacebookObjects;

namespace Facebook_Graph_Toolkit.GraphApi
{
    /// <summary>
    /// A Facebook friendlist
    /// </summary>
    public class FriendList
    {
        JsonObject data;
        internal FriendList( JsonObject JO )
        {
            data = JO;
        }
        /// <summary>
        /// The list ID
        /// </summary>
        public string ID
        {
            get
            {
                return (string) data[ "id" ];
            }
        }
        /// <summary>
        /// The name of the list
        /// </summary>
        public string Name
        {
            get
            {
                return (string) data[ "name" ];
            }
        }
        /// <summary>
        /// The type of the list
        /// </summary>
        public string ListType
        {
            get
            {
                return (string) data[ "list_type" ];
            }
        }

        /// <summary>
        /// Gets the friends for a specific list
        /// </summary>
        /// <param name="AccessToken">Access Token</param>
        /// <param name="ListID">List ID</param>
        /// <returns>The friends in a list</returns>
        public static IList<NameIDPair> GetFriendsInList( string ListID , string AccessToken )
        {
            return Helpers.ApiCaller.GetFriendsInList(ListID , AccessToken);
        }


    }
}

Now add this method to GraphApi.User:

/// <summary>
/// Gets a list of the user's friendlists
/// </summary>
/// <param name="AccessToken">Access Token</param>
/// <param name="UserID">User ID</param>
/// <returns>The user's friendlists</returns>
public static IList<FriendList> GetFriendLists( string UserID , string AccessToken )
{
    return Helpers.ApiCaller.GetFriendLists(UserID , AccessToken);
}

Add the following methods to Helpers.ApiCaller:

internal static IList<FriendList> GetFriendLists( string ID , string AccessToken )
{
    IList<FriendList> FriendLists = new List<FriendList>();

    string URL = string.Format("https://graph.facebook.com/{0}/friendlists?access_token={1}" , ID , AccessToken);
    string response = Helpers.WebResponseHelper.GetWebResponse(URL);
    JsonObject JO = new JsonObject(response);
    JsonArray dataArray = (JsonArray) JO[ "data" ];
    foreach ( JsonObject FriendListJO in dataArray.JsonObjects )
        FriendLists.Add(new FriendList(FriendListJO));
    return FriendLists;
}

internal static IList<NameIDPair> GetFriendsInList( string ID , string AccessToken )
{
    IList<NameIDPair> Friends = new List<NameIDPair>();
    string URL = string.Format("https://graph.facebook.com/{0}/members?access_token={1}" , ID , AccessToken);
    JsonObject JO = new JsonObject(Helpers.WebResponseHelper.GetWebResponse(URL));
    JsonArray dataArray = (JsonArray) JO[ "data" ];
    foreach ( JsonObject FriendJO in dataArray.JsonObjects )
        Friends.Add(new NameIDPair(FriendJO));
    return Friends;
}

Finally, in your application code:

IList<FriendList> lists = FB.User.GetFriendLists(userID , Api.AccessToken);

And then lets say you want all of the people in your Programmers list:

string ID = ( from list in lists
              where list.Name == "Programmers"
              select list.ID ).First();
IList<NameIDPair> friends = FB.FriendList.GetFriendsInList(ID , Api.AccessToken);

As with the other code I posted today, if this all seems to work OK then I'll request that it be added to the core.  I'm not sure if I'm following proper coding conventions for this project, but for my purposes it works, so I'm using it.  YMMV    :)

 

 

Oct 24, 2011 at 4:00 PM

Thank you very much for your code, I'm also working on new features on the toolkit such as notifications. I'll include this in the next release.

Oct 25, 2011 at 1:41 AM

If you send me a list of what you're working on, I'll consider adding something that's not in your list.

It  can't  hurt to create a tracker item that says "here is what we can expect in the next release, please comment if anything more critical is missing". Then everyone can plan or contribute accordingly.

Sincere thanks for your project here. I find myself productive within hours of getting my brain wrapped around it, where, like hundreds of other people, I've been very disappointed with FDT and other packages.  Sure, this is very limited compared to some of the others, but that's fine.  I think those projects are so bad in part because they strive to do way too much.

Nov 8, 2011 at 2:11 AM
Edited Nov 8, 2011 at 2:56 AM

FYI, I have created methods:

  • Api.CreateFriendList(string ListName) returns string ListID
  • Api.DeleteFriendList(string ListID)
  • Api.AddMemberToFriendList(string ListID, string MemberID)
  • Api.RemoveMemberFromFriendList(string ListID, string MemberID)

I'm testing these now.  Kayson, if you'd like me to rename them or change the signature, I will do so.

For reference, I'm not sure if the methods will stay in Api.  I understand what's happening with static methods vs instance methods, usage of ApiCaller, etc.  I'm trying to work out the most elegant place for this code.

 

Note: calls to FB generally return a Boolean result, but FGT ignores these.  I think we could change signatures of Api calls from void to bool without breaking existing apps.  What do you think?

Nov 11, 2011 at 2:22 PM

I agree with your suggestion that the Boolean result returned by Facebook can be processed by FGT. There're a lot of features in the Facebook Platform and I'll be really glad if someone else like you can help wrap them in C#. I currently have more than 10 updates and fixes in the upcoming release, and I still haven't write documentations about them so there's a lot of work to be done.

Anyway, if you think you've test your code enough you can email it to me. It was not easy to figure out how the methods should be placed in the library (since there's a lot), and it took me quite some time to came up with the way I'm using now:

Static methods in classes that belong to GraphApi namespace represents "connections" in Facebook's Graph Api platform. All of these methods, along with the constructors of these objects, only get data from Facebook, but never modify them.

On the other hand, instance methods inside the Api class modify data on Facebook (with the exception of FQL).

I'm not sure if the above is the best way, but I belive it should be good enough to keep the library organized. Of course if you have a better way of structuring the library you can share it here.

Nov 11, 2011 at 6:42 PM

I wouldn't presume to suggest any restructuring, as 1) I don't know any better than you do, and 2) that would break existing apps.  I do get confused about where things are as far as static  or instance methods, but you're clarifying that above, and that helps.  With these FriendList methods, I've been thinking "everything is related to the current user"  which makes the User class a sort of dumping ground for a lot of things that might be better served elsewhere.  But again, I don't want to do any restructuring for now.

I have verified the first three FriendList methods and will test the Remove method over the next few days.  I will email everything right after that testing is done.

Thanks for the exchanges.