Problems while getting custom dimensions via API from Google Analytics - google-analytics

Goog day. When I try to get custom dimensions via API, I got error
Exception 'Google_Service_Exception' with message 'Error calling GET
https://www.googleapis.com/analytics/v3/management/accounts/~all/webproperties/~all/customDimensions:
(400) Cannot query by ~all for id webPropertyId'
My code
$service_account_name = '<Service Email>#developer.gserviceaccount.com';
$key_file_location = '<keyName>.p12';
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array(Google_Service_Analytics::ANALYTICS),
$key,
'notasecret',
'http://oauth.net/grant_type/jwt/1.0/bearer',
'<My email>'
);
$client->getAuth()->setAssertionCredentials($cred);
$service = new Google_Service_Analytics($client);
$result = $service->management_customDimensions->listManagementCustomDimensions('~all', '~all');
print_r($result);
Similar code for getting goals works correctly
$service_account_name = '<Service Email>#developer.gserviceaccount.com';
$key_file_location = '<keyName>.p12';
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array(Google_Service_Analytics::ANALYTICS),
$key,
'notasecret',
'http://oauth.net/grant_type/jwt/1.0/bearer',
'<My email>'
);
$client->getAuth()->setAssertionCredentials($cred);
$service = new Google_Service_Analytics($client);
$result = $service->management_profiles->listManagementProfiles('~all', '~all');
print_r($result);
Both methods listManagementProfiles and listManagementProfiles get parametrs $accountId and $webPropertyId .
Could someone help, why I get error, while getting custom dimensions via API?

Looking at the documentation "~all" is specifically mentioned as valid parameter value for listManagementProfiles:
Account ID for the view (profiles) to retrieve. Can either be a
specific account ID or '~all', which refers to all the accounts to
which the user has access.
but not for listManagementCustomDimensions, here is says simply
Account ID for the custom dimensions to retrieve.
(same for property id). So your problem is quite literally what the error message says, you cannot use "~all" when querying custom dimensions.
So it seems that to list all custom dimensions you'd have to iterate through a list of property ids (as returned by the properties/list method) instead of using "~all".

Related

Getting An Error when trying to create a subcollection in Firestore

I am trying to create a node in Google Firebase, and use its unique id to create a Document in Google Firestore of the same name.
I'm using Google's PHP Firestore Client: https://github.com/GoogleCloudPlatform/google-cloud-php-firestore
And I've read through their documentation: http://googlecloudplatform.github.io/google-cloud-php/#/docs/cloud-firestore/v0.5.1/firestore/writebatch
Here is my code:
<?php
use \Google\Cloud\Firestore\FirestoreClient;
use \Google\Cloud\Core\Timestamp;
use \Google\Cloud\Firestore\Transaction as FirestoreTransaction;
use \grptx\Firebase as FirebaseClient;
class FirestoreTest
{
public function create()
{
$client = new FirebaseClient();
$database = $client->getDatabase();
$org = array(
"acl" => array(),
"people" => array()
);
$ref = $database->getReference("/clients/")->push($org);
$key = $ref->getKey();
$config = array(
"projectId" => "xxx",
"keyFile" => json_decode(file_get_contents("/xxx/firebase_auth.json"), true)
);
$firestore = new FirestoreClient($config);
$batch = $firestore->batch();
$collection = $firestore->collection("clients")->document("-LXXXXXX")->collection("trips");
}
}
And I get this error:
Exception 'Google\Cloud\Core\Exception\BadRequestException' with message '{
"message": "Document name \"projects\/xxx-test\/databases\/(default)\/documents\/clients\/\" has invalid trailing \"\/\".",
"code": 3,
"status": "INVALID_ARGUMENT",
"details": []
}'
Any help is appreciated.
Basically this will happen if you try to put blank as document name.
This is the error that occurs if you try to get a collection as a document. It's kind of tricky because this can also happen if you try to get a document with the name of empty string in a collection.
I don't know PHP, but I would guess that either in your $database->getReference("/clients/")->push($org); call, you were supposed to name a document to push your information to, or in your $firestore->collection("clients")->document("-LXXXXXX")->collection("trips"); call that the document you are trying to get ("-LXXXXXX") has the name empty string. (Of course, this is assuming your document isn't actually named "-LXXXXXX", and you are using that as a substitute for some variable that happens to be equal to "").
For instance, in python this call randomly failed me earlier:
db.collection(u'data').document(current_id)
with the same error: 'Document name ".../documents/data/" has invalid trailing "/". and will exit.' I scratched my head for a while but that's because the variable current_id is the empty string.
Basically, internally Firebase converts it into a long pathname and then tries to get a document or a collection at that pathname depending on what your last call was. This causes an issue if you try to get a document that is named "".

