facebook, how to send tracking info for the user inside data? - facebook

i am using this example to send messages to my friends.
the problem i get into is how do i use the data property to add some tracking info.
I would like to pass a var $test and then be able to read it in a json format, or even an array.
In other words, I would like to pass a var when i send the message and when they accept it and it redirect them to the canvas, i would like to be able to grab it from somewhere:
ex:
"data":[
{
"id":"167548189960088",
"application":{
"name":"Cat's Test Site",
"id":"314268391344"
},
"to":{
"name":"Cissy Lim",
"id":"100001147247007"
},
"data":"'here is my var'",
"message":"'INSERT_UT8_STRING_MSG'",
"created_time":"2011-02-16T08:37:02+0000"
},
Thanks

The "data" parameter currently only supports a string. Very annoying since Facebook seems to support json objects everywhere else. You could put a "json string" there and then eval that to a json object when you want to read it.

Related

REST: Is it considered restful if API sends back two type of response?

We have stock website and we help buyers connect with the sellers. We are creating API to let buyers push their contact details and get back the seller details. This is transaction and get logged in our database. We have created following API:
The request is POST, the URL looks like:
/api/leads
The request body looks like:
{
"buyermobile": "9999999999",
"stockid": "123"
}
The response looks like:
{
"sellermobile" : "8888888888",
"selleraddress": "123 avenue park"
}
We have a new requirement, i.e. we need to send back PDF URL (instead of "sellermobile" & "selleraddress"). This PDF URL would contain the seller details in case it comes from one of our client.
We have modified the same API, now the request body looks like:
{
"buyermobile": "9999999999",
"stockid": "123",
"ispdf": true
}
The response looks like:
{
"sellerdetailspdf" : "https://example.com/sellerdetails-1.pdf",
}
Is it RESTFUL to do this? OR we should create separate API for getting response as PDF?
I wouldn't approach it this way. What happens when you need to add XLS? Do you add "isxls" to the request too?
Things I'd consider:
Use a mime type for content negotiation. Post the same request, and specify in the Accept header what you expect back - JSON, PDF, etc. You're then actually getting the report instead of a link to the report, which may or may not be better.
- or -
Include a link in the typical lead response.
{
"sellermobile" : "8888888888",
"selleraddress": "123 avenue park",
"_links": {
"seller-details-pdf": "https://example.com/sellerdetails-1.pdf"
}
}
- or -
Support a query parameter that specifies the type in the response.
- or -
Have a single property that specifies the type in the response, rather than a boolean. Much cleaner to extend when you add new response types.
The first two options have the bonus that you don't require clients to handle multiple response types to a single request. That's not forbidden by any spec, but it's annoying for clients. Try not to annoy the people who you want to pay you. :)
Again the implementation looks good to me, however you could potentially look at breaking the return of the PDF URL to another endpoint maybe something like api/lead/pdf that way your request body is the same for api/lead and all subsequent endpoints under /lead. Allowing your routes and other code to handle small portioned tasks instead of having a route that handles multiple flags and multiple code routes.
That looks good to me - the same type of input should give the same type of response but in your case you have two different types of input - one with the "ispdf" flag and one without. So it's consistent to responds with two different types of response, one with the PDF link and one without.
That's still something you'll want to document but basically it's a correct implementation.

Custom fields and global subscriptions for Meteor user accounts

I'm adding custom data to Meteor user accounts for the first time. I've been able to add custom fields without difficulty and I know they're there because I can see them in Mongol. I am publishing via a global subscription so how do I then go about reading data from individual fields? It seems the syntax is very different from that when using publish/subscribe methods.
So, I have user accounts like this (as seen in Mongol):
"_id": "#################",
"profile": {
"name": "Test User"
},
"customfields": {
"customfield1": [
"A","B","C"
]
}
}
In server/main.js I have the following
Meteor.publish(null, function() {
return Meteor.users.find(this.userId, {fields:{customfields:1}});
});
This seems to be publishing fine. But what code do I use to render the cursor as data? I've been using variations on code like this in client/main.js and having no success:
var stuff = Meteor.users.find(this.userId).fetch();
console.log(stuff.customfield1);
Any help appreciated.
MyCollection.find() returns a cursor whereas MyCollection.findOne() returns an object, i.e. a single mongodb document.
A publication must return a cursor or array of cursors. You publication is fine.
You are basically trying to make the customfields key of the user object visible on the client. (The profile key is automatically published by Meteor).
On the client, where you are doing:
var stuff = Meteor.users.find(this.userId).fetch();
You can simply use:
var stuff = Meteor.user();
or
var stuff = Meteor.users.findOne(Meteor.userId());
Then stuff.customfields will contain what you're looking for.
The second form is way too verbose for me unless you're looking for a different user than the logged in user.
Note: this.userId on the client will not be the userId of the current user, it will be undefined. That only works on the server. That may actually be the root cause of your problem. In addition, your publications must be ready() for the data to be available. This isn't true immediately after login for example.
Since customfield1 is nested in customfields, did you try stuff.customfields.customfield1?

How to give personalised greeting in Watson Conversation?

