Facebook open graph custom stories and custom objects with js sdk - facebook-javascript-sdk

I'm trying to devellop a facebook app using custom stories and objects using js sdk but i met some problems.
What i try to achive is to create a story like:
"John played football on MyApp.- with Mike and Kate at city stadium"
under the text to be an image, a title and some description and on click goes to a link.
I have defined my action "Play" and my object "Football".
The action code facebook gives is:
FB.api(
'me/myapp:play',
'post',
{
football: "http://samples.ogp.me/xxxxxxxxxxxx"
},
function(response) {}
);
The object code facebook gives is:
FB.api(
'me/objects/myapp:football',
'post',
{
app_id: myappid,
type: "myapp:football",
url: "http://samples.ogp.me/xxxxxxxxxxx",
title: "Sample Football",
image: "https://fbstatic-a.akamaihd.net/images/devsite/attachment_blank.png",
description: ""
},
function(response) {}
);
However I used it as follows:
HTML:
<a onclick="playFootball();" href="#">Play Football</a>
JS:
function playFootball() {
FB.api(
'me/testapp-radu:play',
'post',
{
tags: "xxxxxx, xxxxxx,",
place: "https://www.facebook.com/pages/MyPlace/xxxxxx?ref=br_rs",
football: "http://samples.ogp.me/xxxxxx",
image: "http://www.peter-ould.net/wp-content/uploads/soccer-ball.jpg",
privacy: {'value': 'SELF'}
},
function(response) {});
}
and the result was this:
http://img545.imageshack.us/img545/337/yj9o.jpg
I was unable to change "played a football" into "played football".
The title was unchanged despite use of property title, same applies to url and description, also I tried to use an object but still no results.
If someone could help me solve these 2 problems I wold be really gratefull, or at least point me to some basic tutorials (facebook documentation sometimes is confuzing for me).

I think you are using football as a wrong way of specifying your story. You are using name of the instance instead of class. Let me explain.
Following are the two scenarios I could come up with:
Your app is about games that users play. So in this case your object becomes game and football will be the name of the game. So now your story reads like:
"A played football with B and C via your_app" since you will be providing the name property of the game object, facebook will select the right story sentence for you
Your app is about sports products, in which case your object becomes sport_product or product and football will be an instance of sport product. But in this case an action of play does not make any sense. So lets say buy is an action. So now your story reads like:
"A bought football with B and C via your_app"
Also if you think about it football does not make sense as an object. What would be the value of the name property of football, "Kaka's football" - does not make sense. Think in terms of a generic class of object rather an instance. (Think Movie not Inception).
Sample Story
Hope this makes sense!

Related

Zapier lazy load input fields choices

I'm building a Zapier app for a platform that have dynamic fields. I have an API that returns the list of fields for one of my resource (for example) :
[
{ name: "First Name", key: "first_name", type: "String" },
{ name: "Civility", key: "civility", type: "Multiple" }
]
I build my action's inputFields based on this API :
create: {
[...],
operation: {
inputFields: [
fetchFields()
],
[...]
},
}
The API returns type that are list of values (i.e : Civility), but to get these values I have to make another API call.
For now, what I have done is in my fetchFields function, each time I encounter a type: "Multiple", I do another API call to get the possible values and set it as choices in my input field. However this is expensive and the page on Zapier takes too much time to display the fields.
I tried to use the z.dehydrate feature provided by Zapier but it doesn't work for input choices.
I can't use a dynamic dropdown here as I can't pass the key of the field possible value I'm looking for. For example, to get back the possible values for Civility, I'll need to pass the civility key to my API.
What are the options in this case?
David here, from the Zapier Platform team.
Thanks for writing in! I think what you're doing is possible, but I'm also not 100% that I understand what you're asking.
You can have multiple API calls in the function (which it sounds like you are). In the end, the function should return an array of Field objects (as descried here).
The key thing you might not be aware of is that subsequent steps have access to a partially-filled bundle.inputData, so you can have a first function that gets field options and allows a user to select something, then a second function that runs and pulls in fields based on that choice.
Otherwise, I think a function that does 2 api calls (one to fetch the field types and one to turn them into Zapier field objects) is the best bet.
If this didn't answer your question, feel free to email partners#zapier.com or join the slack org (linked at the bottom of the readme) and we'll try to solve it there.

