def main(client, campaign_id):
    # Initialize appropriate services.
    shared_set_service = client.GetService('SharedSetService',
                                           version='v201806')
    shared_criterion_service = client.GetService('SharedCriterionService',
                                                 version='v201806')
    campaign_shared_set_service = client.GetService('CampaignSharedSetService',
                                                    version='v201806')

    # Keywords to create a shared set of.
    keywords = ['mars cruise', 'mars hotels']
    # Create shared negative keyword set.
    shared_set = {
        'name': 'API Negative keyword list - %d' % uuid.uuid4(),
        'type': 'NEGATIVE_KEYWORDS'
    }

    # Add shared set.
    operations = [{'operator': 'ADD', 'operand': shared_set}]

    response = shared_set_service.mutate(operations)

    if response and response['value']:
        shared_set = response['value'][0]
        shared_set_id = shared_set['sharedSetId']

        print 'Shared set with ID %d and name "%s" was successfully added.' % (
            shared_set_id, shared_set['name'])
    else:
        raise errors.GoogleAdsError('No shared set was added.')

        # Add negative keywords to shared set.
    shared_criteria = [{
        'criterion': {
            'xsi_type': 'Keyword',
            'text': keyword,
            'matchType': 'BROAD'
        },
        'negative': True,
        'sharedSetId': shared_set_id
    } for keyword in keywords]

    operations = [{
        'operator': 'ADD',
        'operand': criterion
    } for criterion in shared_criteria]

    response = shared_criterion_service.mutate(operations)

    if 'value' in response:
        for shared_criteria in response['value']:
            print 'Added shared criterion ID %d "%s" to shared set with ID %d.' % (
                shared_criteria['criterion']['id'],
                shared_criteria['criterion']['text'],
                shared_criteria['sharedSetId'])
    else:
        raise errors.GoogleAdsError('No shared keyword was added.')

        # Attach the articles to the campaign.
    campaign_set = {'campaignId': campaign_id, 'sharedSetId': shared_set_id}

    operations = [{'operator': 'ADD', 'operand': campaign_set}]

    response = campaign_shared_set_service.mutate(operations)

    if 'value' in response:
        print 'Shared set ID %d was attached to campaign ID %d' % (
            response['value'][0]['sharedSetId'],
            response['value'][0]['campaignId'])
    else:
        raise errors.GoogleAdsError('No campaign shared set was added.')
