Reputation: 1620
I'm using Facebook SDK http://facebooksdk.net/ to upload videos.
My function: EnsureRequiredPermissions() works well, but how can it be written better?
The following C# console application should be able to upload videos to a facebook wall and if you were to substitute "me" for a PageId and use the Page's AuthToken instead it should also be able to upload videos to a Facebook Page too.
Note the work around for the default timeout of 100 seconds.
public void Main()
{
var facebookClient = new FacebookClient(@"SomeFacebookOAuthToken");
// Ensure the web request does not time out at 100 seconds.
facebookClient.SetHttpWebRequestFactory(CreateHttpWebRequest);
if (!EnsureRequiredPermissions(facebookClient))
{
Console.WriteLine(@"Insufficient permissions to continue.");
return;
}
var result = UploadVideo(facebookClient, @"C:\Path\To\Video.mp4", @"Some Title", @"Some Description");
Console.WriteLine(result);
}
private static bool EnsureRequiredPermissions(FacebookClient facebookClient)
{
var requiredPermissions = new List<String>
{
@"publish_stream"
};
dynamic response = facebookClient.Get(@"me/permissions");
var responseObj = JObject.Parse(response.ToString());
foreach (JProperty permission in responseObj[@"data"][0].Children())
{
if (requiredPermissions.Contains(permission.Name) && permission.Value.ToString() == @"1")
requiredPermissions.Remove(permission.Name);
}
return requiredPermissions.Count == 0;
}
private static object UploadVideo(FacebookClient facebookClient, string path, string title, string description)
{
var mediaStream = new FacebookMediaStream
{
ContentType = @"application/octet-stream",
FileName = Path.GetFileName(path)
};
// Note: FacebookMediaStream supports IDisposable but closes the stream before all bytes are read.
using (var fileStream = File.OpenRead(path))
{
mediaStream.SetValue(fileStream);
var parameters = new
{
description = description,
title = title,
mediaStream
};
try
{
return facebookClient.Post(@"me/videos", parameters);
}
catch (FacebookOAuthException unknownError)
{
// Facebook are wankers so pretty much every exception
// will be: "An unknown error has occurred".
Console.WriteLine(unknownError);
throw;
}
}
}
private static HttpWebRequestWrapper CreateHttpWebRequest(Uri url)
{
var httpWebRequest = (HttpWebRequest) WebRequest.Create(url);
var wrapper = new HttpWebRequestWrapper(httpWebRequest)
{
Timeout = System.Threading.Timeout.Infinite
};
return wrapper;
}
Upvotes: 0
Views: 511
Reputation: 1107
i know im late, but here's how i do it: Assembly Facebook.dll, v6.0.10.0
1) Create Models :
public class FbData<T> {
public IList<T> Data { get; set; }
}
public class UserPermission {
public string Permission { get; set; }
public string Status { get; set; }
[JsonIgnore]
public bool Granted { get { return Status.ToLower() == "granted"; } }
}
2) Use helper like this:
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using Microsoft.AspNet.Facebook;
using Microsoft.AspNet.Facebook.Client;
using System.Threading.Tasks;
public class FacebookHelper
{
public static async Task<IList<T>> GetArrayAsync<T>(Facebook.FacebookClient facebookClient, string path)
{
dynamic response = await facebookClient.GetTaskAsync(path);
var str = response.ToString() as string;
if (str.IsNullOfEmpty())
return default(IList<T>);
var result = await Newtonsoft.Json.JsonConvert.DeserializeObjectAsync<FbData<T>>(str);
return result.Data;
}
public static async Task<bool> EnsureRequiredPermissions(Facebook.FacebookClient facebookClient, params string[] Permissions)
{
var requiredPermissions = new List<String>(Permissions);
var userPerms = await GetArrayAsync<UserPermission>(facebookClient, "me/permissions");
var allowed = from e in userPerms where e.Granted select e.Permission;
requiredPermissions.RemoveAll(o => allowed.Contains(o));
return requiredPermissions.Count == 0;
}
}
EDIT: Add more exemple If you wish to make one call for example picture, likes and user, you can use something like this:
public static async Task<T> GetAsync<T>(Facebook.FacebookClient facebookClient, string objectPath, bool AddGetFields = true)
where T: class
{
var path = objectPath + (AddGetFields ? FacebookQueryHelper.GetFields(typeof(T)) : "");
dynamic response = await facebookClient.GetTaskAsync(path);
var str = response.ToString() as string;
if (str.IsNullOfEmpty())
return default(T);
return await Newtonsoft.Json.JsonConvert.DeserializeObjectAsync<T>(str);
}
public static Task<MyAppUser> GetCurrentLogedUser(Facebook.FacebookClient facebookClient)
{
return GetAsync<MyAppUser>(facebookClient, "/me");
}
and the model will be :
public class MyAppUser
{
public string Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Link { get; set; }
[JsonProperty("picture")] // This renames the property to picture.
[FacebookFieldModifier("type(large)")] // This sets the picture size to large.
public FacebookConnection<FacebookPicture> ProfilePicture { get; set; }
//[FacebookFieldModifier("limit(8)")] // This sets the size of the friend list to 8, remove it to get all friends.
//public FacebookGroupConnection<MyAppUserFriend> Friends { get; set; }
//[FacebookFieldModifier("limit(16)")] // This sets the size of the photo list to 16, remove it to get all photos.
//public FacebookGroupConnection<FacebookPhoto> Photos { get; set; }
public FacebookGroupConnection<Like> Likes { get; set; }
}
public class Like
{
public string Name { get; set; }
public string Category { get; set; }
public string Id { get; set; }
}
public class FacebookPicture
{
public string Url { get; set; }
}
the FacebookQueryHelper.GetFields(typeof(T)) return a string tell to facebook to return specific field, so if a model have only id, it will not return all field. If the model have a FacebookGroupConnection or FacebookConnection property it will be filled (Like the Likes property). It will also add modifiers, like :[FacebookFieldModifier("limit(16)")] will limit the resutl array to 16
Upvotes: 1