How to specify an ad-set-id in Facebook graph API URL - facebook-graph-api

I'm using the delivery endpoints of the Facebook Marketing API (v3.2)
I've successfully got this one working:
/{AD_ACCOUNT}/delivery_estimate
(Note, as usual the docs are misleading and you have to use the prefix act_ for it to work)
I can't get this to work:
/{AD_SET}/delivery_estimate
(Ad sets are groups of ads within a campaign).
If you just supply the number on its own, it fails, as you'd expect, with:
Cannot determine the target object for this request. Currently
supported objects include ad account, business account and associated
object.
I've tried a few variations - ad_, adset_, ad-set_, ad_set, adsetid_ etc. - none of which work.
Anybody know what it is? I've not found anything in the API docs, so if anyone does have a Facebook URL that explains it…

Answer - there's no prefix or special way to write ad set IDs. I'm unclear why it wasn't working before.
You can use this to get a list of adsets for the account (as an array in 'data'):
https://graph.facebook.com/v3.3/act_0000000000/adsets
Then you just supply the ID on it's own after the API version number:
https://graph.facebook.com/v3.3/12345678901234567/delivery_estimate?targeting_spec...

Related

AWS API Gateway, Cognito Identity Pool and REST: can I restrict to specific paths and methods?

I want to implement a blog API - for fun and learning - which allows a user to manage and write/view their own blog posts. So far I have an API with paths like
/ - GET all posts,
/blog/{id} - GET a specific post or PUT to update a post
/blog/ - POST for a new blog
Using a cognito user pool, a user can sign up, and login and the API Gateway uses an authorizer to allow or deny access (I'm mucking about with Blazor at the same time - there isn't really an interface yet just a bit of cobbled together C# that uses the identity provide API}.
However, any user can see all posts. I really want something like this:
/{user}/ - GET all posts by user
/{user}/blog/{id} - GET or PUT specific blog post
and so on.
Behind the API gateway are four really simply lambda functions. So far, with the user pool authorizer I can see the Authorization header but nothing else (the request context and context have no Identity elements that are not null).
I was wondering whether I could use Identity Pool to do the specific user permissions using IAM Roles, but I cant think of what the roles might look like, or whether this seems possible. I know there are parameters you can embed in roles - you do that for S3 Roles - why not API paths?
Does this sound plausible or would I need to go down the Lambda function to do authorization? Anyone any examples? I googled and look through stack overflow, but couldn't see anything specific around this.
Another problem I guess would be getting a nice ID substitution for user here - I collect email and nickname so far - need a nice username rather than a cognito user id, which looks like they're wouldn't play well with a URL?
Thanks.
The answer to my query appears to be in this you tube video, put up by the AWS team late last night (uk time, anyway.) So far, using C#, I can authenticate myself against the user pool, and get AWS Credentials, but when I attempt to access my API I get "message": "unauthorized", and that's it!
Anyway, onwards and upwards.
You tube video about fine grained access control using cognito identity pools.

How do I expose a service to different frontends?

I want to create a microservice for "orders". The service will have typical actions like "get orders" or "create an order".
I would like to expose this service in two ways:
User frontend: If you call /orders, you will see your orders
Support frontend: if you call /orders, you will see all the orders of all the users
I would like to deploy one API (orders) that can be called from 2 API gateways (user and support). But, I don't know how to do it without duplicating code.
Is this the right approach?
I'm using AWS Apigateway + Lambda + Serverless.
In some way you're being able to differentiate the user that is making the request inside your lambda function, because you need to get only its orders. Based on that I'm considering that you're receiving some kind of token in your lambda where you can extract the correct user.
Considering that scenario, one standard solution to your problem is add something to your token that differentiate if the user is from the support group or not. Normally you add a claim to the token informing that he/she is part of the support group. Then inside your lambda you check this token and give a different answer based on your requirements. But for that solution, you'll need to have means to add new claims/manage your identity provider data (user information inside your service that provides user tokens).
But with that solution you will find a small problem: if a support user must get all the orders and in another moment only its orders you won't find an easy way to implement this. If your requirements demand that you provide both use cases for support users you will need another solution.
In that case another solution would be to provide two different endpoints (API Gateway API's) touching the same backend lambda. In the normal endpoint you forward the request to the backend and the lambda gets all the orders for the user. In the support endpoint you add something else to the request (can be a query parameter or a http header).
For a more secure solution, your support endpoint must not allow requests from people outside the support group. And if you go for a query parameter alternative, you must block this exact query param in the normal endpoint. Someone can abuse the normal api sending the query param for it and get all the orders if you just forward the query params downstream.
You will do all this different configuration in the integration request of AWS API Gateway. You can find how it works here.

Why passing resources ids via REST API URI if they already known?

I have studied various resources for URI design best practices. Almost every author or blogger says RESTFul API URI have to look like this for example.
/* List all users in account 2 where user id is 1 */
`/users/1/accounts/2/users` [GET]
Above api caller have to pass above two ids in every request.
But my scenario is quite different.
There is a Resource Manager(RM) before my API server so every request have to pass through RM for authentication with valid token to access above example API. Note: [token send via header]
Once request is authorized in return RM provide user info i.e.(user_id, account_id etc.) to my API server via interceptor.
Question is my API server is already aware of user_id and his account_id then still there is need to get these information in API URI.
I have tried following design:
1. /users/accounts/users
2. /accounts/users
3. /users
What is best suitable design for this scenario? I spent two weeks but couldn't decide because these are enterprise APIs design; once designed than will never changed.
You should include ids in the URI for the very reason you give at the end - your API will be very difficult, maybe impossible, to change once it's being used. On the other hand, your implementation will change over time. Your authentication / authorization mechanism could change. Your enterprise may wish to move to an model which doesn't pass around ids in this fashion, and they certainly won't want to find that they have to re-design every single API which depends on the old behaviour.
At the end of the day, including enough information in the URI for the URI to identify the resource it relates to is a key part of ReST. The URI should be all that you need to identify the resource, you don't depend on out-of-band information or implementation details to further identify the resource you're addressing.

How to get promoted page posts using FB api

I am able to get all the page posts that can be promoted via the endpoint given at https://developers.facebook.com/docs/marketing-api/campaigns/objectives#connection_objects
eg query:
https://graph.facebook.com/v2.5/[PAGE-ID]/promotable_posts?fields=id&is_published=true&access_token=[TOKEN]
but how do I get all the posts that are already promoted? I am unable to find anything on the FB API docs.
There is no simple way to do this as there is no association between a post and an ad.
The easiest way to do this would likely be to request all creatives for an account, along with their object_story_id:
/<VERSION>/act_<ACCOUNT_ID>/adcreatives?fields=object_story_id
And then request all ads within the account along with creative and reference whether there is a match:
/<VERSION>/act_<ACCOUNT_ID>/ads?fields=id,creative

How to get user's username in v2.0 or later of Facebook's Graph API

I used to get the user's username in the API 1.0 fairly easily, using /me and getting the username property of the response object.
Now I'm getting this error with API 2.0:
"(#12) username is deprecated for versions v2.0 and higher"
The only way I found to get this until now was to use FQL, but now it seems deprecated.
Is there a way around this?
I don't mean to be unhelpful, but it appears access to username has been removed from the API, as far as I can tell. Places where an app may have been using username, such as in the old share dialogs, can no longer do that when used with the 2.0 API. I think its also a way of preventing apps from having access to usable unique identifiers outside of the app scope - any user IDs you retrieve under 2.0 API are specific to your app alone.
I found a simple workaround that involves a get request to Facebook. Instead of the username, Facebook will give you an ID that is unique to your application.
I have found that making a request to https://www.facebook.com/[profile_id] will then redirect to the user's real profile. The username can be extracted from the redirect URL.
Example:
> curl -i https://www.facebook.com/710290539
HTTP/1.1 301 Moved Permanently
Location: https://www.facebook.com/colinskow
(Note: Since I am the owner of the app in test mode, this could possibly be an exception. Please let me know in comments if you are able to confirm this in a production environment.)
As a workaround you can use the email as a unique identifier. Email address can be retrieved using "email" as the permission scope.
Facebook has removed the username field from the new API version. It is not possible to retrieve the username. But Facebook provides an application specific unique ID. If you need to share the same user between several apps you can use the newly introduced Business Mapping API. This allows to add all the required apps to a group. In this case the ID will be unique among all the apps in the group.
More information on Business Mapping API is available at https://developers.facebook.com/docs/apps/for-business 1