KeystoneJS and naming?

I'm new to Keystone JS and NodeJS.
This is the Part I totally do not understand;
Example 'Post' as defined as 'Post', but there are no 'posts', but when I call/ search for Post, in example (and my practices), it was 'posts'.
Exp:
keystone.set('nav', {
posts: ['posts', 'post-categories'],
enquiries: 'enquiries',
users: 'users',
});
Similar 'PostCategory' => 'post-categories', 'Enquiry'=>'enquiries' etc.
But when I making new Routes=>View for my custom post type, I must use:
locals.data = {
food: []
};
At this, its 'food' not 'foods'.
Keystone automatically uses the plural form of your model names in the Admin Panel, instead of its singular name. It's still referred to by its singular name (Food, PostCategory, Enquiry, etc.) throughout your code, but the admin panel uses the plural forms if referring to multiple documents of a model.
When working with local, you can name the properties of that object anything you want. Doesn't have to be locals.data.food; it can be whatever you want.
Also, the plural form of food is food. So nothing will change when using the plural form of a Food model in your Admin Panel.

Rehydrate store references in Mobx

What is the best way to rehydrate your store during app initialization, specifically the references between stores?
For instance, lets say I have 2 api calls:
/todos -> return array of todos
[{id: 1, person_id: 2}]
/persons -> return array of Persons
[{id: 2, name: 'John'}, {id: 3, name: 'Sam'}]
and a Todo object looks like this
class Todo {
...
#observable person;
...
}
Some of the Todos will have a reference to a Person, but not all of them, and not all of the Persons will be referenced, so its not as simple as just scrapping the Persons api call and just returning the Person reference with the Todos api call.
However, we can't be sure that the Persons api call will be returned first, so we cannot just assume to link up the Todo / Person reference whenever the todos response arrives (would like to run calls in parallel)...
Is it just a matter of extra logic in the client side code to ensure we set up all references whenever the data comes in? Or is there some better practice anyone has found in there experience.
EDIT
The more I think about it, I'm thinking the most predictable logic would be to always either get or create a reference object.
So in the above example, if the Todos response comes in first, we would look for the Person object with the id of 2, if it exists great, if it doesn't, create it and reference that object. Then when the persons response comes in it would do the same thing...look for Person with the id of 2, if it exists, update it with the new data, if not, create it.
Anyone have any better ideas?
The simplest way is indeed to load your objects in order, and find them. After that to load them in parallel, and find-or-create placeholders if you refer to them. It's quite a common pattern.

How to construct intersection in REST Hypermedia API?

