Add `alt` parameter while generating reports from AdExchange Seller API - php

I'm trying to retrieve a report from the AdExchange Seller API.
I am using the maximum allowed amount of dimensions and metrics so the reports is quite big (>100.000 rows). According to the documentation on large reports this is possible using the limit break feature by adding the alt=media parameter. But I can't figure out how to add that parameter using the Google API client for PHP. I would prefer to stick to the official Google libraries, but I'm open for suggestions.
Note: adding alt=csv or alt=media to the optParams does not work and I can easily access the data if I remove some of the dimensions and metrics.
More specifically I'm using the accounts_reports resource and then the generate method. Looking at the source code (shown below), I can't see anywhere that it would be able to accept a alt parameter, but I'm obviously missing something.
$this->accounts_reports = new Google_Service_AdExchangeSeller_Resource_AccountsReports(
$this,
$this->serviceName,
'reports',
array(
'methods' => array(
'generate' => array(
'path' => 'accounts/{accountId}/reports',
'httpMethod' => 'GET',
'parameters' => array(
'accountId' => array(
'location' => 'path',
'type' => 'string',
'required' => true,
),
'startDate' => array(
'location' => 'query',
'type' => 'string',
'required' => true,
),
'endDate' => array(
'location' => 'query',
'type' => 'string',
'required' => true,
),
'dimension' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'filter' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'locale' => array(
'location' => 'query',
'type' => 'string',
),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
'metric' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'sort' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'startIndex' => array(
'location' => 'query',
'type' => 'integer',
),
),
),
)
)
);
Digging further I found this statement in the Google_Service_AdExchangeSeller_Resource_AccountsReports class.
Generate an Ad Exchange report based on the report request sent in the query
parameters. Returns the result as JSON; to retrieve output in CSV format
specify "alt=csv" as a query parameter. (reports.generate)
But how exactly would that work? As far as I can figure out, it doesn't.

Not really an answer but to long for a comment.
I don't think you are going to get that to work with the client library. The client libraries are generated via the Discovery Services API. Which gives information about what parameters the API takes. For some reason this alt=csv is not registered in the discovery services for that API. Its there in the description but its not registered as a parameter. So the Client library itself isn't going to build it for you.
You can see the response I am looking at here
An idea would be to make the change to the client library yourself you have the code. While altering the client libraries manually is not ideal it is doable.
Try and add alt and give it a value of CSV.
I don't have enough experience with the inner workings of the PHP client library but you can post this as an issue on their forum. Mention that its not in discovery they may have an easer way of applying a random parameter to the query string. I doubt it but its worth a shot.

This should be possible with the PHP client library. The following example demonstrates how to do it with the Drive API:
$fileId = '0BwwA4oUTeiV1UVNwOHItT0xfa2M';
$content = $driveService->files->get($fileId, array(
'alt' => 'media' ));
https://developers.google.com/drive/v3/web/manage-downloads#examples

Related

Error "(get) unknown parameter: 'personFields'" when following examples in Google People API documentation