Example #2
0
def main(client, campaign_id):
    # Initialize appropriate services.
    campaign_extension_setting_service = client.GetService(
        'CampaignExtensionSettingService', version='v201509')
    customer_service = client.GetService('CustomerService', version='v201509')

    customer_tz = timezone(customer_service.get()['dateTimeZone'])
    time_fmt = '%s %s' % ('%Y%m%d %H%M%S', customer_tz)

    # Create the sitelinks
    sitelink1 = {
        'xsi_type': 'SitelinkFeedItem',
        'sitelinkText': 'Store Hours',
        'sitelinkFinalUrls': {
            'urls': ['http://www.example.com/storehours']
        }
    }

    # Show the Thanksgiving specials link only from 20 - 27 Nov.
    sitelink2 = {
        'xsi_type':
        'SitelinkFeedItem',
        'sitelinkText':
        'Thanksgiving Specials',
        'sitelinkFinalUrls': {
            'urls': ['http://www.example.com/thanksgiving']
        },
        # The time zone of the start and end date/times must match the time zone
        # of the customer.
        'startTime':
        datetime(datetime.now().year, 11, 20, 0, 0, 0, 0,
                 customer_tz).strftime(time_fmt),
        'endTime':
        datetime(datetime.now().year, 11, 27, 23, 59, 59, 59,
                 customer_tz).strftime(time_fmt)
    }

    # Show the wifi details primarily for high end mobile users.
    sitelink3 = {
        'xsi_type': 'SitelinkFeedItem',
        'sitelinkText': 'Wifi Available',
        'sitelinkFinalUrls': {
            'urls': ['http://www.example.com/mobile/wifi']
        },
        # See https://developers.google.com/adwords/api/docs/appendix/platforms
        # for device criteria IDs.
        'devicePreference': {
            'devicePreference': '30001'
        }
    }

    # Show the happy hours link only during Mon - Fri 6PM to 9PM.
    sitelink4 = {
        'xsi_type': 'SitelinkFeedItem',
        'sitelinkText': 'Happy hours',
        'sitelinkFinalUrls': {
            'urls': ['http://www.example.com/happyhours']
        },
        'scheduling': {
            'feedItemSchedules':
            [{
                'dayOfWeek': day,
                'startHour': '18',
                'startMinute': 'ZERO',
                'endHour': '21',
                'endMinute': 'ZERO'
            } for day in
             ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY']]
        }
    }

    # Create your Campaign Extension Settings. This associates the sitelinks
    # to your campaign.
    campaign_extension_setting = {
        'campaignId': campaign_id,
        'extensionType': 'SITELINK',
        'extensionSetting': {
            'extensions': [sitelink1, sitelink2, sitelink3, sitelink4]
        }
    }

    operation = {'operator': 'ADD', 'operand': campaign_extension_setting}

    # Add the extensions.
    response = campaign_extension_setting_service.mutate([operation])

    if 'value' in response:
        print(
            'Extension setting with type "%s" was added to campaignId "%d".' %
            (response['value'][0]['extensionType'],
             response['value'][0]['campaignId']))
    else:
        raise errors.GoogleAdsError('No extension settings were added.')
def main(client, ad_group_id):
    # Initialize appropriate service.
    mutate_job_service = client.GetService('MutateJobService',
                                           version='v201509')

    # Create list of all operations for the job.
    operations = []

    # Create AdGroupCriterionOperations to add keywords.
    for i in range(KEYWORD_NUMBER):
        keyword = 'mars%d' % i
        if random.randint(1, 10) == 1:
            keyword += '!!!'
        operations.append({
            'xsi_type': 'AdGroupCriterionOperation',
            'operator': 'ADD',
            'operand': {
                'xsi_type': 'BiddableAdGroupCriterion',
                'adGroupId': ad_group_id,
                'criterion': {
                    'xsi_type': 'Keyword',
                    'matchType': 'BROAD',
                    'text': keyword
                }
            }
        })

    # You can specify up to 3 job IDs that must successfully complete before
    # this job can be processed.
    policy = {'prerequisiteJobIds': []}

    # Call mutate to create a new job.
    response = mutate_job_service.mutate(operations, policy)

    if not response:
        raise errors.GoogleAdsError('Failed to submit a job; aborting.')

    job_id = response['id']
    print 'Job with ID %s was successfully created.' % job_id

    # Create selector to retrieve job status and wait for it to complete.
    selector = {'xsi_type': 'BulkMutateJobSelector', 'jobIds': [job_id]}

    time.sleep(RETRY_INTERVAL)
    # Poll for job status until it's finished.
    print 'Retrieving job status...'
    for i in range(RETRIES_COUNT):
        job_status_response = mutate_job_service.get(selector)
        status = job_status_response[0]['status']
        if status in ('COMPLETED', 'FAILED'):
            break
        print('[%d] Current status is \'%s\', waiting %d seconds to retry...' %
              (i, status, RETRY_INTERVAL))
        time.sleep(RETRY_INTERVAL)

    if status == 'FAILED':
        raise errors.GoogleAdsError('Job failed with reason: \'%s\'' %
                                    job_status_response[0]['failure_reason'])
    if status in ('PROCESSING', 'PENDING'):
        raise errors.GoogleAdsError('Job did not complete within %d seconds' %
                                    (RETRY_INTERVAL * (RETRIES_COUNT - 1)))

    # Status must be COMPLETED.
    # Get the job result. Here we re-use the same selector.
    result_response = mutate_job_service.getResult(selector)

    # Output results.
    index = 0
    for result in result_response['SimpleMutateResult']['results']:
        if 'PlaceHolder' in result:
            print 'Operation [%d] - FAILED' % index
        else:
            print 'Operation [%d] - SUCCEEDED' % index
        index += 1

    # Output errors
    for error in result_response['SimpleMutateResult']['errors']:
        index = int(re.search(INDEX_REGEX, error['fieldPath']).group(1))
        reason = error['reason']
        keyword = operations[index]['operand']['criterion']['text']
        print('ERROR - keyword \'%s\' failed due to \'%s\'' %
              (keyword, reason))
Example #4
0
def main(client, places_email_address, places_access_token):
    # Create a feed that will sync to the Google Places account specified by
    # places_email_address. Do not add FeedAttributes to this object,
    # as AdWords will add them automatically because this will be a
    # system generated feed.
    feed = {
        'name': 'Places feed #%s' % uuid.uuid4(),
        'systemFeedGenerationData': {
            'xsi_type': 'PlacesLocationFeedData',
            'oAuthInfo': {
                'httpMethod': 'GET',
                'httpRequestUrl': 'https://www.google.com/local/add',
                'httpAuthorizationHeader': 'Bearer %s' % places_access_token
            },
            'emailAddress': places_email_address,
        },
        # Since this feed's feed items will be managed by AdWords, you must set
        # its origin to ADWORDS.
        'origin': 'ADWORDS'
    }

    # Create an operation to add the feed.
    places_operations = [{'operator': 'ADD', 'operand': feed}]

    places_response = client.GetService(
        'FeedService', version='v201409').mutate(places_operations)
    added_feed = places_response['value'][0]
    print 'Added places feed with ID: %d\n' % added_feed['id']

    # Add a CustomerFeed that associates the feed with this customer for the
    # LOCATION placeholder type.
    customer_feed = {
        'feedId': added_feed['id'],
        'placeholderTypes': [PLACEHOLDER_LOCATION],
        'matchingFunction': {
            'operator': 'IDENTITY',
            'lhsOperand': {
                'xsi_type': 'FunctionArgumentOperand',
                'type': 'BOOLEAN',
                'booleanValue': True
            }
        }
    }

    customer_feed_operation = {
        'xsi_type': 'CustomerFeedOperation',
        'operator': 'ADD',
        'operand': customer_feed
    }

    customer_feed_service = client.GetService('CustomerFeedService',
                                              version='v201409')
    added_customer_feed = None

    i = 0
    while i < MAX_CUSTOMER_FEED_ADD_ATTEMPTS and added_customer_feed is None:
        try:
            added_customer_feed = customer_feed_service.mutate(
                [customer_feed_operation])['value'][0]
        except suds.WebFault:
            # Wait using exponential backoff policy
            sleep_seconds = 2**i
            print(
                'Attempt %d to add the CustomerFeed was not successful.'
                'Waiting %d seconds before trying again.\n' %
                (i, sleep_seconds))
            time.sleep(sleep_seconds)
        i += 1

    if added_customer_feed is None:
        raise errors.GoogleAdsError(
            'Could not create the CustomerFeed after %s attempts. Please retry the '
            'CustomerFeed ADD operation later.' %
            MAX_CUSTOMER_FEED_ADD_ATTEMPTS)

    print('Added CustomerFeed for feed ID %d and placeholder type %d\n' %
          (added_customer_feed['id'], added_customer_feed['placeholderTypes']))
def main(client, campaign_id):
    # Initialize appropriate service.
    feed_service = client.GetService('FeedService', version='v201607')
    feed_item_service = client.GetService('FeedItemService', version='v201607')
    feed_mapping_service = client.GetService('FeedMappingService',
                                             version='v201607')
    campaign_feed_service = client.GetService('CampaignFeedService',
                                              version='v201607')

    sitelinks_data = {}

    # Create site links feed first.
    site_links_feed = {
        'name':
        'Feed For Site Links #%s' % uuid.uuid4(),
        'attributes': [{
            'type': 'STRING',
            'name': 'Link Text'
        }, {
            'type': 'URL_LIST',
            'name': 'Link Final URLs'
        }, {
            'type': 'STRING',
            'name': 'Line 2 Description'
        }, {
            'type': 'STRING',
            'name': 'Line 3 Description'
        }]
    }

    response = feed_service.mutate([{
        'operator': 'ADD',
        'operand': site_links_feed
    }])

    if 'value' in response:
        feed = response['value'][0]
        link_text_feed_attribute_id = feed['attributes'][0]['id']
        final_url_feed_attribute_id = feed['attributes'][1]['id']
        line_2_feed_attribute_id = feed['attributes'][2]['id']
        line_3_feed_attribute_id = feed['attributes'][3]['id']
        print('Feed with name \'%s\' and ID \'%s\' was added with' %
              (feed['name'], feed['id']))
        print('\tText attribute ID \'%s\' and Final URL attribute ID \'%s\'.' %
              (link_text_feed_attribute_id, final_url_feed_attribute_id))
        print('\tLine 2 attribute ID \'%s\' and Line 3 attribute ID \'%s\'.' %
              (line_2_feed_attribute_id, line_3_feed_attribute_id))
        sitelinks_data['feedId'] = feed['id']
        sitelinks_data['linkTextFeedId'] = link_text_feed_attribute_id
        sitelinks_data['finalUrlFeedId'] = final_url_feed_attribute_id
        sitelinks_data['line2FeedId'] = line_2_feed_attribute_id
        sitelinks_data['line3FeedId'] = line_3_feed_attribute_id
    else:
        raise errors.GoogleAdsError('No feeds were added.')

    # Create site links feed items.
    items_data = [{
        'text': 'Home',
        'finalUrls': 'http://www.example.com',
        'line2': 'Home line 2',
        'line3': 'Home line 3'
    }, {
        'text': 'Stores',
        'finalUrls': 'http://www.example.com/stores',
        'line2': 'Stores line 2',
        'line3': 'Stores line 3'
    }, {
        'text': 'On Sale',
        'finalUrls': 'http://www.example.com/sale',
        'line2': 'On Sale line 2',
        'line3': 'On Sale line 3'
    }, {
        'text': 'Support',
        'finalUrls': 'http://www.example.com/support',
        'line2': 'Support line 2',
        'line3': 'Support line 3'
    }, {
        'text': 'Products',
        'finalUrls': 'http://www.example.com/products',
        'line2': 'Products line 2',
        'line3': 'Products line 3'
    }, {
        'text': 'About Us',
        'finalUrls': 'http://www.example.com/about',
        'line2': 'About line 2',
        'line3': 'About line 3',
        'locationId': '21137'
    }]

    feed_items = []
    for item in items_data:
        feed_item = {
            'feedId':
            sitelinks_data['feedId'],
            'attributeValues': [{
                'feedAttributeId':
                sitelinks_data['linkTextFeedId'],
                'stringValue':
                item['text']
            }, {
                'feedAttributeId':
                sitelinks_data['finalUrlFeedId'],
                'stringValues': [item['finalUrls']]
            }, {
                'feedAttributeId':
                sitelinks_data['line2FeedId'],
                'stringValue':
                item['line2']
            }, {
                'feedAttributeId':
                sitelinks_data['line3FeedId'],
                'stringValue':
                item['line3']
            }],
            # Optional: use the 'startTime' and 'endTime' keys to specify the time
            # period for the feed to deliver.  The example below will make the feed
            # start now and stop in one month.
            # Make sure you specify the datetime in the customer's time zone. You
            # can retrieve this from customer['dateTimeZone'].
            #
            # ['startTime']: datetime.datetime.now().strftime('%Y%m%d %H%M%S')
            # ['endTime']: (datetime.datetime.now() +
            #               relativedelta(months=1)).strftime('%Y%m%d %H%M%S')
        }

        # Use geographical targeting on a feed.
        # The IDs can be found in the documentation or retrieved with the
        # LocationCriterionService.
        if 'locationId' in item:
            feed_item['geoTargeting'] = {'id': item['locationId']}
            feed_item['geoTargetingRestriction'] = {
                'geoRestriction': 'LOCATION_OF_PRESENCE'
            }

        feed_items.append(feed_item)

    feed_items_operations = [{
        'operator': 'ADD',
        'operand': item
    } for item in feed_items]

    response = feed_item_service.mutate(feed_items_operations)
    if 'value' in response:
        sitelinks_data['feedItemIds'] = []
        for feed_item in response['value']:
            print 'Feed item with ID %s was added.' % feed_item['feedItemId']
            sitelinks_data['feedItemIds'].append(feed_item['feedItemId'])
    else:
        raise errors.GoogleAdsError('No feed items were added.')

    # Create site links feed mapping.

    feed_mapping = {
        'placeholderType':
        PLACEHOLDER_SITELINKS,
        'feedId':
        sitelinks_data['feedId'],
        'attributeFieldMappings': [{
            'feedAttributeId':
            sitelinks_data['linkTextFeedId'],
            'fieldId':
            PLACEHOLDER_FIELD_SITELINK_LINK_TEXT
        }, {
            'feedAttributeId':
            sitelinks_data['finalUrlFeedId'],
            'fieldId':
            PLACEHOLDER_FIELD_SITELINK_FINAL_URLS
        }, {
            'feedAttributeId':
            sitelinks_data['line2FeedId'],
            'fieldId':
            PLACEHOLDER_FIELD_LINE_2_TEXT
        }, {
            'feedAttributeId':
            sitelinks_data['line3FeedId'],
            'fieldId':
            PLACEHOLDER_FIELD_LINE_3_TEXT
        }]
    }

    response = feed_mapping_service.mutate([{
        'operator': 'ADD',
        'operand': feed_mapping
    }])
    if 'value' in response:
        feed_mapping = response['value'][0]
        print(
            'Feed mapping with ID %s and placeholder type %s was saved for feed'
            ' with ID %s.' %
            (feed_mapping['feedMappingId'], feed_mapping['placeholderType'],
             feed_mapping['feedId']))
    else:
        raise errors.GoogleAdsError('No feed mappings were added.')

    # Construct a matching function that associates the sitelink feeditems to the
    # campaign, and set the device preference to Mobile. For more details, see the
    # matching function guide:
    # https://developers.google.com/adwords/api/docs/guides/feed-matching-functions
    matching_function_string = (
        'AND(IN(FEED_ITEM_ID, {%s}), EQUALS(CONTEXT.DEVICE, \'Mobile\'))' %
        re.sub(r'\[|\]|L', '', str(sitelinks_data['feedItemIds'])))

    campaign_feed = {
        'feedId': sitelinks_data['feedId'],
        'campaignId': campaign_id,
        'matchingFunction': {
            'functionString': matching_function_string
        },
        # Specifying placeholder types on the CampaignFeed allows the same feed
        # to be used for different placeholders in different Campaigns.
        'placeholderTypes': [PLACEHOLDER_SITELINKS]
    }

    response = campaign_feed_service.mutate([{
        'operator': 'ADD',
        'operand': campaign_feed
    }])
    if 'value' in response:
        campaign_feed = response['value'][0]
        print('Campaign with ID %s was associated with feed with ID %s.' %
              (campaign_feed['campaignId'], campaign_feed['feedId']))
    else:
        raise errors.GoogleAdsError('No campaign feeds were added.')
def main(client, adgroup_id):
    # Initialize appropriate service.
    adgroup_ad_service = client.GetService('AdGroupAdService',
                                           version='v201509')

    # Create the text ad
    text_ad = {
        'xsi_type':
        'TextAd',
        'headline':
        'Luxury Cruise to Mars',
        'description1':
        'Visit the Red Planet in style.',
        'description2':
        'Low-gravity fun for everyone!',
        'displayUrl':
        'www.example.com',
        # Specify a tracking URL for 3rd party tracking provider. You may specify
        # one at customer, campaign, ad group, ad, criterion or feed item levels.
        'trackingUrlTemplate': ('http://tracker.example.com/?season={_season}'
                                '&promocode={_promocode}&u={lpurl}'),
        'urlCustomParameters': {
            'parameters': [
                # Since your tracking URL has two custom parameters, provide
                # their values too. This can be provided at campaign, ad group,
                # ad, criterion, or feed item levels.
                {
                    'key': 'season',
                    'value': 'christmas'
                },
                {
                    'key': 'promocode',
                    'value': 'NYC123'
                }
            ]
        },
        # Specify a list of final URLs. This field cannot be set if URL
        # field is set, or finalUrls is unset. This may be specified at ad,
        # criterion, and feed item levels.
        'finalUrls': [
            'http://www.example.com/cruise/space/',
            'http://www.example.com/locations/mars/'
        ],
        # Specify a list of final mobile URLs. This field cannot be set if URL
        # field is set, or finalUrls is unset. This may be specified at ad,
        # criterion, and feed item levels.
        'finalMobileUrls': [
            'http://mobile.example.com/cruise/space/',
            'http://mobile.example.com/locations/mars/'
        ]
    }

    text_adgroup_ad = {
        'adGroupId': adgroup_id,
        'ad': text_ad,
        # Optional: Set the status.
        'status': 'PAUSED'
    }

    operations = [{'operator': 'ADD', 'operand': text_adgroup_ad}]

    response = adgroup_ad_service.mutate(operations)

    if 'value' in response:
        for adgroup_ad in response['value']:
            print('AdGroupAd with ID %s and display URL \'%s\'was added.' %
                  (adgroup_ad['ad']['id'], adgroup_ad['ad']['displayUrl']))
            print 'Upgraded URL properties:'
            print 'Final Urls: %s' % adgroup_ad['ad']['finalUrls']
            print 'Final Mobile URLs: %s' % adgroup_ad['ad']['finalMobileUrls']
            print('Tracking URL template: %s' %
                  adgroup_ad['ad']['trackingUrlTemplate'])
            print 'Custom parameters: %s' % adgroup_ad['ad'][
                'urlCustomParameters']
    else:
        raise errors.GoogleAdsError('Failed to create AdGroupAd.')
Example #7
0
def main(client, campaign_id):
  # Initialize appropriate service.
  customer_extension_setting_service = client.GetService(
      'CustomerExtensionSettingService', 'v201705')

  # To create a price extension, at least three table rows are needed.
  table_rows = [
      CreatePriceTableRow('Scrubs', 'Body Scrub, Salt Scrub',
                          'https://www.example.com/scrubs',
                          60 * MICROS_PER_DOLLAR, 'USD', 'PER_HOUR',
                          final_mobile_url='http://m.example.com/scrubs'),
      CreatePriceTableRow('Hair Cuts', 'Once a month',
                          'https://www.example.com/haircuts',
                          75 * MICROS_PER_DOLLAR, 'USD', 'PER_MONTH',
                          final_mobile_url='http://m.example.com/haircuts'),
      CreatePriceTableRow('Skin Care Package', 'Four times a month',
                          'https://www.examples.com/skincarepackage',
                          250 * MICROS_PER_DOLLAR, 'USD', 'PER_MONTH',
                          final_mobile_url=(
                              'http://m.example.com/skincarepackage'))
  ]

  # Create the price extension feed item.
  customer_extension_setting = {
      'extensionType': 'PRICE',
      'extensionSetting': {
          'extensions': [{
              'priceExtensionType': 'SERVICES',
              'trackingUrlTemplate': 'http://tracker.example.com/?u={lpurl}',
              'language': 'en',
              'campaignTargeting': {
                  'TargetingCampaignId': campaign_id
              },
              'scheduling': {
                  'feedItemSchedules': [
                      {
                          'dayOfWeek': 'SATURDAY',
                          'startHour': 10,
                          'startMinute': 'ZERO',
                          'endHour': 22,
                          'endMinute': 'ZERO'
                      },
                      {
                          'dayOfWeek': 'SUNDAY',
                          'startHour': 10,
                          'startMinute': 'ZERO',
                          'endHour': 18,
                          'endMinute': 'ZERO'
                      }
                  ]
              },
              'tableRows': table_rows,
              # Price qualifier is optional.
              'priceQualifier': 'FROM',
              'xsi_type': 'PriceFeedItem'
          }]
      }
  }

  # Create an operation to add the feed.
  operations = [{
      'operator': 'ADD',
      'operand': customer_extension_setting
  }]

  # Add the price extension.
  response = customer_extension_setting_service.mutate(operations)

  # Print the results.
  if 'value' in response:
    print ('Extension setting with type "%s" was added to your account.'
           % response['value'][0]['extensionType'])
  else:
    raise errors.GoogleAdsError('No extension settings were added.')
Example #8
0
def main(client, campaign_id):
  # Initialize appropriate services.
  campaign_extension_setting_service = client.GetService(
      'CampaignExtensionSettingService', version='v201609')
  customer_service = client.GetService('CustomerService', version='v201609')
  # Find the matching customer and its time zone. The getCustomers method will
  # return a single Customer object corresponding to the configured
  # clientCustomerId.
  customer = customer_service.getCustomers()[0]
  customer_tz = timezone(customer['dateTimeZone'])
  time_fmt = '%s %s' % ('%Y%m%d %H%M%S', customer_tz)

  print ('Found customer ID %d with time zone "%s".'
         % (customer['customerId'], customer['dateTimeZone']))

  # Create the sitelinks
  sitelink1 = {
      'xsi_type': 'SitelinkFeedItem',
      'sitelinkText': 'Store Hours',
      'sitelinkFinalUrls': {'urls': ['http://www.example.com/storehours']}
  }

  # Show the Thanksgiving specials link only from 20 - 27 Nov.
  sitelink2 = {
      'xsi_type': 'SitelinkFeedItem',
      'sitelinkText': 'Thanksgiving Specials',
      'sitelinkFinalUrls': {'urls': ['http://www.example.com/thanksgiving']},
      # The time zone of the start and end date/times must match the time zone
      # of the customer.
      'startTime': datetime(datetime.now().year, 11, 20, 0, 0, 0, 0,
                            customer_tz).strftime(time_fmt),
      'endTime': datetime(datetime.now().year, 11, 27, 23, 59, 59, 59,
                          customer_tz).strftime(time_fmt),
      # Target this sitelink for United States only. For valid geolocation
      # codes, see:
      # https://developers.google.com/adwords/api/docs/appendix/geotargeting
      'geoTargeting': {'id': 2840},
      # Restrict targeting only to people physically within the United States.
      # Otherwise, this could also show to people interested in the United
      # States, but not physically located there.
      'geoTargetingRestriction': {
          'geoRestriction': 'LOCATION_OF_PRESENCE'
      }
  }

  # Show the wifi details primarily for high end mobile users.
  sitelink3 = {
      'xsi_type': 'SitelinkFeedItem',
      'sitelinkText': 'Wifi Available',
      'sitelinkFinalUrls': {'urls': ['http://www.example.com/mobile/wifi']},
      # See https://developers.google.com/adwords/api/docs/appendix/platforms
      # for device criteria IDs.
      'devicePreference': {'devicePreference': '30001'},
      # Target this sitelink only when the ad is triggered by the keyword
      # "free wifi."
      'keywordTargeting': {
          'text': 'free wifi',
          'matchType': 'BROAD'
      }
  }

  # Show the happy hours link only during Mon - Fri 6PM to 9PM.
  sitelink4 = {
      'xsi_type': 'SitelinkFeedItem',
      'sitelinkText': 'Happy hours',
      'sitelinkFinalUrls': {'urls': ['http://www.example.com/happyhours']},
      'scheduling': {
          'feedItemSchedules': [
              {
                  'dayOfWeek': day,
                  'startHour': '18',
                  'startMinute': 'ZERO',
                  'endHour': '21',
                  'endMinute': 'ZERO'
              } for day in ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY',
                            'FRIDAY']
          ]
      }
  }

  # Create your Campaign Extension Settings. This associates the sitelinks
  # to your campaign.
  campaign_extension_setting = {
      'campaignId': campaign_id,
      'extensionType': 'SITELINK',
      'extensionSetting': {
          'extensions': [sitelink1, sitelink2, sitelink3, sitelink4]
      }
  }

  operation = {
      'operator': 'ADD',
      'operand': campaign_extension_setting
  }

  # Add the extensions.
  response = campaign_extension_setting_service.mutate([operation])

  if 'value' in response:
    print ('Extension setting with type "%s" was added to campaignId "%d".' %
           (response['value'][0]['extensionType'],
            response['value'][0]['campaignId']))
  else:
    raise errors.GoogleAdsError('No extension settings were added.')
