Pagination with google ads api in php
I am trying to do the pagination with google-ads-php at the bottom of my page in php, so I get through my ads, like PREVIOUS 1,2,3 NEXT So this is my code:
public function runExample(GoogleAdsClient $googleAdsClient, int $customerId){ $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient(); // Creates a query that retrieves all ads. $query = "SELECT campaign.name, ad_group.name, " . "ad_group_ad.ad.responsive_display_ad.marketing_images, " . "ad_group_ad.ad.app_ad.images, ad_group_ad.ad.app_ad.youtube_videos, " . "ad_group_ad.ad.responsive_display_ad.youtube_videos, ad_group_ad.ad.local_ad.videos, " . "ad_group_ad.ad.video_responsive_ad.videos, ad_group_ad.ad.video_ad.media_file, " . "ad_group_ad.ad.app_engagement_ad.images, ad_group_ad.ad.app_engagement_ad.videos, " . "ad_group_ad.ad.display_upload_ad.media_bundle, ad_group_ad.ad.gmail_ad.product_images, " . "ad_group_ad.ad.gmail_ad.product_videos, ad_group_ad.ad.gmail_ad.teaser.logo_image, " . "ad_group_ad.ad.image_ad.image_url, ad_group_ad.ad.legacy_responsive_display_ad.square_marketing_image, " . "ad_group_ad.ad.local_ad.marketing_images, ad_group_ad.ad.responsive_display_ad.logo_images, " . "ad_group_ad.ad.responsive_display_ad.square_logo_images, " . "ad_group_ad.ad.responsive_display_ad.square_marketing_images, " . "ad_group_ad.ad.responsive_display_ad.youtube_videos, " . "metrics.impressions, campaign.campaign_budget, campaign.status, " . "campaign.start_date, campaign.end_date, metrics.all_conversions, " . "metrics.average_cost, ad_group_ad.ad.type, ad_group_ad.ad.id, " . "campaign.campaign_budget, metrics.cost_micros, ad_group_ad.status, metrics.impressions " . "FROM ad_group_ad " . "WHERE segments.date >= '{$this->from}' AND segments.date <= '{$this->to}' " . "ORDER BY campaign.name ASC"; // Issues a search stream request. /** @var GoogleAdsServerStreamDecorator $stream */ $stream = $googleAdsServiceClient->search($customerId, $query, ['pageSize' => 10]); $ads = []; foreach ($stream->iterateAllElements() as $googleAdsRow) { dump($googleAdsRow->serializeToJsonString()); /** @var GoogleAdsRow $googleAdsRow */ $ads[] = json_decode($googleAdsRow->serializeToJsonString(), true); }
As you see the pageSize
is set to 10, so it will be 23 pages, because I have 230 ads.
How can I do the pagination, now the $stream returns all ads in one response. How can return only 10 ads, and then when user click for example second page button, it will return the next 10 ads, and so on?
Thanks in advance!
here is how it can be done in Python though -
import sys from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException client = GoogleAdsClient.load_from_storage() ga_service = client.get_service("GoogleAdsService") search_request = client.get_type("SearchGoogleAdsRequest") try: search_request.query = QUERY_STRING search_request.customer_id = CUSOMER_ID search_request.page_size = PAGE_SIZE df = pd.DataFrame() while True: response = ga_service.search(search_request) dictobj = MessageToDict(response._pb) df = df.append(pd.json_normalize(dictobj,record_path=['results'])) if response.next_page_token == '': break else: search_request.page_token = response.next_page_token except GoogleAdsException as ex: print(ex)While your answer may solve the question, including an explanation of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. You can edit your answer to add explanations and give an indication of what limitations and assumptions apply. - From Review
To achieve pagination, you may slightly change the display.
Say, if you want to display 10 records per page, so for the 2nd page, it will be records 11 to 20.
So , to display page 2, you may revising the part :
foreach ($stream->iterateAllElements() as $googleAdsRow) { dump($googleAdsRow->serializeToJsonString()); /** @var GoogleAdsRow $googleAdsRow */ $ads[] = json_decode($googleAdsRow->serializeToJsonString(), true); }to
$index=0; foreach ($stream->iterateAllElements() as $googleAdsRow) { $index++; if ($index >=11 && $index <=20) { dump($googleAdsRow->serializeToJsonString()); /** @var GoogleAdsRow $googleAdsRow */ $ads[] = json_decode($googleAdsRow->serializeToJsonString(), true); } }Please see whether the above works, and if so, you may amend the codes to show the data according to page number
It is not working, you can see here developers.google.com/google-ads/api/docs/query/… that you can limit only with one number, It is not made for paging.
The limit with 1 parameter and limit with 2 parameters (separated by a comma) are both standard SQL queries. I think google should support both,
LOL, but currently they are not supporting this, so do not confuse people!
Yes :_ ` Error in query: unexpected input`
Thanks I will revise my answer
Google Ads API provides native pagination that as of now is not very well documented. However, you can only paginate by "next" and "previous" pages. Here is a working example on keywords since that's the use case most people probably get stuck upon.
$googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient(); $query = 'SELECT ad_group.id, ' . 'ad_group_criterion.type, ' . 'ad_group_criterion.criterion_id, ' . 'ad_group_criterion.keyword.text, ' . 'ad_group_criterion.keyword.match_type ' . 'FROM ad_group_criterion ' . 'WHERE ad_group_criterion.type = KEYWORD'; // Get the stream $stream = $googleAdsServiceClient->search($customerId, $query, ['pageSize' => 1000]); // Get the first page $page = $stream->getPage(); foreach ($page->getIterator() as $googleAdsRow) { // Iterating over the first page of 1000 keywords. } // Get the next page token $nextPageToken = $page->getNextPageToken(); // Get the second page $page = $stream->getPage(); $stream = $googleAdsServiceClient->search($customerId, $query, ['pageSize' => 1000, 'pageToken' => $nextPageToken]); foreach ($page->getIterator() as $googleAdsRow) { // Iterating over the second page of 1000 keywords. }Note that you have to use search() and not searchStream() and iterator of the actual page instead of iterateAllElements()