Get url path of node using entity query

I'm trying to figure out how I can get the path of a node via entity query. So far I've managed to fetch the title of the node but I can seem to find a solution on how to get the node path/url. Here is a sample of my code
$facultyPostings = $query->get('node')
->condition('status', 1, '=')
->condition('type', 'careers')
->condition('field_career_directory', 'Faculty Postings', '=')
->sort('created')
->execute();
foreach ($facultyPostings as $key => $faculty_postings_careers) {
$careersNode = _nodeLoad($faculty_postings_careers);
$variables['faculty_postings'][$key]['title'] = $careersNode->get('title')->value;
$variables['faculty_postings'][$key]['path'] = $careersNode->get('path')->value;
}
You need to use the service provided in Drupal 8 core.services.yml file. So in your loop you can use.
//think so this will get the nid
$nid = $careersNode->get('id')->value;
//This one is correct as per the documentation
$alias = \Drupal::service('path.alias_manager')->getAliasByPath('/node/'.$nid);
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Path%21AliasManager.php/class/AliasManager/8.3.x

google calendar api Error 400 - Invalid resource id value

I want to insert events in Google calendar through the API using a Symfony command (batch).
When I insert an event with an ID like "event01487", it throws me the following errors : "code": 400, "message": "Invalid resource id value."
This id is unique as no events have been inserted - it didn't even insert it once. The id seems to fit the Google requirements...
Do you have any idea why I got this ?
foreach($bookingsToSync as $booking){
$event = new Google_Service_Calendar_Event();
$event->setId($booking['id']);
$event->setSummary($booking['title']);
$event->setDescription($booking['description']);
$start = new \Google_Service_Calendar_EventDateTime();
$start->setDateTime($booking['startDate']->format(DateTime::ATOM));
$event->setStart($start);
$end = new \Google_Service_Calendar_EventDateTime();
$end->setDateTime($booking['endDate']->format(DateTime::ATOM));
$event->setEnd($end);
$output->writeln($event->getId());
$service->events->insert($calendarId, $event);
}
You have to follow the guidelines defined here : https://developers.google.com/google-apps/calendar/v3/reference/events/insert
Basically, the id has to be between 5 and 1024 characters and be composed from characters in this alphabet : 0123456789abcdefghijklmnopqrstuv
You should encode your id as base32
$encoded = bin2hex( $booking['id'] );
To Decode
$decoded = hex2bin( $encoded );

WooCommerce REST Client API - Programmatically get consumer key and secret