While Defining the Dialog in the Watson Conversation I'm not able to greet user with his/her name or I'm not able to detect contact number sent by the user and rephrase it to the user. Is it possible to do it in the Watson Conversation Api or not.
Although Mitch's response is correct, here is an example of doing a personalised response.
1. Set your conversation_start node text to "Hello <? context.username ?>".
2. In your code you would do something like this (Python).
import json
from watson_developer_cloud import ConversationV1
conversation = ConversationV1(
username='SERVICE_USERNAME',
password='SERVICE_PASSWORD',
version='2016-07-11')
workspace_id = 'WORKSPACE_ID_CONVERSATION'
response = conversation.message(workspace_id=workspace_id, context= {'username':'Simon'})
print json.dumps(response)
3. When you run this, it should output the following, with the "text" part being what the user sees.
{
"entities":[],
"intents":[],
"output":{
"log_messages":[],
"nodes_visited":["node_1_1472298724972],
"text":["Hello Simon"]
},
"context":{
"username":"Simon",
"conversation_id":"9dc1501b-ac53-4b51-a299-37f5314ebf89",
"system":{
"dialog_turn_counter":1,
"dialog_stack":["root"],
"dialog_request_counter":1
}
},
"input":{}
}
One thing to be aware is that, the context object is used to maintain the state of the conversation. So if you plan to use just REST API's then you need to merge your context variables into the preceding context object before sending it. You do only need to do this at points where you do know the conversation needs that context.
Do you already have access to this information? You can send these values through as context, and refer to them using $context_variable
The same goes for collecting information from a user. You can capture things using regular expressions via your application, or using some Spring Expressions, you can see the text.matches here:
https://www.ibm.com/watson/developercloud/doc/conversation/dialog_reference.shtml
You would store this as context, and then refer to it using $context_variable again.
Information like names and phone numbers is quite open ended, so can be difficult to capture without using an open entity extraction engine, which we are researching best ways to incorporate this.
To get the user's input, use:
"context": {"yourVariable": "<?input.text?>"}
And to show:
"output": {"text": "You entered this $yourVariable"}

Graph API - get JSON data without "paging" key

I'm getting facebook data using graph api, adding fields in string and get JSON result.
Example:
https://graph.facebook.com/me?fields=music
But JSON returned contains a "paging" key and I do not I want this key.
{ "music":{
"data":[
{
"name":"",
"category":"",
"id":"",
"created_time":""
},
{
"name":"",
"category":"",
"id":"",
"created_time":""
}
],
"paging":{
"next":"https://graph.facebook.com/me?fields=music&method=GET&metadata=true&format=json&callback=___GraphExplorerAsyncCallback___&access_token=...&limit=5000&offset=5000&__after_id=..."
}}}
EDITED:
I'm using Java API (restfb.com) to get JSON.
The command in java is:
FacebookClient client = new DefaultFacebookClient("ACCESS_TOKEN_HERE");
JsonObject rMusic = client.fetchObject("ID_HERE", JsonObject.class, Parameter.with("fields", "id,name,religion,birthday,music"));
How do I avoid it or remove it?
When you have your Javascript object built from the JSON, just pay attention to the array of data: result.music.data
And forget about the paging property: result.music.paging
Remember, there's no law in coding that you have to look at every property in your scripts.
Based upon the edit to the question above, here's a new answer.
The Rest API is deprecated. You should upgrade your app to use the Graph API as this is the one being supported.
Also, if you see a property you don't like, you don't have to access it. Remember, there's no law in coding that you have to look at every property in your scripts.

Sending Batch Request to Facebook Open Graph Beta

I am trying to submit a batch request to add objects via Open Graph Beta to a user's Timeline but no matter what I do I get this:
The action you're trying to publish is invalid because it does not specify any reference objects. At least one of the following properties must be specified: egg.
I am specifying an egg property though. My requests look like this:
https://graph.facebook.com/?batch=[{'method':'POST','relative_url':'/me/my_namespace:find','egg':'http%3A%2F%2Fwww.mydomain.com%2Fmy_namespace%2Fog%2Fegg.php%3Ftypeid%3D-966','start_time':'1317439270','end_time':'1317439270'}]&access_token=<<snipped>>&method=post
I am sending egg as a url-encoded reference string to a URL that contains my open graph data -- the URL does work if I send it not as a batch but since when setting up a user's Timeline I will in some cases have to post up to 1000 actions I am trying to speed things up by batching them.
I was able to successfully delete via a batch request.
Instead of sending the 'egg' as a param of the batch object, you need to format this like a query string and send it in the body param.
Also, relative_url should not begin with a '/'
Try posting this instead...
https://graph.facebook.com/batch?access_token=TOKEN&method=post&batch=
[
{
"method": "post",
"relative_uri": "me/your_namespace:find",
"body": "egg=http%3A%2F%2Fwww.mydomain.com%2Fmy_namespace%2Fog%2Fegg.php%3Ftypeid%3D-966&start_time= 1317439270&end_time= 1317439270
}
]
I've tested this and it works.
When Posting data to the batch API, the data must be formatted like a querysting and sent in the 'body' param as a string.