Status Again

Coordinator
Oct 22, 2008 at 5:46 AM
I've added Paul Huff as a developer to the project and checked in his FeedService contribution. My professional circumstances have taken me away from Facebook development so I'm just going to hang on as coordinator for a spell. I've still got three Facebook apps out there live in production, but we've had to put them entirely on hold for the time being.

That's the way the corporate cookie crumbles, I suppose.

Bill
Developer
Oct 24, 2008 at 7:56 PM
Edited Oct 24, 2008 at 8:01 PM
Thanks for adding me Bill!

The contribution I sent to Bill was very rough...it was more to demonstrate that I was capable of handling this.  I had not even tested it yet, so there were some bugs to work out.

I have a more robust solution I will upload this weekend.  Sorry its taken so long!

I will bundle all this stuff up and make an official release as well.  Please feel free to contact me with any questions.
Oct 24, 2008 at 9:57 PM
Edited Oct 24, 2008 at 10:02 PM
Bill and Paul,

Thank you so much for continuing Nikhil's excellent Facebook API framework. Paul, your initial check-in was useful to me even though it was incomplete. I used the new support for public canvas pages (Application.RequiresLogin and Application.RequiresAppAdded) to finish this project - http://www.facebook.com/apps/application.php?id=81764930178.

I look forward to getting my hands on future updates and testing them.

Regards,

- Ben Henderson

Updated: post contained weird characters instead of carriage returns. The editor doesn't like Google Chrome.
Coordinator
Oct 27, 2008 at 11:32 PM
You're welcome.

Bill
Oct 29, 2008 at 12:59 AM
does the latest checkin compile for you guys?

\Framework\Service\FeedTemplateBundle.cs' could not be opened ('The system cannot find the file specified. ')    Framework
\Framework\Service\FeedOneLineStoryTemplate.cs' could not be opened ('The system cannot find the file specified. ')    Framework
\Framework\Service\FeedFullStoryTemplate.cs' could not be opened ('The system cannot find the file specified. ')    Framework
\Framework\Service\FeedShortStoryTemplate.cs' could not be opened ('The system cannot find the file specified. ')    Framework
\Framework\Service\FeedStorySize.cs' could not be opened ('The system cannot find the file specified. ')    Framework

Developer
Oct 29, 2008 at 4:53 PM
No...this was not a stable version.  I am working on one but have had a few kinks.  Its a busy busy time.  Got a new job and the transition has bogged me down....plus the holiday with 2 kids makes for busy times.

A full release is in the works.
Nov 12, 2008 at 3:15 AM
Well, I've managed to get the build working by reverse engineering the Debug dlls with reflector. I've been playing with the Feeds API and have added some unit tests and MP3 support - but for the life of me I cannot get this to work. After calling user.publishUserAction and modifying the code to include the session key, I get the following:

104

Incorrect signature

These are the parameters passed to the method,

template_bundle_id : 94237540542
template_data : { "performer":"Andrew Marshall","title":"Prelude in C♯ Minor","composer":"Sergei Rachmaninoff","mp3":{ "src":"http://www.planetmarshall.co.uk/profileplayer/Rach_Op3_2.mp3","title":"Prelude in C Sharp Minor","album":"Composed by Sergei Rachmaninoff","artist":"Piano: Andrew Marshall" } }
story_size : 2
session_key : d26787435c77f61c9bf0b5a5-643450341
v : 1.0
api_key : b7721a9e5cdc53357af79934ddb66035
method : feed.publishUserAction
format : JSON
call_id : 8cb1261ad97b518
sig : 4bed625d375affdcee940d8c8a8b0840
Nov 12, 2008 at 9:42 AM
I think the template data is missing brackets. If mp3 is an array, it should be: { "performer":"Andrew Marshall","title":"Prelude in C♯ Minor","composer":"Sergei Rachmaninoff","mp3":[{ "src":"http://www.planetmarshall.co.uk/profileplayer/Rach_Op3_2.mp3","title":"Prelude in C Sharp Minor","album":"Composed by Sergei Rachmaninoff","artist":"Piano: Andrew Marshall" }] }
Nov 13, 2008 at 1:17 AM
<style> pre { color:Maroon; font-family:monospace; } </style>

Signature Generation

Thanks, but this was not the issue; the mp3 parameters are correct. This issue lies with the FeedService.publishUserAction method. In order to generate the correct signature, the signature generation function requires the names of all parameters passed to the method, including those that are optional and have no value. However, consider the following snippet from FeedService.cs
if (!string.IsNullOrEmpty(story.BodyGeneral))
{
request.Parameters["body_general"] = story.BodyGeneral;
}
In this case, if story.BodyGeneral is null - as it can be since the parameter is optional - the name "body_general" will not be added to the parameter list and so the generated signature will be invalid. The solution is to replace it with the following construct,
parameters["body_general"] = _story.BodyGeneral ?? string.Empty;
If this is repeated for the remaining parameters, the correct signature is generated. I discovered this by comparing the parameters passed to the equivalent PHP sinature generation method.

Unit Tests

Conceivably, parameter generation is error prone and is an ideal candidate for unit testing. As parameters are generated internal to FacebookRequest.InvokeMethod, this can't be done as it stands. However, consider the following interface,
interface IRequestParameterGenerator
{
Dictionary<string,> GenerateParameters();
}
</string,>
I have created a class that implements this interface, called FeedStoryParameterGenerator, and refactored publishUserAction as follows,
public string publishUserAction( IRequestParameterGenerator generator )
{
FacebookRequest request = new FacebookRequest(_session, true);
request.Parameters.AddRange(generator.GenerateParameters());
FacebookResponse response = request.InvokeMethod("feed.publishUserAction");
...
}
We can now construct unit tests for publishUserStory as follows
[TestMethod]
public void TestTemplateData()
{
Hashtable data = new Hashtable();
data["composer"] = "Sergei Rachmaninoff";
data["title"] = "Prelude in C♯ Minor";

FeedStory story = new FeedStory(94237540542, data);
var generator = new FeedStoryParameterGenerator(story);
string expected = "{\r\"title\":\"Prelude in C♯ Minor\",\"composer\":\"Sergei Rachmaninoff\"\r}";
Dictionary<string,> parameters = generator.GenerateParameters();
Assert.IsTrue(parameters.ContainsKey("template_data"));
Assert.AreEqual(expected ,parameters["template_data"] );
}


</string,>
Because publishUserStory accepts and interface, we could provide further test coverage by using a mock framework to test that calls are made with the expected parameter list. One further thing, I modified FeedStory to accept a long as the template_bundle_id, as this is required for some ids ( including the one I was using).
Developer
Nov 26, 2008 at 4:09 PM
I have been meaning to make a new release for weeks.  I started a new job that has had me SLAMMED and not been able to get to it.  I will eventually.  Before I was working on this at my old job since I needed it for a project there.  Not so at my new gig.  Sorry guys.  Soon, I swear.

The feeds were working, but my code that Bill put up was definitley not working.  I have done a lot since putting that up.  Please bear with me people.  I came into a new job with an absolutely insane Dec. 8th deadline and been SLAMMED.  I will get back to the release soon.  I haven't had time to touch it in a few weeks.  I'll try to get to it soon and make an official release.