Facebook Graph API - Ads Insights with different Action Values from Post - javascript

I'm using facebook Graph API to retrieve action values from campaigns. But the JSON returned is always different from any values from facebook screen.
My Request from JavaScript
var d = new FormData();
d.append("access_token", "MY_ADS_INSIGHTS_TOKEN");
d.append("fields", "actions");
d.append("date_preset", "lifetime"); // I want lifetime data
return await (await fetch("https://graph.facebook.com/v3.1/" + campaignid + "/insights", {
method: "post",
body: d
})).json();
and after I access the report insights using the URL:
https://graph.facebook.com/v3.1/REPORT_RUN_ID/insights?access_token=MY_ADS_INSIGHTS_TOKEN
JSON returned after access report task
{
"data": [
{
"actions": [
{
"action_type": "comment",
"value": "2"
},
{
"action_type": "like",
"value": "4"
},
{
"action_type": "photo_view",
"value": "30"
},
{
"action_type": "post",
"value": "1"
},
{
"action_type": "link_click",
"value": "7"
},
{
"action_type": "page_engagement",
"value": "249"
},
{
"action_type": "post_engagement",
"value": "245"
},
{
"action_type": "post_reaction",
"value": "205"
}
],
"date_start": "2018-07-09",
"date_stop": "2018-07-15",
"ad_id": null // removed
}
],
"paging": {
"cursors": {
"before": "MAZDZD",
"after": "MAZDZD"
}
},
"__fb_trace_id__": null // removed
}
Facebook Post Results
I want to know:
Why Facebook Graph API return the post_reaction as 205 since from facebook view it is 160 or 150? the value doesn't match anything, happens to action like too
Notes:
I'm not using any SDK, but this isn't the problem.
The Ad has only ONE ads group and the group has only ONE campaign
I make the requisition at the same time as I see the post. There are no major interactions in this post, it is old enough that the values do not change.
I known that Facebook cache anything, but this Ad is from 10, July.
Ad Campaign Insights reference: https://developers.facebook.com/docs/marketing-api/reference/ad-campaign-group/insights/
I accept answers using SDKs or different programming languages like C#, php or Java as example, I want only know HOW make the right request or what is exactly happening.

Related

How to call FullTextSearchKnowledgeArticle action using REST calls?

