How to get the list of all users including their last login - smartsheet-api

I have a dashboard to do for my organization about the use of smartsheet licenses by employees.
Normally, the request to obtain such information is as follows (according to the documentation):
https://api.smartsheet.com/2.0/users?include=lastLogin
However, this request displays exactly 100 results per page. All I want is to have all the results.
The documentation indicates that another parameter must be added to the request to obtain the full list of results. The request becomes:
https://api.smartsheet.com/2.0/users?include=lastLogin&includeAll=true
It works, however I only get the entire list of users without their last login, which brings me back to my question: How to get the list of all users including their last login ?

So, according to the docs for the List Users operation, specifying the include=lastLogin query string parameter will only include the lastLogin attribute for each User object in the response when the number of results returned in the response is 100 or fewer. (FWIW, I'd suspect that Smartsheet implemented this behavior because it'd be detrimental to API performance if a single API request tried to fetch the lastLogin value for hundreds or thousands of users.)
Good news though -- you can still get the info you want -- it's just going to take a little extra effort (and code) on your part. You'll need to submit a separate API request for each page of results (i.e., include both the include=lastLogin query string paramater and also the page query string parameter to specify the page number of results you want to retrieve with each request), and then join the results from all responses into a single list that you write to your dashboard. The value of the totalPages attribute in the initial List Users response will tell you how many total pages (of 100 users each by default, which is the maximum number of users you can request at a time if you want the lastLogin attribute included for each User object) are available -- i.e., how many requests you will need to issue in order to get all users and the lastLogin attribute for each.
For example, your first request would be:
GET https://api.smartsheet.com/2.0/users?include=lastLogin
...and let's assume that the response looks like this:
{
"pageNumber": 1,
"pageSize": 100,
"totalPages": 3,
"totalCount": 100,
"data": [
...
]
}
This response will contain the first 100 users -- but the response tells you it's only the first page of three available pages of results (i.e., the value of the totalPages attribute in the response is 3) -- so you'll need to issue two more requests in order to have retrieved the full set of users.
So, next you issue a second request, this time including the page parameter to specify that you want page 2:
GET https://api.smartsheet.com/2.0/users?include=lastLogin&page=2
...and the response returns the second page of results that looks like this:
{
"pageNumber": 2,
"pageSize": 100,
"totalPages": 3,
"totalCount": 100,
"data": [
...
]
}
This response will contain the next 100 users -- i.e., the second page of three available pages -- you'll need to issue one more request in order to have retrieved the full set of users.
So finally, you issue a third request, this time including the page parameter to specify that you want page 3:
GET https://api.smartsheet.com/2.0/users?include=lastLogin&page=3
...and the response contains the third (and in this example, final) page of results that looks something like this (where the value of the totalCount property is a numeric value >= 1 and <= 100 that indicates the number of users in the response):
{
"pageNumber": 3,
"pageSize": 100,
"totalPages": 3,
"totalCount": 52,
"data": [
...
]
}
Now, because the value of the pageNumber property in the response is equal to the value of the totalPages property in the response, you know this is the final set of users and you don't need to issue any more requests.
Between the 3 requests, you've now retrieved the full set of users (and the lastLogin attribute value for each).

Related

API Request Assistance

I'm new to playing around with calling third party REST API's.
I have an API which requires an ID (/sites/{id}/. As I don't know the ID off the top of my head and would like to query multiple ID's, is there anyway to wildcard this ID for it to run through and check for instance ID's 1 through to 10? Or is this more of a python integration?
As mentioned above, if an API happens to have a parameter "id", whether or not you can scan for all available IDs (or any ID between 1 and 10) depends entirely on the API.
In your case, the API (for help.rapid7.com) is well documented. It appears to have an endpoint to "list sites", which should give you what you're looking for:
https://help.rapid7.com/insightvm/en-us/api/index.html#operation/getSites
Sites
GET /api/3/sites
Server URL
https://help.rapid7.com/api/3/sites
Retrieves a paged resource of accessible sites.
PARAMETERS
Query Parameters
* page integer <int32>
Default: 0
The index of the page (zero-based) to retrieve.
* size integer <int32>
Default: 10
The number of records per page to retrieve.
* sort
Multiple query params of string
The criteria to sort the records by, in the format:
property[,ASC|DESC].
The default sort order is ascending.
Multiple sort criteria can be specified using multiple sort query parameters.
You would probably want to do the following:
Call /api/3/sites (with a filter) to get a list of sites you're interested in, then
Make successive calls to /sites/{id}/ for each site in the list you want detailed information about.

When to know when I should put the parameters in the body or not?

I was thinking about the most logical request for my api, while trying to think about rest, but I can't wrap my head around which one of these three choices is correct: what would be the best design for the request, supposing that I want to send 10 from some user triggering the request to user2?
1)
POST /pay
body: {"username": "user2", "amount": 10}
2)
POST /pay/users/user2
body: {"amount": 10}
3)
POST /pay/users/user2/10
I don't know how much information should be in the URL vs. how much information should be in the URL.
Suppose you have many users and some functions that users can perform.
So your api could be like:
GET /users # get user list
POST /users + {"name": "John"} # create user
DELETE /users/{userId} # remove user
GET /users/{userId} # get user by id
GET /users/{userId}/payments # get users payments
POST /users/{userId}/payments + {"amount": 10} # submit new payment
GET /users/{userId}/payments/{paymentId} # get users payment details
As you can see it is a very simple resource tree.
I recommend taking a look at restful-api-guidelines
You want to put an Canonical Identifier in the URL and any other data in the body.
For a POST (which is used to create an new resource) the Canonical Identifier generaly does not yet exist therefor it doesn't need one.
The server then creates one and returns it to the client in the location header.
If you mean to update instead of insert, PUT or PATCH should be used. If the username is your Identifier, then option 2 should be used. An identifier should in general not be editable.
Since your "adding" an new payment I would suggest using option 1. But I would call it payment and perhaps add more information about the payment.

