I need to get some automated ad insights using the Marketing Api. For this purpose I have created a System User via the Business Manager, and generated a System User access token with the ads_read permission.
Using this token then to make api calls and get a specific Campaign's Insights, with the FacebookAds php v2.6 sdk, I get the following error:
Uncaught exception 'FacebookAds\Http\Exception\PermissionException'
with message '(#275) Cannot determine the target object for this
request. Currently supported objects include ad account, business
account and associated objects.'
Does my app need to be whitelisted or am I missing something else? I noticed that next to the 'ads_read' permission there was this note that stated '(your App must be whitelisted)'.
Here is the sample code I'm using
<?php
define('VENDOR_DIR', 'vendor/'); // Path to the Vendor directory
$loader = require VENDOR_DIR.'autoload.php';
use FacebookAds\Api;
use FacebookAds\Object\Campaign;
// Initialize a new Session and instantiate an Api object
Api::init(
'xxxxxxxxxxxxxxxx', // App ID
'xxxxxxxxxxxxxxxxx',
'xxxxxxxxxxxxxxxxxx' // System User Access Token
);
$api = Api::instance();
use FacebookAds\Object\Values\InsightsLevels;
$campaign = new Campaign('xxxxxxxxxxxxx');
$params = array(
'level' => InsightsLevels::CAMPAIGN,
);
$async_job = $campaign->getInsightsAsync(array(), $params);
$async_job->read();
while (!$async_job->isComplete()) {
sleep(1);
$async_job->read();
}
$async_job->getResult();
?>
It seems like your app doesn't have ads_read permission. Here you can find more information on how to ask for it: https://developers.facebook.com/docs/marketing-api/access
Related
I've been following the steps here and here to try to use a service account key file to access the Google pay api and insert a LoyaltyClass. The Google Pay library suggests using version 1.1.1 of the Google api client library, which is what I've done here:
$client = new Google_Client();
$client->addScope('https://www.googleapis.com/auth/wallet_object.issuer');
$client->setApplicationName("Test");
$client->setDeveloperKey("My service account key");
$test_class = new LoyaltyClass;
$service = new Google_Service_Walletobjects($client);
$wallet_object = $test_class->create_wallet_class();
$service->loyaltyclass->insert($wallet_object);
And I get this error:
PHP Fatal error: Uncaught Google_Service_Exception: Error calling POST https://www.googleapis.com/walletobjects/v1/loyaltyClass?key=2ee78c76d17cabcdce22c4e89af27ab73ad694a4: (401) Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project. in /var/www/html/google-api-php-client/src/Google/Http/REST.php:76
The cloud api console logs that I've reached the api with the correct service account, but doesn't log any requests. The link they suggest directs me to prompt a user to login, but I want to access this api without input from a user, just my service account. Is there a way to do this?
What are you supplying to setDeveloperKey?
The documentation uses setAuthConfigFile instead of setDeveloperKey:
$client = new Google_Client();
$client->setApplicationName('Wallet Objects App');
$client->setScopes(array('https://www.googleapis.com/auth/wallet_object.issuer'));
$client->setAuthConfigFile('/example/path/to/privatekey.json');
There's a GitHub sample project that initializes the Google_Client class which uses the following code:
$this->client = new Google_Client();
// do OAuth2.0 via service account file.
// See https://developers.google.com/api-client-library/php/auth/service-accounts#authorizingrequests
putenv('GOOGLE_APPLICATION_CREDENTIALS=' . SERVICE_ACCOUNT_FILE); // for Google_Client() initialization for server-to-server
$this->client->useApplicationDefaultCredentials();
// Set application name.
$this->client->setApplicationName(APPLICATION_NAME);
// Set Api scopes.
$this->client->setScopes(array(SCOPES));
SEVICE_ACCOUNT_FILE is defined in Config.php.
If you'd like a step by step tutorial for integrating with the Passes API, there's a codelab that you can follow: https://codelabs.developers.google.com/passes-loyaltyapi
It's written for NodeJS, but most of the concepts should still apply to PHP.
EDIT: Updated to refer to setAuthConfigFile from the Google Pay developer site.
EDIT: Updated to include PHP sample code from GitHub
I'm building an application that has a simple email-pass login. I want to use the Microsoft Graph to return the profile information of a user that has logged in (I'm not using office365 OAuth right now).
I've set up an action that tries to fetch this user data (i.e given name or profile photo) from an organization I'm part of. I got this error:
"line":113,
"message":"Client error: GET https://graph.microsoft.com/v1.0/users/{user}
resulted in a 401 Unauthorized response:
{
"error": {
"code": "Authorization_IdentityNotFound",
"message": "The identity of the calling application (truncated...)"
}
}
I've set up the application as specified on the Microsoft Graph tutorial (step 2) and this the code I've written, using the repository readme:
class MsGraphService implements iAction
{
protected $accessToken;
public function __construct()
{
$guzzle = new \GuzzleHttp\Client();
$url = 'https://login.microsoftonline.com/'.ENV('MSGRAPH_TENAND_ID').'/oauth2/token?api-version=1.0';
$token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => ENV('MSGRAPH_CLIENT_ID'),
'client_secret' => ENV('MSGRAHP_CLIENT_SECRET'),
'resource' => 'https://graph.microsoft.com/',
'grant_type' => 'client_credentials',
],
])->getBody()->getContents());
$this->accessToken = $token->access_token;
}
public function execute($data)
{
$graph = new Graph();
$graph->setAccessToken($this->accessToken);
$user = $graph->createRequest("GET", sprintf("/users/%s",$data['email']))
->setReturnType(Model\User::class)
->execute();
return $user->getGivenName();
}
}
The accesstoken attribute was caught, so I think the app configuration is ok.
Maybe is an issue about API permissions, specifically: Application permissions?
I've also asked about this on GitHub.
You are probably running into problems because you are trying to use the AzureAD V1 authentication endpoint. It is much easier to get the AzureAD v2 endpoint to work with Microsoft Graph. There are details on how to do it here https://learn.microsoft.com/en-us/graph/tutorials/php?tutorial-step=3
The main different between V1 and V2 is that you no longer use a resource parameter and you use scopes instead to say want you want access to.
When trying to fetch user related information using the API (no signed-in user) you should ask an administrator for permissions to read that information. In order to set the correct permissions to your application you should:
Go to https://portal.azure.com and login
Click on Azure Active Directory
Go to App Registrations
Select your existing appliaction and click on View API permissions
Select + Add a permission / Microsoft Graph / Application Permissions / User / User.Read.All
Ask an administrator for consent
With that, you will be able to fetch users data from your application without a signed-in user.
I'm using Hybridauth 3 in my PHP app to make some periodical tweets on behalf of my account.
The app has all possible permissions. I'm giving it all permissions when it asks for them on the first auth step.
After that Twitter redirects me to the specified callback URL and there I'm getting a pair of access_token and access_token_secret.
But when I'm trying to make a tweet using these tokens - it gives me:
{"errors":[{"code":220,"message":"Your credentials do not allow access to this resource."}]}
Here's how I'm trying to make a tweet:
$config = [
'authentication_parameters' => [
//Location where to redirect users once they authenticate
'callback' => 'https://mysite/twittercallback/',
//Twitter application credentials
'keys' => [
'key' => 'xxx',
'secret' => 'yyy'
],
'authorize' => true
]
];
$adapter = new Hybridauth\Provider\Twitter($config['authentication_parameters']);
//Attempt to authenticate the user
$adapter->setAccessToken(/*tokens I've got from getAccessToken() on /twittercallback/*/);
if(! $adapter->isConnected()) {
// never goes here, so adapter is connected
return null;
}
try{
$response = $adapter->setUserStatus('Hello world!');
}
catch (\Exception $e) {
// here I've got the error
echo $e->getMessage();
return;
}
Tried to recreate tokens and key\secret pairs and passed auth process for the app many times, including entering password for my Twitter account (as suggested in some posts on stackoverflow) but still have this error.
P.S. According to this, Hybridauth has fixed the issue in the recent release.
It looks like you are using application authentication as opposed to user authentication. In order to post a tweet, you must authenticate as a user. Also, make sure your Twitter app has read/write privileges.
After comparing headers of outgoing requests from my server with the ones required by Twitter, I've noticed that Hybris doesn't add very important part of the header: oauth_token. At least it's not doing this in the code for Twitter adapter and for the scenario when you apply access token with setAccessToken(). It's just storing tokens in the inner storage but not initializing corresponding class member called consumerToken in OAuth1 class.
So to initialize the consumer token properly I've overridden the apiRequest method for Twitter class (before it used the defalut parent implementation) and added a small condition, so when consumer token is empty before the request - we need to try to init it.
public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [])
{
if(empty($this->consumerToken)) {
$this->initialize();
}
return parent::apiRequest($url, $method, $parameters, $headers);
}
I'm not sure that I've fixed it the best way, but as long as it's working - that's fine.
For your info setAccessToken was fixed in v3.0.0-beta.2 (see PR https://github.com/hybridauth/hybridauth/pull/880)
I faced the same error when implementing a sample app in clojure and the following resource was a huge help to sort out my confusion about application-only auth vs user authentication: https://developer.twitter.com/en/docs/basics/authentication/overview/oauth
I am trying to use pubnub with their access manager to authorize certain users to a specific channel and then publish a message to the channel after the user has been granted read/write rights. I must be doing something wrong with the publish() call on this after granting access to the user. The first part of code below returns what looks like a successful response for the grant() but the publish() call results in :
Fatal error: Call to undefined method access::publish() in /home/dayfv98/public_html/mobile/pubtest.php on line 48
Here is my code:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require('pubnub.php');
require('pam.php');
$chat_entry = addslashes(trim($_POST['chat_entry']));
// CONNECT TO ACCESS MANAGER
$manager = new access(
"MY_PUB_KEY...not included for security",
"MY_SUB_KEY...not included for security",
"MY_SEC_KEY...not included for security"
);
## Grant User Access
print_r($manager->grant(
"chat", // CHANNEL
"44444", // STRING (AUTH KEY)
true, // READ
true, // WRITE
0 // TTL in MINUTES
));
$manager->publish(array(
'channel' => 'chat', ## REQUIRED Channel to Send
'message' => $chat_entry
));
?>
The access manager library is not intended to be used to do anything outside of the scope of the access manager. It is only intended for grants, revokes, and audits.
You will need to use the normal PubNub sdk, but when constructing your PubNub object, provide the auth token you have previously granted.
**EDIT : ** The PHP SDK seems to have some issue with Access Manager right now. I've done some minor hotfix modifications to address this and have included them into a gist, but please keep an eye on the official repository on github for a newer version : https://gist.github.com/keyosk/9c86b981948a3cf7f378
For instance, to use the auth token you granted in your example above, you would do this :
$pubnub = new Pubnub(array(
'publish_key' => 'MY_PUB_KEY',
'subscribe_key' => 'MY_SUB_KEY',
'auth_token' => '44444',
));
$pubnub->publish(array(
'channel' => 'chat',
'message' => $chat_entry
));
According to the documentation the endpoint looks like
GET /debug_token?
input_token={input-token}&
access_token={access-token}
where
input_token: the access token you want to get information about
access_token: your app access token or a valid user access token from a developer of the app
Assuming I don't have a "valid user access token from a developer of the app" - just because I don't want to refresh it every 2 months and keep always it in mind - how would I perform it using "app access token"?
The getApplicationAccessToken() method is protected, so there is no way to access it without overriding it to public.
Any elegant solution that I'm missing?
PS: a call example that would fail with "You must provide an app access token or a user access token that is an owner or developer of the app" error due to lack of access token:
$tokenDebug = $fb->api('debug_token', array(
'input_token' => $token,
));
PPS: the "interesting" thing is that the error from above would appear not for every $token but for some, and I cannot see any obvious distinction between tokens that fail and that succeed.
PPPS: $token is a user access token
PPPPS: Created a feature request for FB PHP SDK https://developers.facebook.com/bugs/637897982899835
PPPPPS: Probably it could be better to create a pull request instead, but it's 1:30am and I'm too tired for that
OK, so if one needs an app access token, app_id|app_secret (both values concatenated with a pipe symbol in the middle) always works.
The method getApplicationAccessToken seems to have been protected in the PHP SDK up to 3.2.2 – whereas getAppId and getAppSecret are already public in that version; so those could be the alternative to hard-coding id and secret in place.
The PHP SDK has the getOAuth2Client() client method, that returns a \Facebook\Authentication\OAuth2Client instance.
This has the debugToken($accessToken) method, that returns a \Facebook\Authentication\AccessTokenMetadata instance that contains data about the access token.
$appid = '123456789';
$appsecret = 'foobar';
$api = new Facebook(['app_id' => $appid, 'app_secret' => $appsecret]);
$oauth = $api->getOAuth2Client();
$meta = $oauth->debugToken($accessToken);
$meta->validateAppId($appid); // Will throw a FacebookSDKException if invalid
$meta->getIsValid(); // boolean
$meta->getExpiresAt(); // \DateTime|null