Error message facebook ads-api advertising an event with ads_management permission of the user - facebook-ads-api

im having difficulties by trying to advertise an event through the facebook ads api. My facebook app has the "reate_event,manage_pages,read_stream,ads_management" permission of the user, who set up an event on facebook.
When i call the facebook ads api with creating an ad it throws me following error message:
[error] => stdClass Object
(
[type] => Exception
[message] => The user is not an admin of the object or the object is not publicly accessible.
[code] => 1487202
)
I did try the same call with being an admin of the specific event and that worked.
Thanks for your help!
Emin

Ads on Facebook are always created using the context of current user, so only objects that are accessible by the current user can be promoted.
In this case, the user creating the ads does not have access to the event that is being promoted and it is not public, therefore it cannot be promoted.
It is not sufficient for your app to have access to a user's objects.

Related

How to create a Google calendar event for non-workspace-google account, if the event was created through Service Account(Google Calendar API)?

I am able to create an event in Google Calendar using Service account and Google Calendar API, where Project and Service Account is created in Google Workspace admin account and in the same account, I have enabled domain-wide delegation property. I haven't created separate calendar and haven't given access to Service account. If I use my workspace-google account in createDelegated(), with this event is getting created in 'abc#myworkspace.com' calendar and 'created by' property is also the same for every attendee I have added.
GoogleCredentials googleCredentials = GoogleCredentials
.fromStream(new FileInputStream(CREDENTIALS_FILE_PATH)).createScoped(SCOPES)
.createDelegated("abc#myworkspace.com");
So my question is what if I need to create event for non-workspace google account(lets say def#gmail.com)
Can I pass 'def#gmail.com' into the createDelegated()? If I do, I am getting,
Error getting access token for service account: 400 Bad Request
So how to create event for non-workspace google account?
Note : App type is still 'Internal' in OAuth consent screen.
Could someone explain what am I missing here?
A service account with domain-wide delegation can only be used for domains
A Google Workspace account is a domain, a personal consumer account is not a domain.
Consequently, you can not perform a request on behalf of a consumer account user via a service account.
Instead, you would need to create the event directly as def#gmail.com similar to the documentation sample.
No you can only delgate to an account on your domain
createDelegated("abc#myworkspace.com");
You can not delgate to a standard google account as there would be no way for you to configure the permissions
perform-google-workspace-domain-wide-delegation-of-authority
Perform Google Workspace Domain-Wide Delegation of Authority
Note: Only users with access to the Admin APIs can access the Admin SDK Directory API, therefore your service account needs to impersonate one of those users to access the Admin SDK Directory API. Additionally, the user must have logged in at least once and accepted the Google Workspace Terms of Service.
Owner vs attendee.
A service account properly delegated. Will have permission to create an event on behalf of a user in the domain that they have been delegated permission.
Example: I have delegated permission to my service account to user User1#myDomain.com. For all intensive purposed the service account now has all permissions of User1. So the service account can create a new event on behalf of user1 and invite anyone to the event they choose.
As there is no way to set up deligation to user2#gmail.com there is no way for the service account to act like this user as it is a standard gmail user.
The only way for an application to create an event on behalf of user2#gmail.com would be to use Oauth2 and request consent of User2#gmail.com to access their private data. Then the application would be able to create a new event on behalf of User2#gmail.com.
Remember this is creating an event. There is nothing stopping the service account delegated as user1#mydomain.com from inviting user2#gmail.com to the event. user2#gmail.com will then be notified that they have been invited to the event they can then decide if they want to attend or not if they accept it then it will appear in their google calendar account. Notice how user2#gmail.com had to manually accept this. User1#mydomain.com did not have to manually accept that the event was created in their google calendar as the service account was acting on their behalf.

How to select particular account while making oauth api call in google?

For Eg: Using google drive api i made an API call to get permission from user and generate access token and got user details using that token. In that case before getting permission from user if i logged in into multiple google accounts in my browser and i tried through particular mail Id through my app. I need to display only that mail id for permission , Not to display all the logged in mail ids. How to filter for particular mail id through api call.
My sample api call:
https://accounts.google.com/o/oauth2/auth?client_id=CLIENT_ID +&redirect_uri=REDIRECT_URI &scope=email+profile+https://www.googleapis.com/auth/drive&response_type=code&access_type=offline
I just removed prompt=select_account keyword from this api call. but it still display all accounts. How to filter for particular mail id?
You add the login_hint parameter with an account value to the authentication request.

Gmail API domain-wide delegation

I am using Gmail API and I am trying to fetch emails from all users under company. But when I run code such as:
function runAPI(auth) {
var gmail = google.gmail('v1');
gmail.users.threads.list({auth: auth, userId: '108800016305523828361'},'',function(err, response){
if (err) {
console.log("The API returned an error: " + err);
return;
}
var threads = response.threads;
console.log(threads);
})
}
I get error:
The API returned an error: Error: Delegation denied for xxxx#xxxxx.com
In admin console I did this:
As client name I used id from the client_secret.json file. And for scope, I gave it all permissions.
How do I properly setup domain wide delegation for Gmail API ?
The setup is fine, however in your code you're doing it wrong.
This code:
gmail.users.threads.list({auth: auth, userId: '108800016305523828361'},'',function(err, response)
specifically.
userId should be "me" however before you can call the Gmail API you need to use the service account "JWT flow" in your code to retrieve an oauth2 credential for the Gmail user you want to access as described in the Preparing to make an authorized API call service account domain-wide delegation doc.
Specifically this uses your service account's private key to request to get a credential for the user you desire (set the user's email in your domain that you want to access in the setServiceAccountUser(user#example.com) function in the request). Then you can use that GoogleCredential in your call to the Gmail API.
For the question How do I properly setup domain wide delegation for Gmail API?
I think this documentation from Google can help you with this, just follow this steps to delegate domain-wide authority.
Go to your Google Apps domain’s Admin console.
Select Security from the list of controls. If you don't see Security listed, select More controls from the gray bar at the bottom of the page, then select Security from the list of controls. If you can't see the controls, make sure you're signed in as an administrator for the domain.
Select Show more and then Advanced settings from the list of options.
Select Manage API client access in the Authentication section.
In the Client Name field enter the service account's Client ID. You can find your service account's client ID in the Service accounts page.
In the One or More API Scopes field enter the list of scopes that your application should be granted access to. For example, if your application needs domain-wide access to the Google Drive API and the Google Calendar API, enter: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
In your case, use this scope for Gmail API.
Click Authorize.
For more information about the error 403 or Delegation denied for <user email>,check this related SO question:
Gmail API returns 403 error code and “Delegation denied for user email"
GMail API Super Admin access other users accounts via API?

What does Spring Social do when Facebook gives us a new Access Token for a user already connected

When Facebook gives a user a newer updated token and we already have a userconnection record for that user, does a new userconnection record get created or does the userconnection record for that user just get updated with the new token?
Basically, what is happening here is that each device they use creates a new different Facebook token, than what is currently stored in Spring Social's userconnect db table. And it is therefore calling the ConnectionSignUp implementation we have written, which right now creates a new Our App User for our application, instead of seeing that it is the same Facebook user and use the same App internal User in our application.
AccountSecurity accountSecurity = accountService.newUserGenerator(newUserName, username, userProfile.getFirstName(),
userProfile.getLastName(), userProfile.getEmail())
Update 12-5-14 4:09 PM PST: It seems that yes, the two different "devices" will get different access tokens. Spring Social will just use the providerid and userproviderid and "see" that they are the same account and not create a new user by calling a ConnectionSignUp execute() method in that case.
However, it seems that Facebook is not sending back the same userproviderid when it should considering it is the exact same app (Flash versus iOS app, but defined as one app in Facebook) and the exact same user account (mine). Facebook should send the same userproviderid.

Impersonate current user when calling a Google API using service account & delegation of authority

There is a marketplace requirement that if a Google Apps for Work domain admin installs our app for their domain, the admin and any users from their domain should thereafter not see a scope auth screen when accessing our app. The act of installing the app for the domain should implicitly delegate domain-wide authority for the service account associated with our app.
In order to achieve this behavior, I am trying to do delegation of authority to a service account to work on behalf of, AKA impersonate, the currently logged in user.
The code snippet below shows the various attempts that I've made to get this to work. The only one that does work is to pass a domain superuser's email address as the "sub" param (AKA prn) when creating the JWT. However, this essentially elevates a regular run of the mill domain user's privileges to those of super user which is not the desired effect.
var client = new googleapis.auth.JWT(
'<serviceaccount>#developer.gserviceaccount.com',
'localhost.pem',
null,
["https://www.googleapis.com/auth/admin.directory.user.readonly"],
// null - // 403 not auth
// {'userId' : 'domainsuperuser#email.com'} // 403 not auth
// {'userId' : 'me'} // 403 not auth
// "domainsuperuser#email.com" // works!
// "{domainsuperuser#email.com}" // not a valid email error
// 'me' // invalid impersonation prn email address
);
Does Google honor any other ID than just the email address of the person you want to impersonate such as the special 'me' value?
It feels like we are running into a chicken and egg problem here. Essentially we don't want to hardcode the email address (especially not an admin email), so it feels like we have to make an API call. But we can't make an API call without impersonating a user.
You don't need to use a service account and domain-wide delegation in this case. Instead, simply go through the normal OAuth2 flow with the user, and the approval screen will be skipped automatically.
When the admin installs the app and approves your scopes, they are essentially automatically granting you access to those scopes for all users in the domain. And while it is a requirement that users not see the approval screen, you still have to go through the OAuth2 flow with them in order get the OAuth2 token. If you launch an OAuth2 flow for the user, and don't request any scopes not already approved by the domain admin and don't set approval_prompt=force in the URL, then the OAuth2 approval screen will instantly redirect to your redirect URI, making the process invisible to the user.

Resources