Example #9
0
 def testGoogleAdsError(self):
     """Coverage test only for the GoogleAdsError class."""
     errors.GoogleAdsError('error message')
Example #10
0
def change_bids(client, ad_group_id, criterion_id, new_bid, length):
    RETRY_INTERVAL = 10
    RETRIES_COUNT = 30
    # Initialize appropriate service.
    mutate_job_service = client.GetService('MutateJobService',
                                           version='v201409')

    # Create list of all operations for the job.
    operations = []

    # Create AdGroupCriterionOperations to change keywords.
    for x in range(0, length):
        operations.append({
            'xsi_type': 'AdGroupCriterionOperation',
            'operator': 'SET',
            'operand': {
                'xsi_type': 'BiddableAdGroupCriterion',
                'adGroupId': ad_group_id[x],
                'criterion': {
                    'id': criterion_id[x],
                },
                'biddingStrategyConfiguration': {
                    'bids': [{
                        'xsi_type': 'CpcBid',
                        'bid': {
                            'microAmount': new_bid[x]
                        }
                    }]
                }
            }
        })

    # You can specify up to 3 job IDs that must successfully complete before
    # this job can be processed.
    policy = {'prerequisiteJobIds': []}
    # Call mutate to create a new job.

    response = mutate_job_service.mutate(operations, policy)

    if not response:
        raise errors.GoogleAdsError('Failed to submit a job; aborting.')
    job_id = response['id']
    print 'Job with ID %s was successfully created.' % job_id

    # Create selector to retrieve job status and wait for it to complete.
    selector = {'xsi_type': 'BulkMutateJobSelector', 'jobIds': [job_id]}

    time.sleep(RETRY_INTERVAL)
    # Poll for job status until it's finished.
    print 'Retrieving job status...'
    for i in range(RETRIES_COUNT):
        job_status_response = mutate_job_service.get(selector)
        status = job_status_response[0]['status']
        if status in ('COMPLETED', 'FAILED'):
            break
        print('[%d] Current status is \'%s\', waiting %d seconds to retry...' %
              (i, status, RETRY_INTERVAL))
        time.sleep(RETRY_INTERVAL)

    if status == 'FAILED':
        raise errors.GoogleAdsError('Job failed with reason: \'%s\'' %
                                    job_status_response[0]['failure_reason'])
    if status in ('PROCESSING', 'PENDING'):
        raise errors.GoogleAdsError('Job did not complete within %d seconds' %
                                    (RETRY_INTERVAL * (RETRIES_COUNT - 1)))

    # Status must be COMPLETED.
    # Get the job result. Here we re-use the same selector.
    result_response = mutate_job_service.getResult(selector)

    # Output results.
    index = 0
    for result in result_response['SimpleMutateResult']['results']:
        if 'PlaceHolder' in result:
            print 'Operation [%d] - FAILED' % index
        else:
            print 'Operation [%d] - SUCCEEDED' % index
        index += 1