I am currently using the client-API to implement a simple user front-end to upload products. The function client->products->create() seems to work fine, how ever I can’t get around one issue.
Every time I upload a product, the vendor is set to the admin user instead of the user that is currently logged in. Is there a way to set the vendor through the API? Has anybody get done this?
This is the function I created that is called by AJaX when the form is submitted (I left key and website fields empty here on purpose):
function addProduct()
{
$options = array(
'debug' => false,
'return_as_array' => false,
'validate_url' => false,
'timeout' => 30,
'ssl_verify' => false,
);
try {
$client = new WC_API_Client('', '', '', $options);
$productName = $_POST["productname"];
$price = $_POST["price"];
$discountPrice = $_POST["discountPrice"];
$description = $_POST["description"];
$shortDescription = $_POST["shortDescription"];
$authorId = 5;
$client->products->create(array('title' => $productName, 'type' => 'simple', 'regular_price' => $price, 'description' => $description));
} catch (WC_API_Client_Exception $e) {
echo $e->getMessage() . PHP_EOL;
echo $e->getCode() . PHP_EOL;
if ($e instanceof WC_API_Client_HTTP_Exception) {
print_r($e->get_request());
print_r($e->get_response());
}
}
echo ("Publicado" . $authorId);
// Una función AJaX en WordPress debe siempre terminarse con die().
die();
}
The problem seems to be the consumer key and consumer secret, so, is there a way to programmatically provide the clients with API keys and get these dynamically?
UPDATE: The method to obtain the consumer key described below will not work; it is no longer possible to get hold of the consumer key from the database once it has been generated. The consumer key stored in this new table is not the same consumer key that is generated in the admin screens and passed out to the end user. It appears to be an SHA256 hashed a version of this key. This is more secure (previously the consumer key and secret stored in wp_usermeta was tantamount to storing clear-text passwords, as anyone with access to that data would be able to log into the API as any of those users), but is a little less convenient. Win some, lose some, but win on security.
Your new WC_API_Client() will take three parameters before the options: $store_url, $consumer_key and $consumer_secret.
Any user on the WC shop who is to be used to access the API will need a consumer key or consumer secret. The consumer key will identify which user the API will run as, and it is that user which will be linked to any entities created through the API.
Until recently, you could get these two pieces of information for a user like this:
$consumer_key = get_user_meta($user_id, 'woocommerce_api_consumer_key', true);
$consumer_secret = get_user_meta($user_id, 'woocommerce_api_consumer_secret', true);
Where $user_id is the ID for the user that will be creating items. If you want the current logged in user to be able to create items in their name then that user would need to be given a consumer key and secret, and would need to be in an appropriate WC/WP group to give them permission to do so.
Note, that if you do this, then the user will also have access to the admin pages for WC to create these items, and not just through the API.
In later versions of WC, the user meta items have been moved to a separate table: wp_woocommerce_api_keys so you need to look in there instead of in the user meta.
This will get you the consumer key and secret for a given user ID:
global $wpdb;
$key = $wpdb->get_row( $wpdb->prepare("
SELECT consumer_key, consumer_secret, permissions
FROM {$wpdb->prefix}woocommerce_api_keys
WHERE user_id = %d
", $user_id), ARRAY_A);
the results being something like this:
array(3) {
["consumer_key"]=>
string(64) "58043812eee6aa75c80407f8eb9cec025825f138eb7d60118af66cf4b38060fa"
["consumer_secret"]=>
string(43) "cs_1da716412bb9680d8b06b09160872b7e54416799"
["permissions"]=>
string(10) "read_write"
}
I am, of course, assuming you are using the API to "loop back" to the current site and not accessing a remote site. Using the WC API to create products even on the current site can be very much more convenient than going through the PHP object API.
I have not yet found any public WC methods to get these details; they are all private and assume only WC needs to know these details.
Yes there is a fine customization that you need to do in your code that is as follows:
Background information:
Each users Consumer Key,Consumer Secret Key and read/write permissions (if WooCommerce API Keys are generated for that users) are stored in wordpress's usermeta table with a meta_keys as 'woocommerce_api_consumer_key', 'woocommerce_api_consumer_secret' and 'woocommerce_api_key_permissions' respectively.
So you just need to get the current users id first then get that user's meta value as mention above assign to some variables and send them as a parameter.
I think the problem is generate programmatically the API keys for that customer for witch you want consume the woocommerce service, because the keys ar owned for each users and there aren't be useful for other users.
My advice is looking admin source code of woocommerce.

How to get stats of multiple campaigns in Facebook ads api

I write the below code for retrieve single campaign stats.
$fields = array(
'start_time','actions','spent','clicks','impressions','end_time',
);
$params = array();
$campaign = new AdCampaign(123456);
$stats = $campaign->getStats($fields, $params);
here I can able to access the stats. But when use this function loop then I got issue like
Calling : $campaign = new AdCampaign($campaign_id);
Error : "An access token is required to request this resource"
But using graph API I can access the multiple campaigns stats at a time
https://graph.facebook.com/stats?ids=123,456,789&fields=start_time,actions,spent,clicks,impressions,end_time&access_token=...
I need it using Ads API .... Please solve it for me..
I think this is a missing feature from the SDK at the moment as you can only access stats relative to an object.
However, calling stats in a loop should not be a problem, assuming you instantiated the API class correctly.
use FacebookAds\Api;
use FacebookAds\Object\AdCampaign;
Api::init($app_id, $app_secret, $access_token);
$campaign_ids = array(...);
$fields = array(
'start_time',
'actions',
'spent',
'clicks',
'impressions',
'end_time',
);
$params = array();
$stats = array();
foreach($campaign_ids as $id) {
$campaign = new AdCampaign($id);
$stats[$id] = $campaign->getStats($fields, $params);
}
You could also just get all stats for all campaigns by using the getAdCampaignStats on AdAccount.

Resources