This question is language independent. Let's not worry about frameworks or implementation, let's just say everything can be implemented and let's look at REST API in an abstract way. In other words: I'm building a framework right now and I didn't see any solution to this problem anywhere.
Question
How one can construct REST URL endpoint for intersection of two independent REST paths which return collections? Short example: How to intersect /users/1/comments and /companies/6/comments?
Constraint
All endpoints should return single data model entity or collection of entities.
Imho this is a very reasonable constraint and all examples of Hypermedia APIs look like this, even in draft-kelly-json-hal-07.
If you think this is an invalid constraint or you know a better way please let me know.
Example
So let's say we have an application which has three data types: products, categories and companies. Each company can add some products to their profile page. While adding the product they must attach a category to the product. For example we can access this kind of data like this:
GET /categories will return collection of all categories
GET /categories/9 will return category of id 9
GET /categories/9/products will return all products inside category of id 9
GET /companies/7/products will return all products added to profile page of company of id 7
I've omitted _links hypermedia part on purpose because it is straightforward, for example / gives _links to /categories and /companies etc. We just need to remember that by using hypermedia we are traversing relations graph.
How to write URL that will return: all products that are from company(7) and are of category(9)? In otherwords how to intersect /categories/9/products and /companies/7/products?
Assuming that all endpoints should represent data model resource or collection of them I believe this is a fundamental problem of REST Hypermedia API, because in traversing hypermedia api we are traversing relational graph going down one path so it is impossible to describe such intersection because it is a cross-section of two independent graph paths.
In other words I think we cannot represent two independent paths with only one path. Normally we traverse one path like A->B->C, but if we have X->Y and Z->Y and we want all Ys that come from X and Z then we have a problem.
So far my proposition is to use query strings: /categories/9/products?intersect=/companies/9 but can we do better?
Why do I want this?
Because I'm building a framework which will auto-generate REST Hypermedia API based on SQL database relations. You could think of it as a trans compiler of URLs to SELECT ... JOIN ... WHERE queries, but the client of the API only sees Hypermedia and the client would like to have a nice way of doing intersections, like in the example.
I don't think you should always look at REST as database representation, this case looks more of a kind of specific functionality to me. I think I'd go with something like this:
/intersection/comments?company=9&product=5
I've been digging after I wrote it and this is what I've found (http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api):
Sometimes you really have no way to map the action to a sensible RESTful structure. For example, a multi-resource search doesn't really make sense to be applied to a specific resource's endpoint. In this case, /search would make the most sense even though it isn't a resource. This is OK - just do what's right from the perspective of the API consumer and make sure it's documented clearly to avoid confusion.
What You want to do is to filter products in one of the categories ... so following Your example if we have:
GET /categories/9/products
Above will return all products in category 9, so to filter out products for company 7 I would use something like this
GET /categories/9/products?company=7
You should treat URI as link to fetch all data (just like simple select query in SQL) and query parameters as where, limit, desc etc.
Using this approach You can build complex and readable queries fe.
GET /categories/9/products?company=7&order=name,asc&offset=10&limit=20
All endpoints should return single data model entity or collection of
entities.
This is NOT a REST constraint. If you want to read about REST constraints, then read the Fielding dissertation.
Because I'm building a framework which will auto-generate REST
Hypermedia API based on SQL database relations.
This is a wrong approach and has nothing to do with REST.
By REST you describe possible resource state transitions (or operation call templates) by sending hyperlinks in the response. These hyperlinks consist of a HTTP methods and URIs (and other data which is not relevant now) if you build the uniform interface using the HTTP and URI standards, and we usually do so. The URIs are not (necessarily) database entity and collection identifiers and if you apply such a constraint you will end up with a CRUD API, not with a REST API.
If you cannot describe an operation with the combination of HTTP methods and already existing resources, then you need a new resource.
In your case you want to aggregate the GET /users/1/comments and GET /companies/6/comments responses, so you need to define a link with GET and a third resource:
GET /comments/?users=1&companies=6
GET /intersection/users:1/companies:6/comments
GET /intersection/users/1/companies/6/comments
etc...
RESTful architecture is about returning resources that contain hypermedia controls that offer state transitions. What i see here is a multistep process of state transitions. Let's assume you have a root resource and somehow navigate over to /categories/9/products using the available hypermedia controls. I'd bet the results would look something like this in hal:
{
_links : {
self : { href : "/categories/9/products"}
},
_embedded : {
item : [
{json of prod 1},
{json of prod 2}
]
}
}
If you want your client to be able to intersect this with another collection you need to provide to them the mechanism to perform this. You have to give them a hypermedia control. HAL only has links, templated links, and embedded as control types. let's go with links..change the response to:
{
_links : {
self : { href : "/categories/9/products"},
x:intersect-with : [
{
href : "URL IS ABSOLUTELY IRRELEVANT!!! but unique 1",
title : "Company 6 products"
},
{
href : "URL IS ABSOLUTELY IRRELEVANT!!! but unique 2",
title : "Company 5 products"
},
{
href : "URL IS ABSOLUTELY IRRELEVANT!!! but unique 3",
title : "Company 7 products"
}
]
},
_embedded : {
item : [
{json of prod 1},
{json of prod 2}
]
}
}
Now the client just picks the right hypermedia control (aka link) based on the title field of the link.
That's the simplest solution. But you'll probably say there's 1000's of companies i don't want 1000's of links...well ok if that;s REALLY the case...you just offer a state transition in the middle of the two we have:
{
_links : {
self : { href : "/categories/9/products"},
x:intersect-options : { href : "URL to a Paged collection of all intersect options"},
x:intersect-with : [
{
href : "URL IS ABSOLUTELY IRRELEVANT!!! but unique 1",
title : "Company 6 products"
},
{
href : "URL IS ABSOLUTELY IRRELEVANT!!! but unique 2",
title : "Company 5 products"
},
{
href : "URL IS ABSOLUTELY IRRELEVANT!!! but unique 3",
title : "Company 7 products"
}
]
},
_embedded : {
item : [
{json of prod 1},
{json of prod 2}
]
}
}
See what i did there? an extra control for an extra state transition. JUST LIKE YOU WOULD DO IF YOU HAD A WEBPAGE. You'd probably put it in a pop up, well that's what the client of your app can do too with the result of that control.
It's really that simple...just think how you'd do it in HTML and do the same.
The big benefit here is that the client NEVER EVER needed to know a company or category id or ever plug that in to some template. The id's are implementation details, the client never knows they exist, they just executed Hypermedia controls..and that is RESTful.