total_count Not Returned as Promised by Object Likes Endpoint

I'm using the Graph API end point referenced below to grab the likes for an object on Facebook.
https://developers.facebook.com/docs/graph-api/reference/v2.1/object/likes
The documentation indicates that I should expect to receive an array of User objects in addition to a field named total_count, which would represent the total number of likes the object has received. I have not been able to get an API response that includes this value - either through my code or via the Graph Explorer.
Has this field already been deprecated? Is there an additional parameter anyone knows of that would trigger the attribute to be returned in the API response?
Is anyone aware of issues with using the solution suggested here?
PageID/posts?fields=comments.limit(1).summary(true),likes.limit(1).summary(true),shares
Add this to the end of your query:
?summary=1
i.e. in graph explorer put: {object-id}/comments?summary=1
( object-id can be the post_id)
Then the total comment count is under this section:
"summary": {
"order": "ranked",
"total_count": 24
}

How do I get lifetime reach and frequency from the Facebook Ad Report Stats API?

I am trying to get lifetime reach and frequency metrics for my users' accounts and am unable to formulate the correct request.
I have tried the following call:
act_1234/reportstats?data_columns=['account_id','reach','frequency']&time_increment=all_days
but this just throws
{
"error": {
"type": "Exception",
"message": "You must specify one of time_ranges, time_interval or date_preset.",
"code": 1487533
}
}
The only thing I can think of is to specify the time_ranges as {time_start:0,time_stop:1391385600} so that the request goes through, but that doesn't return the correct values.
Any ideas?
EDIT 1
I am playing around with specifying the time_interval based on the earliest campaign start time to the current date, not sure if there is a better way.
It will work if you set time_interval and time_increment:
act_1234/reportstats?time_interval={"day_start":{"day":"01","month":"02","year":"2014"},"day_stop":{"day":"04","month":"02","year":"2014"}}&time_increment=all_days&data_columns=['account_id','reach','frequency']&format=json
In case you want to fetch long time range, the only way would be to use the async query.
For async, do a POST request to the same URL above, but with additional parameter: async=true
act_1234/reportstats?time_interval={"day_start":{"day":"01","month":"02","year":"2014"},"day_stop":{"day":"04","month":"02","year":"2014"}}&time_increment=all_days&data_columns=['account_id','reach','frequency']&format=json&async=true
You will get a report ID as a response to this request.
Then you have to make GET request with next parameters:
act_1234/reportstats?report_run_id=NUMBER_YOU_RECEIVED_PREVIOUSLY
And you will get a response with requested parameters, or you will get current progress of the report (in percentage, sometimes it can take a while to generate reports for long period).

How to get (better) demographics for fans of a Facebook page?

I'm trying to get demographics for fans of a page on Facebook - mostly country and city, but age and gender as secondary.
The primary way to do it is using FQL and doing a query in the insights table. Like so:
FB.api({
method: 'fql.query',
query: "SELECT metric, value FROM insights WHERE object_id='288162265211' AND metric='page_fans_city' AND end_time=end_time_date('2011-04-16') AND period=period('lifetime')"
}, callback);
The problem with this, however, is that the table returns a maximum of 19 records only, both for the country and the city stats. The response for a page I'm testing is as such:
[
{
"metric": "page_fans_city",
"value": {
"dallas": "12345",
"atlanta": "12340",
(...)
"miami": "12300"
}
}
]
So I'd like to know if there's any alternative to that -- to get demographics of the current fans of a page (no snapshot necessary).
Things I've tried:
Using LIMIT and OFFSET on the query do nothing (other than, sometimes, give me an empty list).
One alternative that has been discussed in the past is to use the "/members" method from the Graph API (more here) to get a list of all users, and then parse through that list. That simply doesn't work - a method exists, and it may have worked in the past, but it's not valid anymore (disabled?).
Request:
https://graph.facebook.com/platform/members?access_token=...
Response:
{"error":
{
"type":"OAuthException",
"message":"(#604) Your statement is not indexable. The WHERE clause must contain an indexable column. Such columns are marked with * in the tables linked from http:\/\/developers.facebook.com\/docs\/reference\/fql "
}}
Other solution was to do a query to the page_fan table and filtering by page_id. This doesn't work, either; it may have worked in the past, but now it says that the page_id column is not indexable therefore it cannot be used (same error as above, which leads me to believe /members uses the same internal API that has been disabled). Page_fan query is only useful to check if individual users are fans of a page.
There's also the like table, but that's only useful for Facebook items (like posts, photos, links, etc), and not Facebook Pages.
Going to the insights website about the Page, you can see the data in some nice graphs and tables, and download an Excel/CSV spreadsheet with the historic demographics data... however, it also limits the data to 19 entries (sometimes 20 with a few holes in there as cities trade top positions though).
Any other hint on how to get that data? I'd either like the insights query with more results, or at least a way to get all the page fans so I could do the location query myself later (even if the page I want to get it from has almost 5 million fans... gulp).
The data pipeline for this metric is currently limited to 20 items. This is a popular feature request and something Facebook hopes to improve soon.