def main(client, campaign_id):
    # Initialize appropriate service.
    feed_service = client.GetService('FeedService', version='v201409')
    feed_item_service = client.GetService('FeedItemService', version='v201409')
    feed_mapping_service = client.GetService('FeedMappingService',
                                             version='v201409')
    campaign_feed_service = client.GetService('CampaignFeedService',
                                              version='v201409')

    sitelinks_data = {}

    # Create site links feed first.
    site_links_feed = {
        'name':
        'Feed For Site Links #%s' % uuid.uuid4(),
        'attributes': [{
            'type': 'STRING',
            'name': 'Link Text'
        }, {
            'type': 'URL',
            'name': 'Link URL'
        }, {
            'type': 'STRING',
            'name': 'Line 1 Description'
        }, {
            'type': 'STRING',
            'name': 'Line 2 Description'
        }]
    }

    response = feed_service.mutate([{
        'operator': 'ADD',
        'operand': site_links_feed
    }])
    if 'value' in response:
        feed = response['value'][0]
        link_text_feed_attribute_id = feed['attributes'][0]['id']
        link_url_feed_attribute_id = feed['attributes'][1]['id']
        line_1_feed_attribute_id = feed['attributes'][2]['id']
        line_2_feed_attribute_id = feed['attributes'][3]['id']
        print('Feed with name \'%s\' and ID \'%s\' was added with' %
              (feed['name'], feed['id']))
        print('\tText attribute ID \'%s\' and URL attribute ID \'%s\'.' %
              (link_text_feed_attribute_id, link_url_feed_attribute_id))
        print('\tLine 1 attribute ID \'%s\' and Line 2 attribute ID \'%s\'.' %
              (line_1_feed_attribute_id, line_2_feed_attribute_id))
        sitelinks_data['feedId'] = feed['id']
        sitelinks_data['linkTextFeedId'] = link_text_feed_attribute_id
        sitelinks_data['linkUrlFeedId'] = link_url_feed_attribute_id
        sitelinks_data['line1FeedId'] = line_1_feed_attribute_id
        sitelinks_data['line2FeedId'] = line_2_feed_attribute_id
    else:
        raise errors.GoogleAdsError('No feeds were added.')

    # Create site links feed items.
    items_data = [{
        'text': 'Home',
        'url': 'http://www.example.com',
        'line1': 'Home line 1',
        'line2': 'Home line 2'
    }, {
        'text': 'Stores',
        'url': 'http://www.example.com/stores',
        'line1': 'Stores line 1',
        'line2': 'Stores line 2'
    }, {
        'text': 'On Sale',
        'url': 'http://www.example.com/sale',
        'line1': 'On Sale line 1',
        'line2': 'On Sale line 2'
    }, {
        'text': 'Support',
        'url': 'http://www.example.com/support',
        'line1': 'Support line 1',
        'line2': 'Support line 2'
    }, {
        'text': 'Products',
        'url': 'http://www.example.com/products',
        'line1': 'Products line 1',
        'line2': 'Products line 2'
    }, {
        'text': 'About',
        'url': 'http://www.example.com/about',
        'line1': 'About line 1',
        'line2': 'About line 2'
    }]

    feed_items = []
    for item in items_data:
        feed_items.append({
            'feedId':
            sitelinks_data['feedId'],
            'attributeValues': [{
                'feedAttributeId':
                sitelinks_data['linkTextFeedId'],
                'stringValue':
                item['text']
            }, {
                'feedAttributeId':
                sitelinks_data['linkUrlFeedId'],
                'stringValue':
                item['url']
            }, {
                'feedAttributeId':
                sitelinks_data['line1FeedId'],
                'stringValue':
                item['line1']
            }, {
                'feedAttributeId':
                sitelinks_data['line2FeedId'],
                'stringValue':
                item['line2']
            }],
            # Optional: use the 'startTime' and 'endTime' keys to specify the time
            # period for the feed to deliver.  The example below will make the feed
            # start now and stop in one month.
            # Make sure you specify the datetime in the customer's time zone. You
            # can retrieve this from customer['dateTimeZone'].
            #
            # ['startTime']: datetime.datetime.now().strftime('%Y%m%d %H%M%S')
            # ['endTime']: (datetime.datetime.now() +
            #               relativedelta(months=1)).strftime('%Y%m%d %H%M%S')

            # Optional: use the 'scheduling' key to specify time and days of the
            # week for feed to deliver. This is a Beta feature.
        })

    feed_items_operations = [{
        'operator': 'ADD',
        'operand': item
    } for item in feed_items]

    response = feed_item_service.mutate(feed_items_operations)
    if 'value' in response:
        sitelinks_data['feedItemIds'] = []
        for feed_item in response['value']:
            print 'Feed item with ID %s was added.' % feed_item['feedItemId']
            sitelinks_data['feedItemIds'].append(feed_item['feedItemId'])
    else:
        raise errors.GoogleAdsError('No feed items were added.')

    # Create site links feed mapping.

    feed_mapping = {
        'placeholderType':
        PLACEHOLDER_SITELINKS,
        'feedId':
        sitelinks_data['feedId'],
        'attributeFieldMappings': [{
            'feedAttributeId':
            sitelinks_data['linkTextFeedId'],
            'fieldId':
            PLACEHOLDER_FIELD_SITELINK_LINK_TEXT
        }, {
            'feedAttributeId':
            sitelinks_data['linkUrlFeedId'],
            'fieldId':
            PLACEHOLDER_FIELD_SITELINK_LINK_URL
        }, {
            'feedAttributeId':
            sitelinks_data['line1FeedId'],
            'fieldId':
            PLACEHOLDER_FIELD_LINE_1_TEXT
        }, {
            'feedAttributeId':
            sitelinks_data['line2FeedId'],
            'fieldId':
            PLACEHOLDER_FIELD_LINE_2_TEXT
        }]
    }

    response = feed_mapping_service.mutate([{
        'operator': 'ADD',
        'operand': feed_mapping
    }])
    if 'value' in response:
        feed_mapping = response['value'][0]
        print(
            'Feed mapping with ID %s and placeholder type %s was saved for feed'
            ' with ID %s.' %
            (feed_mapping['feedMappingId'], feed_mapping['placeholderType'],
             feed_mapping['feedId']))
    else:
        raise errors.GoogleAdsError('No feed mappings were added.')

    # Create site links campaign feed.
    operands = []
    for feed_item_id in sitelinks_data['feedItemIds']:
        operands.append({
            'xsi_type': 'ConstantOperand',
            'type': 'LONG',
            'longValue': feed_item_id
        })

    feed_item_function = {
        'operator':
        'IN',
        'lhsOperand': [{
            'xsi_type': 'RequestContextOperand',
            'contextType': 'FEED_ITEM_ID'
        }],
        'rhsOperand':
        operands
    }

    # Optional: to target to a platform, define a function and 'AND' it with the
    #           feed item ID link:
    platform_function = {
        'operator':
        'EQUALS',
        'lhsOperand': [{
            'xsi_type': 'RequestContextOperand',
            'contextType': 'DEVICE_PLATFORM'
        }],
        'rhsOperand': [{
            'xsi_type': 'ConstantOperand',
            'type': 'STRING',
            'stringValue': 'Mobile'
        }]
    }
    combined_function = {
        'operator':
        'AND',
        'lhsOperand': [{
            'xsi_type': 'FunctionOperand',
            'value': feed_item_function
        }, {
            'xsi_type': 'FunctionOperand',
            'value': platform_function
        }]
    }

    campaign_feed = {
        'feedId': sitelinks_data['feedId'],
        'campaignId': campaign_id,
        'matchingFunction': combined_function,
        # Specifying placeholder types on the CampaignFeed allows the same feed
        # to be used for different placeholders in different Campaigns.
        'placeholderTypes': [PLACEHOLDER_SITELINKS]
    }

    response = campaign_feed_service.mutate([{
        'operator': 'ADD',
        'operand': campaign_feed
    }])
    if 'value' in response:
        campaign_feed = response['value'][0]
        print('Campaign with ID %s was associated with feed with ID %s.' %
              (campaign_feed['campaignId'], campaign_feed['feedId']))
    else:
        raise errors.GoogleAdsError('No campaign feeds were added.')