Use a single POST request to update to create two objects Bad API design?

Consider the scenario, an unknown unauthenticated user is looking at the list of nerddinners and then goes to a particular dinner, enter his name and email and clicks "Attend". This should result in two things. Create the user and create the DinnerAttendRequest for that user.
The user also has a property called FavProgLanguage which is set to the prog language property of the dinner which he wants to attend.
Assuming it is a single page javascript app which talks to an API, there are two approaches which come to mind.
1) On the client, set the users FavProgLanguage and then POST to /user with name, email and favproglanguage to create the user. Use the created UserId and POST to /DinnerAttendRequest with DinnerId and UserId to create DinnerAttendRequest.
2) POST to /somename with Name, email and dinnerId and then use dinnerId at server to populate favproglanguage of user. create user and then use userid to create DinnerAttendRequest
The first approach seems more natural/RESTful, however if the logic of computing the favproglanguage is a bit complex, all the api consumers would have to implement that logic and with the second approach that code is written just once on the server.
Which is a better approach? Is the second approach RESTful?
Your 1st design would place the burden of logic, workflow and the fav lang decision, upon the client, this would make handling the user creation and reservation a single transaction difficult and something that a client app would need to orchestrate. Your fav lang logic sounds like an important business rule that again should ideally sit at the server for re-use...
Why don't you look at having some resources like so:
Dinner e.g. { "name", "date", etc. }
Booking e.g. { "user" { NESTED USER RESOURCE }, "bookingStatus", etc. }
User e.g. { "email", "name", "fav lang", etc.}
Some example urls
/dinners/{uid}
/dinners/{uid}/bookings
/users/{uid}
Basically I would POST a Booking resource containing a nested User resource to the dinner bookings url and run the logic for checking is a user exists, creating if needed and updating their fav lang in a transaction.
So to create a booking I would POST a Booking Resource:
{
"user": {
"email": "john#doe.com",
"name": "name"
},
"bookingStatus": "requested"
}
To /dinners/{uid}/bookings
And expect a 201 created response with a response like this:
{
"uid": "4564654",
"user": {
"uid": "1234564",
"email": "john#doe.com",
"name": "name",
"favLang": "C#"
},
"bookingStatus": "booked"
}
Obviously the properties are largely just for example but hopefully this demonstrates some of the concepts and shows that a single POST can be considered RESTful...