I am trying to use the Google People API to add and update my Google contacts. I have set up the API almost verbatim with the example code given in Google's documentation (https://developers.google.com/people/v1/getting-started). I get an error for the following line of code, which again comes verbatim from the documentation:
$profile = $people_service->people->get('people/me', array('personFields' => 'names,emailAddresses'));
The error is as follows:
Fatal error: Uncaught exception 'Google_Exception' with message '(get) unknown parameter: 'personFields'' in /home/danbak15/bakerlegalservicesmo.com/office/google-api-php-client-2.2.0/src/Google/Service/Resource.php:147 Stack trace: #0 /home/danbak15/bakerlegalservicesmo.com/office/google-api-php-client-2.2.0/vendor/google/apiclient-services/src/Google/Service/People/Resource/People.php(52): Google_Service_Resource->call('get', Array, 'Google_Service_...') #1 /home/danbak15/bakerlegalservicesmo.com/office/BLScontacts.php(36): Google_Service_People_Resource_People->get('people/me', Array) #2 {main} thrown in /home/danbak15/bakerlegalservicesmo.com/office/google-api-php-client-2.2.0/src/Google/Service/Resource.php on line 147
I have seen an answer to a similar question (Can't access my profile data when accessing google-people API) suggest using the Google_Service_PeopleService class instead of the Google_Service_People class as called for in the documentation. However, when I try to do this, I get another error:
Fatal error: Uncaught exception 'Google_Service_Exception' with message '{ "error": { "code": 401, "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "errors": [ { "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "domain": "global", "reason": "unauthorized" } ], "status": "UNAUTHENTICATED" } } ' in /home/danbak15/bakerlegalservicesmo.com/office/google-api-php-client-2.2.0/src/Google/Http/REST.php:118 Stack trace: #0 /home/danbak15/bakerlegalservicesmo.com/office/google-api-php-client-2.2.0/src/Google/Http/REST.php(94): Google_Http_REST::decodeHttpResponse(Object(GuzzleHttp\Psr7\Response), Object(GuzzleHttp\Psr7\Request), 'G in /home/danbak15/bakerlegalservicesmo.com/office/google-api-php-client-2.2.0/src/Google/Http/REST.php on line 118
At this point, I am at a total loss. I would like to use Google Contacts to keep track of my contacts and would like to be able to work with Google Contacts via PHP so that I can add them to my database. Can anyone shed any light on this? Thank you in advance for any help!
UPDATE:
I tried moving the page to a local server on my computer (forgetting that Google redirects the page to my website) to see if I could get a different result from a different server. Somehow, magically, it worked when I tried to access the script from my website—for about 15-30 minutes or so. Then, I got the same error as before. If I run the page from my localhost server, I will get caught in an endless authorization redirect loop (to be expected given that Google redirects me to the online page), but then the online page will work for a time.
At this point, I can't begin to guess where the issue is. Does this make sense to anyone else?
This worked fine for me:
$scopes[] = 'https://www.googleapis.com/auth/contacts.readonly';
$client->setScopes($scopes);
$service = new Google_Service_People($client);
$optParams = ['requestMask.includeField' => 'person.names'];
$connections = $service->people_connections->listPeopleConnections('people/me', $optParams)->getConnections();
foreach ($connections as $connection) {
if (!empty($connection->getNames()[0])) {
print $connection->getNames()[0]->getDisplayName() . "\n" . '<br>';
}
}
I guess I know whats happens.
My English not very well so I hope you can understand what I mean..
In my case, I'm using Google_Service_People class (src\Google\Service\People.php) and get same error as you. So I take a look about People.php and see this :
$this->people = new Google_Service_People_Resource_People(
$this,
$this->serviceName,
'people',
array(
'methods' => array(
'get' => array(
'path' => 'v1/{+resourceName}',
'httpMethod' => 'GET',
'parameters' => array(
'resourceName' => array(
'location' => 'path',
'type' => 'string',
'required' => true,
),
'requestMask.includeField' => array( // <= This is the problem.
'location' => 'query',
'type' => 'string',
),
),
),
I check the official document and it say "requestMask.includeField is already DEPRECATED." but it still in api's code by somehow.
So I change it to this :
$this->people = new Google_Service_People_Resource_People(
$this,
$this->serviceName,
'people',
array(
'methods' => array(
'get' => array(
'path' => 'v1/{+resourceName}',
'httpMethod' => 'GET',
'parameters' => array(
'resourceName' => array(
'location' => 'path',
'type' => 'string',
'required' => true,
),
'personFields' => array( // <- Change to 'personFields'
'location' => 'query',
'type' => 'string',
),
),
After that every thing go well.
If you are using Google API Client Libraries from PHP. This client library is in beta. So there something in their api doesn't look like how it exactly is in their api document.
So that is my case. English not my language so I hope you can understand what I trying to describe.
John Rodriguez solved the issue. Thank you! My library is a little bit different, but the problem was the same. In my case I am using the Google_Service_PeopleService class instead of the Google_Service_People class. The path to the file I changed is: google-api-php-client-2.2.0/vendor/google/apiclient-services/src/Google/Service/PeopleService.php. In this case, $this->people is a Google_Service_PeopleService_Resource_People class which contains an array of methods. I commented out the depreciated code. Here is the relevant code:
$this->people = new Google_Service_PeopleService_Resource_People(
$this,
$this->serviceName,
'people',
array(
'methods' => array(
'createContact' => array(
...
),
),
),'deleteContact' => array(
...
),
),
),'get' => array(
'path' => 'v1/{+resourceName}',
'httpMethod' => 'GET',
'parameters' => array(
'resourceName' => array(
'location' => 'path',
'type' => 'string',
'required' => true,
),
'personFields' => array(
'location' => 'query',
'type' => 'string',
),
/* 'requestMask.includeField' => array(
'location' => 'query',
'type' => 'string',
), */
),
),'getBatchGet' => array(
'path' => 'v1/people:batchGet',
'httpMethod' => 'GET',
'parameters' => array(
'personFields' => array(
'location' => 'query',
'type' => 'string',
),
/* 'requestMask.includeField' => array(
'location' => 'query',
'type' => 'string',
), */
'resourceNames' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
),
),'updateContact' => array(
...
),
),
),
So far this has worked as it should, but I have not thoroughly tested it yet. Thank you for your help!

aws SDK 3, PHP, runInstance does not create the supplied Tags

$options = array(
'UserData' => base64_encode('test'),
'SecurityGroupIds' => [AWS_REGIONS[$region]['security_group']],
'InstanceType' => AWS_REGIONS[$region]['instance_type'],
'ImageId' => AWS_REGIONS[$region]['ami'],
'MaxCount' => $to_launch,
'MinCount' => 1,
//'EbsOptimized' => true,
'SubnetId' => AWS_REGIONS[$region]['subnet_id'],
'Tags' => [['Key' => 'task', 'Value' => $task],['Key' => 'Name', 'Value' => $task]],
'InstanceInitiatedShutdownBehavior' => 'terminate'
);
$response = $client->runInstances($options);
I am using the "latest" Ec2Client
It launches fine but the Tags are completely ignored.
I suspect an error within the EC2 API but I am not that experienced.
Maybe someone with experience can help me out ?
This is because Ec2Client::runInstances does not have tags option
http://docs.aws.amazon.com/aws-sdk-php/v3/api/api-ec2-2015-10-01.html#runinstances
You would need to make a separate call to tag newly created instance(s) using Ec2Client::createTags:
$result = $client->createTags(array(
'DryRun' => true || false,
// Resources is required
'Resources' => array('string', ... ),
// Tags is required
'Tags' => array(
array(
'Key' => 'string',
'Value' => 'string',
),
// ... repeated
),
));
Read more here:
http://docs.aws.amazon.com/aws-sdk-php/v3/api/api-ec2-2015-10-01.html#createtags

CGridView Filter duplicate Ajax requests when using Tabs

In my web application I use tabs and load part of the views per Ajax. So it's possible, that I do load the same CGridView multiple times without reloading the page. If that occurs I become duplicate Ajax requests if I use CGridView Filters.
The filters and requests are standard. Following images show those simple filter and 10 GET requests if type the search value once.
Here is the code of Tabs-widget I use:
$this->widget('bootstrap.widgets.TbTabs', array(
'id' => 'thirdPartyCatTabs',
'title' => Translate::t('project', 'Categories'),
'type' => 'tabs',
'placement' => 'top',
'events' => array(
'shown' => 'js:loadContent'
),
'tabs' => array(
array(
'id' => 'standardCat',
'label' => Translate::t('project', 'Standard Categories'),
'linkOptions' => array(
'data-tab-url' => Yii::app()->createUrl('/thirdParty/settings/thirdPartyCategoryStandard'),
),
),
array(
'id' => 'standardCatMap',
'label' => Translate::t('project', 'Standard Category-Mapping'),
'linkOptions' => array(
'data-tab-url' => Yii::app()->createUrl('/thirdParty/settings/showCategoryMapTab'),
),
),
)
));
I guess I have to use uniqid() at some place, but can't figure out where.
Thanks.

Nested Parameters/Values in POST Requests

I have been thinking about a good way to handle nested/complex values in POST requests to a apigility resource.
For example, an order might contain a collection of order items in a single POST requested that is used to create an order. Both, order and order-item do exist as a resource. However, I would very much like to have only one request that would create order and order item entities. Handling that in the resource is not a problem, but I wonder how you would configure that resource (let´s call it order-place) using the apigiliy UI - or, if at all impossible, using the configuration. Applying validators and filters is one of the key features of apigility, and i´d like to keep using that, even for complex request data.
And before you ask, using an underscore to separate the values scopes, for example order_comment and order_item_comment should not be an option.
Any ideas?:)
Addition: A sample json request payload could look like this:
{
"created_at": "2000-01-01",
"amount" : "5000.00",
"address" : {
"name": "some name",
"street": "some street"
...
},
"items" : [
{"productId":99,"qty":1}
...
]
}
Starting from Wilt's answer, I've found that the following code works as well:
# file path: /module/MyApi/config/module.config.php
// some other stuff
'MyApi\\V1\\Rest\\MyRestService\\Validator' => array(
'address' => array(
0 => array(
'name' => 'name',
'required' => true,
'filters' => array(),
'validators' => array(),
),
1 => array(
'name' => 'street',
'required' => true,
'filters' => array(),
'validators' => array(),
),
'type' => 'Zend\InputFilter\InputFilter'
),
'amount' => array(
'name' => 'amount',
'required' => true,
'filters' => array(),
'validators' => array()
)
The only problem I get is when address is passed as a field (string or numeric) rather then an array or object. In this case Apigility throws an exception:
Zend\InputFilter\Exception\InvalidArgumentException: Zend\InputFilter\BaseInputFilter::setData expects an array or Traversable argument; received string in /var/www/api/vendor/zendframework/zendframework/library/Zend/InputFilter/BaseInputFilter.php on line 175
Adding address as a further simple (required) field avoids the exception, but then Apigility doesn't see any difference whether we pass address as an array of name and street or a dummy string.
If you are using the ContentValidation module then you can configure an input filter for the nested resources by assigning it to a variable. Then you have to add a type key (essential otherwise reusing the filter won't work). Now you are able to use this variable in your input_filter_specs and you can reuse the whole filter inside another filter. So something like this in your config.php:
<?php
namespace Application;
// Your address config as if it was used independently
$addressInputFilter => array(
'name' => array(
'name' => 'name',
'required' => true,
'filters' => array(
//...
)
'validators' => array(
//...
)
),
'street' => array(
'name' => 'street',
'required' => true,
'filters' => array(
//...
)
'validators' => array(
//...
)
),
// 'type' key necessary for reusing this input filter in other configs
'type' => 'Zend\InputFilter\InputFilter'
),
'input_filter_specs' => array(
// The key for your address if you also want to be able to use it independently
'Application\InputFilter\Address'=> $addressInputFilter,
// The key and config for your other resource containing a nested address
'Application\InputFilter\ItemContainingAddress'=> array(
'address' => $addressInputFilter,
'amount' => array(
'name' => 'amount',
'required' => true,
'filters' => array(
//...
),
'validators' => array(
//...
)
)
//... your other fields
)
)

Update TTL in existing Route53 Resource Record set

I have few A records in my Route53 Account. I want to bulk update the TTL for all of them.
The logic I'm using is that I get all the records using "ListResourceRecordSets" operation. Create following change object for each record.
array(
'Action' => 'UPSERT',
'ResourceRecordSet' => array(
'Name' => OLD_CNAME,
'Type' => 'A',
'TTL' => NEW_TTL,
'ResourceRecords' => array(array(
'Value' => OLD_IP
)),
));
Then I send a "ChangeResourceRecordSets" request with change objects created in last step.
Route53 is returning this error Validation errors: [ChangeBatch][Changes][0][Change][Action] must be one of "CREATE" or "DELETE" [ChangeBatch][Changes][1][Change][Action] must be one of "CREATE" or "DELETE" )
P.S. I couldn't find any UPSERT example for ChangeResourceRecordSets call.
Either update your AWS SDK to a later version that supports UPSERT or You first have to delete the record set(s) and then add them with the new changes.
UPSERT was added in early 2014: https://aws.amazon.com/blogs/aws/new-features-for-route-53-improved-health-checks-https-record-modification/
So you must have a really old SDK.
To do it without UPSERT:
array(
'Action' => 'DELETE',
'ResourceRecordSet' => array(
'Name' => OLD_CNAME,
'Type' => 'A',
'TTL' => OLD_TTL,
'ResourceRecords' => array(array(
'Value' => OLD_IP
)),
));
and then:
array(
'Action' => 'CREATE',
'ResourceRecordSet' => array(
'Name' => OLD_CNAME,
'Type' => 'A',
'TTL' => NEW_TTL,
'ResourceRecords' => array(array(
'Value' => OLD_IP
)),
));

Categories