How can we call MSCRM action using some HTTP Client request (c#)?
Can any one please assist on this.
The documentation is not covering this action, and I was able to pull this payload from couple of references. But I could not test this in my environment, please test it yourself.
The sample will look like this:
{
"SearchText": "",
"UseInflection": false,
"RemoveDuplicates": false,
"StateCode": 3,
"QueryExpression": {
"#odata.type": "Microsoft.Dynamics.CRM.QueryExpression",
"EntityName": "knowledgearticle",
"ColumnSet": {
"AllColumns": true
},
"Distinct": false,
"NoLock": false,
"PageInfo": {
"PageNumber": 1,
"Count": 10,
"ReturnTotalRecordCount": true,
"PagingCookie": ""
},
"LinkEntities": [],
"Criteria": {
"FilterOperator": "And",
"Conditions": [
{
"EntityName": "knowledgearticle",
"AttributeName": "languagelocaleid",
"Operator": "Equal",
"Values": [
"56940B3E-300F-4070-A559-5A6A4D11A8A3"
]
}
]
}
}
}
Reference.
Make a POST request to the the following URL.
[Your organization root URL]/api/data/v9.1/FullTextSearchKnowledgeArticle
Here is one sample payload that works. You can optionally add additional filters to filter the search result.
{
"SearchText":"test",
"UseInflection":true,
"RemoveDuplicates":true,
"StateCode":3,
"QueryExpression":{
"#odata.type":"Microsoft.Dynamics.CRM.QueryExpression",
"EntityName":"knowledgearticle",
"ColumnSet":{
"AllColumns":true
},
"PageInfo":{
"PageNumber":1,
"Count":10
},
"Orders":[
{
"AttributeName":"modifiedon",
"OrderType":"Descending"
}
]
}
}
Refer the link below for sample code for connecting to Dynamics.
CDSWebApiService class library (C#)

How to correctly retrieve a document from PropDB using specific formatting in the http Trigger GET request (Azure Function)

Here is my issue:
I am trying to set-up an http trigger using Azure functions in javascript. I have been able to post this data into Cosmosdb using my POST function.
CosmosDB Example Item I am looking for:
{
"id": "POLL:FAVECOLORS:LM:LMBWZ18",
"partition": "POLL:LM",
"value": {
"name": "fave colors poll",
"question": "Which color do you like the most?",
"answers": [
{
"text": "Orange",
"count": 0
},
{
"text": "Yellow",
"count": 0
},
{
"text": "Blue",
"count": 0
}
]
},
"_rid": "<info>",
"_self": "<info>",
"_etag": "\"<info>\"",
"_attachments": "<info>/",
"_ts": <info>
}
I am trying to pull this information via input into my Azure Function.
Here is my function.json.
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"route": "<MyURL>/{type}/{objname}/{brand}/{site}",
"methods": [
"get",
"post",
"patch"
]
},
{
"type": "http",
"direction": "out",
"name": "$return"
},
{
"name": "CosmosSend",
"type": "documentDB",
"databaseName": "PropDB",
"collectionName": "WithoutCCN",
"createIfNotExists": false,
"connection": "<Connection-Info>",
"direction": "out"
},
{
"type": "documentDB",
"name": "documents",
"databaseName": "PropDB",
"collectionName": "WithoutCCN",
"connection": "<Connection-Info>",
"direction": "in",
"sqlQuery": "SELECT * FROM c WHERE c.id = {id}"
}
],
"disabled": false
}
I am not sure how I can change my requests format so that it uses the request parameters for the query instead of looking for "https:///{type}/{objname}/{brand}/{site}?id=POLL:FAVECOLORS:LM:LMBWZ18"
module.exports = function (context, req) {
var documents = context.bindings.documents;
var totalDocuments = documents.length;
var azureAppId = req.headers["azure-app-id"];
context.log('azure-app-id = ' + azureAppId);
var idx = '' + (req.params.type + ':' + req.params.objname + ':' + req.params.brand + ':' + req.params.site).toUpperCase();
var paritionx = '' + (req.params.type + ":" + req.params.brand).toUpperCase();
var valuex = req.body;
if (req.method === 'GET') {
context.log('Found '+ totalDocuments +' documents');
if(totalDocuments === 0)
{
context.done(null, createResult(200, 'application/json', "The
requested document was not found."));
}
else {
context.done(null, createResult(200, 'application/json', documents));
}
} else if (req.method === 'POST') {
if (typeof req.body === 'object') {
context.bindings.CosmosSend = JSON.stringify({
id: idx,
partition: paritionx,
value: valuex
});
context.done(null, createResult(201, 'application/json', req.body));
}
else {
context.done(null, createResult(400, 'text/plain', 'The message must be of type application/json.'));
}
I have tried to take the variable 'idx' and put that into the query since it is already in the same format as the POST sends the 'id', but since it is not apart of the function.json itself it cannot be found. If I change the query in the function to:
"sqlQuery": "SELECT * FROM c WHERE c.id = /"{TYPE}:{OBJNAME}:{BRAND}:{SITE}/""
and anything remotely close to that kinda thinking it doesnt work. If I shove what I am looking for exactly into it:
"sqlQuery": "SELECT * FROM c WHERE c.id = \"POLL:FAVECOLORS:LM:LMBWZ18\""
It will find it perfectly every time, but only that one record, and it defeats the purpose of the GET request including its own target information.
I have really been racking my brain on this issue and any tips would really help. I have read a lot of microsoft docs related to the Azure Function and javascript but nothing has helped with this specific issue.
The expected results will be the item in cosmos returned when given the http GET request from the Azure Function app. it will look for the item by the information located in the URL of the request.
Have you tried adding the id as an optional parameter in the route?
"route": "<MyURL>/{type:alpha}/{objname:alpha}/{brand:alpha}/{site:alpha}/{id:alpha?}",
Keep in mind though, that doing this in the same HTTP Trigger Function will always execute the query, even on a POST where you don't send the id. So you are consuming RU's that you are not using.
Ideally you would split this into separate Functions, one for POST, one for GET, which helps them scale independently and you have a greater separation of concerns.

Return JSON results as JS array with AJAX?

Apologies in advance - I am new to this and so other answers have not been able to help me.
I have used AJAX to send data to a PHP script (part of a 3rd party API). The PHP script returns the results as JSON, but I have no idea how to format these on my HTML page.
Ultimately, I would like to save the JSON results as an array and then use JS/Jquery to format them on the page.
I am not sure how to modify the PHP and AJAX scripts to achieve this. Can anyone point me in the right direction?
My AJAX:
$.ajax({
type: 'POST',
url: 'calculator.php',
data: {toPostcode: toPostcodeValue, parcelLengthInCMs: parcelLengthInCMsValue, parcelHeighthInCMs: parcelHeighthInCMsValue, parcelWidthInCMs: parcelWidthInCMsValue, parcelWeightInKGs: parcelWeightInKGsValue},
success: function(data) {
<!--NOT SURE WHAT TO PUT HERE-->
}
})
PHP (after the calculator does its thing - not sure if it needs to be changed):
$serviceTypesJSON = json_decode($rawBody);
echo json_encode($serviceTypesJSON);
The expected JSON results should look like:
{
"services": {
"service" : [
{
"code": "AUS_PARCEL_REGULAR",
"name": "Parcel Post (your own packaging)",
"speed": 2,
"price": 6.95,
"max_extra_cover": 5000,
"extra_cover_rule": "100,1.5,1.5",
"icon_url": "http://test-static.npe.auspost.com.au/api/images/pac/regular_post_box.png",
"description": "Based on the size and weight you've entered",
"details": "Check our ",
"delivery_time": "Delivered in up to 3 business days",
"ui_display_order": 1,
"options": {
"option": [
{
"code": "AUS_SERVICE_OPTION_STANDARD",
"name": "Standard Service",
"price": "0.00",
"price_type": "static",
"option_type": "optional",
"ui_display_order": 1
},
{
"code": "AUS_SERVICE_OPTION_SIGNATURE_ON_DELIVERY",
"name": "Signature on Delivery",
"price": 2.95,
"price_type": "static",
"option_type": "optional",
"tooltip": "Signature on Delivery provides you with the peace of mind that your item has been delivered and signed for.",
"ui_display_order": 2,
"suboptions": {
"option": {
"code": "AUS_SERVICE_OPTION_EXTRA_COVER",
"name": "Extra Cover",
"option_type": "optional",
"price_type": "dynamic",
"tooltip": "Extra Cover provides cover for loss, damage or theft of your item and will fully compensate you to the value specified for your item.",
"ui_display_order": 1
}
}
}
]
}
},
You can do two things, if the return data is JSON use dataType: "json" in the AJAX call.
Edit 1
If you are using dataType: "json". Which is more preferred if you are sure the data return is JSON string. data variable in the success will directly give you the JSON object. I think you can access it like data['services'].
success: function (data) {
jsonObj = $.parseJSON(data);
//this gives you the inner onject of the return data
servicesObj = jsonObj.services;
}
Or you can just get the data then use jQuery.parseJSON() to parse the data string into JSON object.
$.ajax({
type: 'POST',
url: 'calculator.php',
data: {
toPostcode: toPostcodeValue,
parcelLengthInCMs: parcelLengthInCMsValue,
parcelHeighthInCMs: parcelHeighthInCMsValue,
parcelWidthInCMs: parcelWidthInCMsValue,
parcelWeightInKGs: parcelWeightInKGsValue
},
success: function (data) {
jsonObj = $.parseJSON(data);
//this gives you the inner onject of the return data
servicesObj = jsonObj.services; //or jsonObj["services"]
}
})
Your success function will never be called if you are using
echo json_encode(); in your php script.
You should add dataType:'json' after type:'POST' and then your success function will get called and will get the result returned by server in data

Backbone? Can.js? Ghetto DIY? How should I work with this data?

I'm working on an application that lets our security dispatchers update a page that contains current road and campus conditions. The backend is a nodejs/express stack with and the data is a simple JSON structure that looks something like this:
{
"campus": {"condition": "open", "status": "normal"},
"roads": {"condition": "wet", "status": "alert"},
"adjacentroads": {"condition": "not applicable", "status": "warning"},
"transit": {"condition": "on schedule", "status": "normal"},
"classes": {"condition": "on schedule", "status": "normal"},
"exams": {"condition": "on schedule", "status": "normal"},
"announcements" : "The campus is currently under attack by a herd of wild velociraptors. It is recommended that you do not come to campus at this time. Busses are delayed.",
"sidebar": [
"<p>Constant traffic updates can be heard on radio station AM1234. Traffic updates also run every 10 minutes on AM5678 and AM901.</p>",
"<p>This report is also available at <strong>555-555-1234</strong> and will be updated whenever conditions change.</p>"
],
"links": [
{
"category": "Transportation Links",
"links": [
{
"url": "http://www.localtransit.whatever",
"text" : "Local Transit Agency"
},
{
"url": "http://m.localtransit.whatever",
"text" : "Local Transit Agency Mobile Site"
}
]
},
{
"category": "Weather Forecasts",
"links": [
{
"url": "http://weatheroffice.ec.gc.ca/canada_e.",
"text" : "Environment Canada"
},
{
"url": "http://www.theweathernetwork.com",
"text" : "The Weather Network"
}
]
},
{
"category": "Campus Notices & Conditions",
"links": [
{
"url": "http://www.foo.bar/security",
"text" : "Security Alerts & Traffic Notices"
},
{
"url": "http://foo.bar/athletics/whatever",
"text" : "Recreation & Athletics Conditions"
}
]
},
{
"category": "Wildlife Links",
"links": [
{
"url": "http://velociraptors.info",
"text" : "Velociraptor Encounters"
}
]
}
],
"lastupdated": 1333151930179
}
I'm wondering what the best way of working with this data on the client side would be (e.g. on the page that the dispatchers use to update the data). The page is a mix of selects (the campus, roads, etc conditions), TinyMCE textareas (announcements and sidebar) and text inputs (links). I'm open to changing this data structure if necessary but it seems to me to work well. I've been looking at Backbone, and also Can.JS but I'm not sure if either of those are suitable for this.
Some additional information:
there's no need to update an individual item in the data structure separatly; I plan on POSTing the entire structure when it's saved. That said...
there's actually two different views, one for the dispatchers and another for their supervisors. The dispatchers only have the ability to change the campus, roads, etc conditions through drop-downs and furthermore can only change the "condition" key; each possible condition has a default status assigned to it. Supervisors can override the default status, and have access to the announcements, sidebar and links keys. Maybe I do need to rethink the previous point about POSTing the whole thing at once?
the supervisors need to be able to add and remove links, as well as add and remove entire link categories. This means that DOM elements need to be added and removed, which is why I'm thinking of using something like Backbone or Can.js instead of just writing some ghetto solution that looks at all the form elements and builds the appropriate JSON to POST to the server.
Suggestions welcomed!
CanJS works great with nested data. can.Model is inheriting can.Observe which allows you to listen to any changes in the object structure.
If you include can.Observe.Delegate you have even more powerful event mechanism (example from the docs):
// create an observable
var observe = new can.Observe({
name : {
first : "Justin Meyer"
}
})
var handler;
//listen to changes on a property
observe.delegate("name.first","set",
handler = function(ev, newVal, oldVal, prop){
this //-> "Justin"
ev.currentTarget //-> observe
newVal //-> "Justin Meyer"
oldVal //-> "Justin"
prop //-> "name.first"
});
// change the property
observe.attr('name.first',"Justin")

jQuery loading data into jqGrid

I'm a first time user of jqGrid, so far I went trough official examples, I'm interested in loading data into grid either using json.
I'm currently looking at, Loading data(JSON Data):
http://trirand.com/blog/jqgrid/jqgrid.html
Here is a bit of javascript that creates grid :
jQuery("#list2").jqGrid(
{
url : '<c:url value="${webappRoot}/getdetails" />',
datatype : "json",
colNames : [ 'id', 'Location', 'Country Code', 'Type', 'Interval',
'Version', 'Last Active', 'Last Login', 'NOTE' ],
colModel : [
{ name : 'id', width : 10 },
{ name : 'location', width : 75 },
{ name : 'countryCode', width : 50 },
{ name : 'type', width : 40 },
{ name : 'interval', width : 30 },
{ name : 'version', width : 45 },
{ name : 'lastactive', width : 50, align : "right" },
{ name : 'lastlogin', width : 50, sortable : false },
{ name : 'note', width : 50, sortable : false}
],
rowNum : 10,
rowList : [ 10, 20, 30 ],
pager : '#pager2',
width: gridWidth,
sortname : 'id',
viewrecords : true,
sortorder : "desc",
caption : "JSON Example"
});
jQuery("#list2").jqGrid('navGrid', '#pager2',
{ edit : false, add : false, del : false});
${webappRoot}/getdetails transforms path to my project like http://localhost/myProject/getdetails, I'm using spring MVC(it might be irrelevant).
When I look in firebug this generates this http request :
GET http://localhost/newProject/getdetails?_search=false&nd=1304638787511&rows=10&page=1&sidx=id&sord=desc
200 OK
135ms
Here is the response :
{
"id": 1,
"location": "office_2782",
"countryCode": "UK",
"quarter": "500",
"version": "v3.05",
"lastactive": "yesterday",
"lastlogin": "today",
"note": "no note",
"type": "read-only"
}
When I navigate to JSON tab it all seems same as this, any idea what I'm doing wrong?
I'm trying to load only one record for start, and I can't get it working, any help is appriciated.
First of all you are not the first person who has problems understanding how the JSON data should be constructed, what the parameters sent from jqGrid to the server mean and so on. The official jqGrid documentation doesn't contain enough introduction, so the first steps of the jqGrid usage can be a little more difficult than one expect.
The problem which exists in your JSON response from the server is that it contains only one item of data instead of an array (or list) of items representing the grid rows. The data should be at least
[
{
"id": 1,
"location": "office_2782",
"countryCode": "UK",
"quarter": "500",
"version": "v3.05",
"lastactive": "yesterday",
"lastlogin": "today",
"note": "no note",
"type": "read-only"
}
]
or better as
{
"total": 1,
"page": 1,
"records": 1,
"rows": [
{
"id": 1,
"location": "office_2782",
"countryCode": "UK",
"quarter": 500,
"version": "v3.05",
"lastactive": "yesterday",
"lastlogin": "today",
"note": "no note",
"type": "read-only"
}
]
}
or even as
{
"total": 1,
"page": 1,
"records": 1,
"rows": [
{
"id": 1,
"row": [ "1", "office_2782", "UK", "500", "v3.05",
"yesterday", "today", "no note", "read-only" ]
}
]
}
or
{
"total": 1,
"page": 1,
"records": 1,
"rows": [
[ "1", "office_2782", "UK", "500", "v3.05", "yesterday", "today",
"no note", "read-only" ]
]
}
The reason of such strange at the first glance JSON data is that jqGrid is designed to support paging, sorting and filtering/searching of data implemented on the server. So the parameters rows=10&page=1&sidx=id&sord=desc from the url sent to the server mean that jqGrid asks the server to get the first page (page=1) of the data with the page having 10 rows per page (rows=10). The data should be previously sorted by id (sidx=id) in the descending order (sord=desc). If you has small number of rows (under some hundert for example) you can use client based sorting, paging and filtering if you add loadonce:true parameter of the jqGrid, but the server based implementation allows you to work with really large dataset having many hundred thousands rows of data with very good performace.
I recommend you to read my this answer where I tried to explain how the additional elements of the server response "total", "page" and "records" will be used. The values of the parameters can be encoded in JSON either as numbers or as strings (on your taste).
If the user clicks on the column header of the 'location' column for example jqGrid will send new request to the server having sidx=location&sord=asc in the url. So it is important to understand, that the server can be asked to provide the data for the grid not once per grid, but many times and the request will contain some parameters chosen by the user who works with the jqGrid.
Defining of jsonReader (and sometimes additional jsonmap parameters for every column) you describe the structure of the server response. Using the information jqGrid read the response and fill the grid.
The demo shows that with the corresponding jsonReader you can read even your original JSON data.
The last advice for you from me would be to consider at the beginning to use loadError event handle which helps to inform the user about the errors reported by the server. In the answer I have shown how it can be implemented in the case of ASP.NET MVC. I don't use spring MVC myself so I can't give you direct examples of how to better implement the error reporting in spring MVC, but the main idea is the same in any server technology: in case of errors the server should respond with the response having an error HTTP status code. Inside of your implementation of the loadError event handle you decode the response and display the information about the error.

Categories