Code Monkey home page Code Monkey logo

google-ads-ruby's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

google-ads-ruby's Issues

LoggingInterceptor crashes if logger config is not provided

When the ads client is initialized it's possible to have the default logger fail to be created. The client will return but will fail on subsequent calls in which the LoggingInterceptor is invoked. I would expect the LoggingInterceptor to just never be used if no logger is set

begin
@logger = create_default_logger
rescue
STDERR.puts(
"Could not create default logger. Check your config file.")
end

logger = @logger
class_to_return = @proto_lookup_util.service(name)
class_to_return = Class.new(class_to_return) do
unless service_path.nil? || service_path.empty?
const_set('SERVICE_ADDRESS', service_path.freeze)
end
logging_interceptor =
Google::Ads::GoogleAds::LoggingInterceptor.new(logger)
const_set('GRPC_INTERCEPTORS', [logging_interceptor])
end

Inserting a similar user list is failing

On doing UserListService.mutate_user_lists with insert for a similar user list is failing with "Creating user list without setting type in oneof user_list field, or creating/updating read-only user list types is not allowed.", the type of user list was set to :SIMILAR

request:
[{:create=><Google::Ads::GoogleAds::V1::Resources::UserList: resource_name: "", id: nil, read_only: nil, name: <Google::Protobuf::StringValue: value: "ppagi audience 2019-06-25T14:39:15-04:00">, description: <Google::Protobuf::StringValue: value: "ppagi description 2019-06-25T14:39:15-04:00">, membership_status: :OPEN, integration_code: nil, membership_life_span: <Google::Protobuf::Int64Value: value: 180>, size_for_display: nil, size_range_for_display: :UNSPECIFIED, size_for_search: nil, size_range_for_search: :UNSPECIFIED, type: :SIMILAR, closing_reason: :UNSPECIFIED, access_reason: :UNSPECIFIED, account_user_list_status: :UNSPECIFIED, eligible_for_search: nil, eligible_for_display: nil, crm_based_user_list: nil, similar_user_list: <Google::Ads::GoogleAds::V1::Common::SimilarUserListInfo: seed_user_list: <Google::Protobuf::StringValue: value: "customers/4983552381/userLists/6038929100482">>, rule_based_user_list: nil, logical_user_list: nil, basic_user_list: nil>}]

response:
<Google::Ads::GoogleAds::V1::Services::MutateUserListsResponse: results: [<Google::Ads::GoogleAds::V1::Services::MutateUserListResult: resource_name: "">], partial_failure_error: <Google::Rpc::Status: code: 3, message: "Creating user list without setting type in oneof user_list field, or creating/updating read-only user list types is not allowed., at operations[0]", details: [<Google::Protobuf::Any: type_url: "type.googleapis.com/google.ads.googleads.v1.errors.GoogleAdsFailure", value: "\n\x9E\x01\n\x03\xF0\x04\x10\x12\x80\x01Creating user list without setting type in oneof user_list field, or creating/updating read-only user list types is not allowed.\x1A\x02*\x00"\x10\x12\x0E\n\noperations\x12\x00">]>>

inconsistencies between documentation and library behaviour

I initially reported these in the forum but they told me to post here.

I would like to report some glitches I faced while implementing google ads code using https://github.com/googleads/google-ads-ruby

Basically it's a matter of documentation stating entities are editable while they are not (or maybe partially, yet would deserve clarification).

I put below the list of entities we did check alongside the error messages we got:

  • Keywords: 'keyword.match_type' cannot be modified by 'UPDATE' so we cant rely on mere update

  • AdCustomizerFeedMapping: bug in the gem maybe, cannot update: undefined method update=' for #<Google::Ads::GoogleAds::V1::Services::FeedMappingOperation:0x00007f211f40b540`

  • Location: Field 'location.geo_target_constant' cannot be modified by 'UPDATE' operation โ€“ Field 'negative' cannot be modified by 'UPDATE' operation.

  • Proximity: 'proximity.geo_point.latitude_in_micro_degrees' cannot be modified by 'UPDATE' --Field 'proximity.radius' cannot be modified by 'UPDATE' etc...

  • ExpandedTextAd: Field 'ad.expanded_text_ad.description' cannot be modified by 'UPDATE' operation., at operations[0].update.ad.expanded_text_ad.description", details: [<Google::Protobuf::Any: type_url: "type.googleapis.com/google.ads.googleads.v1.errors.GoogleAdsFailure", value: "\n\x9C\x01\n\x02\b\v\x12QField 'ad.expanded_text_ad.description' cannot be modified by 'UPDATE' operation.\"C\x12\x0E\n\noperations\x12\x00\x12\b\n\x06update\x12\x04\n\x02ad\x12\x12\n\x10expanded_text_ad\x12\r\n\vdescription\n\xA2\x01\n\x02\b\v\x12TField 'ad.expanded_text_ad.headline_part1' cannot be modified by 'UPDATE' operation.\"F\x12\x0E\n\noperations\x12\x00\x12\b\n\x06update\x12\x04\n\x02ad\x12\x12\n\x10expanded_text_ad\x12\x10\n\x0Eheadline_part1\n\xA2\x01\n\x02\b\v\x12TField 'ad.expanded_text_ad.headline_part2' cannot be modified by 'UPDATE' operation.\"F\x12\x0E\n\noperations\x12\x00\x12\b\n\x06update\x12\x04\n\x02ad\x12\x12\n\x10expanded_text_ad\x12\x10\n\x0Eheadline_part2\n\x90\x01\n\x02\b\v\x12KField 'ad.expanded_text_ad.path1' cannot be modified by 'UPDATE' operation.\"=\x12\x0E\n\noperations\x12\x00\x12\b\n\x06update\x12\x04\n\x02ad\x12\x12\n\x10expanded_text_ad\x12\a\n\x05path1\n\x90\x01\n\x02\b\v\x12KField 'ad.expanded_text_ad.path2' cannot be modified by 'UPDATE' operation.\"=\x12\x0E\n\noperations\x12\x00\x12\b\n\x06update\x12\x04\n\x02ad\x12\x12\n\x10expanded_text_ad\x12\a\n\x05path2\nu\n\x02\b\v\x12?Field 'ad.final_urls' cannot be modified by 'UPDATE' operation.\".\x12\x0E\n\noperations\x12\x00\x12\b\n\x06update\x12\x04\n\x02ad\x12\f\n\nfinal_urls">]

  • AdCustomizerFeed: The customer is not eligible to mutate this resource. Yet delete/create work fine

  • CampaignAdSchedule: Field 'ad_schedule.day_of_week' cannot be modified by 'UPDATE' operation., at operations[1].update.ad_schedule.day_of_week", details: [<Google::Protobuf::Any: type_url: "type.googleapis.com/google.ads.googleads.v1.errors.GoogleAdsFailure", value: "\n\x8B\x01\n\x02\b\v\x12IField 'ad_schedule.day_of_week' cannot be modified by 'UPDATE' operation.\":\x12\x10\n\noperations\x12\x02\b\x01\x12\b\n\x06update\x12\r\n\vad_schedule\x12\r\n\vday_of_week\n\x85\x01\n\x02\b\v\x12FField 'ad_schedule.end_hour' cannot be modified by 'UPDATE' operation.\"7\x12\x10\n\noperations\x12\x02\b\x01\x12\b\n\x06update\x12\r\n\vad_schedule\x12\n\n\bend_hour\n\x89\x01\n\x02\b\v\x12HField 'ad_schedule.end_minute' cannot be modified by 'UPDATE' operation.\"9\x12\x10\n\noperations\x12\x02\b\x01\x12\b\n\x06update\x12\r\n\vad_schedule\x12\f\n\nend_minute\n\x89\x01\n\x02\b\v\x12HField 'ad_schedule.start_hour' cannot be modified by 'UPDATE' operation.\"9\x12\x10\n\noperations\x12\x02\b\x01\x12\b\n\x06update\x12\r\n\vad_schedule\x12\f\n\nstart_hour\n\x8D\x01\n\x02\b\v\x12JField 'ad_schedule.start_minute' cannot be modified by 'UPDATE' operation.\"

Get customer request not working in v0.7

After the v0.7 update, the method "get_customer" of customer service is not working and it gets an error:

undefined method 'customer_id' for #<Google::Ads::GoogleAds::V0::Services::GetCustomerRequest>

You can check it in the "get_account_information.rb" example. Thanks.

partial_failure don't work

Hello, I try to set partial_failure in the method
campaign_service =client.service(:Campaign)
campaign_service.mutate_campaigns(externalCustomerId,campaignOperatio,true)

but this fail:
**/usr/local/rvm/gems/ruby-2.5.1/gems/google-ads-googleads-0.7.0/lib/google/ads/google_ads/v0/services/campaign_service_client.rb:250:in mutate_campaigns': wrong number of arguments (given 3, expected 2) (ArgumentError)** as it says here https://developers.google.com/google-ads/api/reference/rpc/google.ads.googleads.v0.services#google.ads.googleads.v0.services.MutateCampaignsRequest`

Dismiss recommendation operation still failing

Hello, the last commit fixes one error but it raises another now, this happens because the file "recommendation_service_pb.rb" inside the v0/services folder is auto-generated incorrectly and needs changes to work properly.

That's why my pull request had changes inside v0 folder the first time.

NameError: uninitialized constant Google::Ads::GoogleAds::V0::Services::DismissRecommendationOperation

Allow user to provide with additional GRPC interceptors

It would be great to have a possibility to provide with own interceptors for service initialization since there is currently no way to inject there. Ideally (or additionally) in a global manner so this could be configured without modifying client/service initialization code and interceptor could be injected dynamically in tests (to fake requests).

NameError when using remove_resource

Code to reproduce:

require 'google/ads/google_ads'
client = Google::Ads::GoogleAds::GoogleAdsClient.new
client.operation.remove_resource.campaign('whatever')

Output:
NameError (uninitialized constant Google::Ads::GoogleAds::V1::Services::CampaignOperation)

Expected output:
A CampaignOperation

I think we're just missing a "require" inside each remove call.

Errors::ErrorLocation::FieldPathElement doesnt contain index anymore

Using 3.2.0, it seems there is a regression within the data I retrieve on errors.

It was possible to get the index of the errored operations before yet this field is now nil see <Google::Ads::GoogleAds::V2::Errors::ErrorLocation::FieldPathElement: field_name: "name", index: nil>]> and full object below.

If ever it is relevant, it happens after a mutation where I use partial_failure: true, validate_only: true.

Is it a known issue?

Thanks

[#<GoogleErrorWrapper:0x00007f682e2904f8 @error=<Google::Ads::GoogleAds::V2::Errors::GoogleAdsError: error_code: <Google::Ads::GoogleAds::V2::Errors::ErrorCode: request_error: :UNSPECIFIED, bidding_strategy_error: :UNSPECIFIED, url_field_error: :UNSPECIFIED, list_operation_error: :UNSPECIFIED, query_error: :UNSPECIFIED, mutate_error: :UNSPECIFIED, field_mask_error: :UNSPECIFIED, authorization_error: :UNSPECIFIED, internal_error: :UNSPECIFIED, quota_error: :UNSPECIFIED, ad_error: :UNSPECIFIED, ad_group_error: :UNSPECIFIED, campaign_budget_error: :DUPLICATE_NAME, campaign_error: :UNSPECIFIED, authentication_error: :UNSPECIFIED, ad_group_criterion_error: :UNSPECIFIED, ad_customizer_error: :UNSPECIFIED, ad_group_ad_error: :UNSPECIFIED, ad_sharing_error: :UNSPECIFIED, adx_error: :UNSPECIFIED, bidding_error: :UNSPECIFIED, campaign_criterion_error: :UNSPECIFIED, collection_size_error: :UNSPECIFIED, criterion_error: :UNSPECIFIED, date_error: :UNSPECIFIED, date_range_error: :UNSPECIFIED, distinct_error: :UNSPECIFIED, feed_attribute_reference_error: :UNSPECIFIED, function_error: :UNSPECIFIED, function_parsing_error: :UNSPECIFIED, id_error: :UNSPECIFIED, image_error: :UNSPECIFIED, media_bundle_error: :UNSPECIFIED, multiplier_error: :UNSPECIFIED, new_resource_creation_error: :UNSPECIFIED, not_empty_error: :UNSPECIFIED, null_error: :UNSPECIFIED, operator_error: :UNSPECIFIED, range_error: :UNSPECIFIED, region_code_error: :UNSPECIFIED, setting_error: :UNSPECIFIED, string_format_error: :UNSPECIFIED, string_length_error: :UNSPECIFIED, operation_access_denied_error: :UNSPECIFIED, resource_access_denied_error: :UNSPECIFIED, resource_count_limit_exceeded_error: :UNSPECIFIED, recommendation_error: :UNSPECIFIED, ad_group_bid_modifier_error: :UNSPECIFIED, context_error: :UNSPECIFIED, field_error: :UNSPECIFIED, shared_set_error: :UNSPECIFIED, shared_criterion_error: :UNSPECIFIED, campaign_shared_set_error: :UNSPECIFIED, conversion_action_error: :UNSPECIFIED, header_error: :UNSPECIFIED, database_error: :UNSPECIFIED, policy_finding_error: :UNSPECIFIED, enum_error: :UNSPECIFIED, keyword_plan_error: :UNSPECIFIED, keyword_plan_campaign_error: :UNSPECIFIED, keyword_plan_negative_keyword_error: :UNSPECIFIED, keyword_plan_ad_group_error: :UNSPECIFIED, keyword_plan_keyword_error: :UNSPECIFIED, keyword_plan_idea_error: :UNSPECIFIED, account_budget_proposal_error: :UNSPECIFIED, user_list_error: :UNSPECIFIED, change_status_error: :UNSPECIFIED, feed_error: :UNSPECIFIED, geo_target_constant_suggestion_error: :UNSPECIFIED, campaign_draft_error: :UNSPECIFIED, feed_item_error: :UNSPECIFIED, label_error: :UNSPECIFIED, media_file_error: :UNSPECIFIED, billing_setup_error: :UNSPECIFIED, customer_client_link_error: :UNSPECIFIED, customer_error: :UNSPECIFIED, customer_manager_link_error: :UNSPECIFIED, feed_mapping_error: :UNSPECIFIED, customer_feed_error: :UNSPECIFIED, ad_group_feed_error: :UNSPECIFIED, campaign_feed_error: :UNSPECIFIED, custom_interest_error: :UNSPECIFIED, campaign_experiment_error: :UNSPECIFIED, extension_feed_item_error: :UNSPECIFIED, ad_parameter_error: :UNSPECIFIED, feed_item_validation_error: :UNSPECIFIED, extension_setting_error: :UNSPECIFIED, feed_item_target_error: :UNSPECIFIED, policy_violation_error: :UNSPECIFIED, asset_error: :UNSPECIFIED, mutate_job_error: :UNSPECIFIED, country_code_error: :UNSPECIFIED, language_code_error: :UNSPECIFIED, conversion_upload_error: :UNSPECIFIED, partial_failure_error: :UNSPECIFIED, policy_validation_parameter_error: :UNSPECIFIED, conversion_adjustment_upload_error: :UNSPECIFIED, media_upload_error: :UNSPECIFIED, youtube_video_registration_error: :UNSPECIFIED, size_limit_error: :UNSPECIFIED, not_whitelisted_error: :UNSPECIFIED, manager_link_error: :UNSPECIFIED, currency_code_error: :UNSPECIFIED, access_invitation_error: :UNSPECIFIED, reach_plan_error: :UNSPECIFIED, invoice_error: :UNSPECIFIED>, message: "A campaign budget with this name already exists.", trigger: <Google::Ads::GoogleAds::V2::Common::Value: boolean_value: false, int64_value: 0, float_value: 0.0, double_value: 0.0, string_value: "">, location: <Google::Ads::GoogleAds::V2::Errors::ErrorLocation: field_path_elements: [<Google::Ads::GoogleAds::V2::Errors::ErrorLocation::FieldPathElement: field_name: "operations", index: nil>, <Google::Ads::GoogleAds::V2::Errors::ErrorLocation::FieldPathElement: field_name: "create", index: nil>, <Google::Ads::GoogleAds::V2::Errors::ErrorLocation::FieldPathElement: field_name: "name", index: nil>]>, details: nil>>]

Invalid type error in GoogleAdsService.mutate

I faced Google::Protobuf::TypeError when execute GoogleAdsService.Mutate like below.
(Almost as same as example codes to create Campaign and Campaign Budget)

require 'google/ads/google_ads'

customer_id = 'xxxyyyzzzz'

client = Google::Ads::GoogleAds::GoogleAdsClient.new

ga_service = client.service(:GoogleAds)

cbudget = client.resource(:CampaignBudget)
cbudget.id = client.wrapper.int64(-1)
cbudget.name = client.wrapper.string(sprintf('Interplanetary Budget %s',(Time.new.to_f * 1000).to_i))
cbudget.delivery_method = client.enum(:BudgetDeliveryMethod)::STANDARD
cbudget.amount_micros = client.wrapper.int64(500000)
cbudget_operation = client.operation(:CampaignBudget)
cbudget_operation['create'] = cbudget

campaign = client.resource(:Campaign)
campaign.name = client.wrapper.string(sprintf('Interplanetary Cruise %s',(Time.new.to_f * 1000).to_i))
campaign.advertising_channel_type = client.enum(:AdvertisingChannelType)::SEARCH

campaign.status = client.enum(:CampaignStatus)::PAUSED

campaign.manual_cpc = client.resource(:ManualCpc)
campaign.campaign_budget = client.wrapper.string("customers/#{customer_id}/campaignBudgets/-1")

campaign.network_settings = client.resource(:NetworkSettings)
campaign.network_settings.target_google_search = client.wrapper.bool(true)
campaign.network_settings.target_search_network = client.wrapper.bool(true)
campaign.network_settings.target_content_network = client.wrapper.bool(false)
campaign.network_settings.target_partner_search_network = client.wrapper.bool(false)

campaign.start_date = client.wrapper.string(DateTime.parse((Date.today + 1).to_s).strftime('%Y%m%d'))

campaign.end_date = client.wrapper.string(DateTime.parse((Date.today.next_year).to_s).strftime('%Y%m%d'))

campaign_operation = client.operation(:Campaign)
campaign_operation['create'] = campaign

ga_service.mutate(customer_id, [cbudget_operation, campaign_operation])

Finally, ga_service.mutate() raises Google::Protobuf::TypeError like below.

(some of stack-trace lines...)

/Users/.../vendor/bundle/ruby/2.5.0/gems/google-gax-1.5.0/lib/google/gax/util.rb:65:in `initialize': Invalid type Google::Ads::GoogleAds::V1::Services::CampaignOperation to assign to submessage field ''. (Google::Protobuf::TypeError)

Do I have something mistake in above sample code? Or GoogleAdsService.Mutate has something bugs?

Campaign#bidding_strategy_type= (and other read-only field writers) should not be defined

campaign.bidding_strategy_type = :MANUAL_CPC is possible but if submitted as part of a write operation it will fail because bidding_strategy_type is read only. We get back a very confusing error message

/Users/samphippen/.gem/ruby/2.5.3/gems/google-gax-1.5.0/lib/google/gax/api_callable.rb:369:in `rescue in block in retryable': GaxError Exception occurred in retry method that was not classified as transient, caused by 3:Request contains an invalid argument. (Google::Gax::RetryError)

Ideally, it would be impossible to call Campaign#bidding_strategy_type= to prevent this from happening. It should be possible to define methods as read only in the protos.

Google::Ads::GoogleAds::GoogleAdsClient#service.feed_item.mutate_feed_items returns error for unused field FIELD_CANNOT_BE_CLEARED

Hi,

Now I try to rewrite my API call to feed and feed_item operation from Adwords API to Google Ads API.
I have a problem when I call mutate_feed_items for DYNAMIC_CUSTOM feed, and it seems to be a bug.

My code like the following, ...

# client = Google::Ads::Googleds::GoogleAdsClient instance
# original_feed_item = generate via client.resource.feed_item, attributes from API query result.

operations = []

operation = client.operation.update_resource.feed_item(original_feed_item) do |modify_feed_item|
  ...
  # set values to update
end

if !opearation.update_mask.empty?
  operations << operation
end

if !operations.empty?
  client.service.feed_item.mutate_feed_items(MY_CUSTOMER_ID, operations)
end

then it raise error Google::Gax::InvalidArgumentError, and logged.

I, [2019-08-07T14:47:16.960735 #76554]  INFO -- : Incoming response (errors):
Error 1: {"errorCode":{"fieldError":"FIELD_CANNOT_BE_CLEARED"},"message":"The field cannot be cleared.","location":{"fieldPathElements":[{"fieldName":"operations","index":},{"fieldName":"update"},{"fieldName":"attribute_values"},{"fieldName":"boolean_value"}]}}
...

feed_item for DYNAMIC_CUSTOM has no field of type boolean, so it seems to be a bug.

Injectable config.logger

Would it be possible to have an injectable config.logger (rather than just the stream/level)? We try to reuse Rails.logger or one of our custom logger instances whenever possible

errors and partial failures details

With adwords api, I would take N operations, do a dry run with partial_failure and validate_only.
Response would give me for each wrong operation: its index, the relevant error.
So I would know exactly which operations were invalid and why, so I could discard them and push the rest.

With google ads, sending 4 operations, 2 with known wrong arguments, I get:

<Google::Ads::GoogleAds::V1::Services::MutateCampaignBudgetsResponse: results: [], 
partial_failure_error: <Google::Rpc::Status: code: 3, message: "Multiple errors in โ€˜detailsโ€™. First
 error: Too low., at operations[0].create.amount_micros", details: [<Google::Protobuf::Any:
 type_url: "type.googleapis.com/google.ads.googleads.v1.errors.GoogleAdsFailure", value: 
"\n<\n\x03\x88\x03\x02\x12\bToo low.\"+\x12\x0E\n\noperations\x12\x00\x12\b\n\x06create
\x12\x0F\n\ramount_micros\n;\n\x03\xB0\x03\x02\x12\nToo short.\x1A\x02*\x00\"$\x12\x10\n
\noperations\x12\x02\b\x01\x12\b\n\x06create\x12\x06\n\x04name">]>>

So:

  • I do not know which operations are fine
  • I do not know which are not
  • I dont have individual details for each errored operation (very handy to go back to data afterwards)

It would be ideal to have access to these information.

Feature Request: provide with intermediate objects to avoid client global

For now, pretty much everything is attached to the client for "convenience" sake.

Yet as a developer, I would not like to need a client object to build the operations: in the end its more a global value than a convenient one.

Basically I would like to be able to create an operation, use an enum, use wrappers without the client.

For instance:

# in addition of 
client = ::Google::Ads::GoogleAds::GoogleAdsClient.new
client.operation(name)
# I'd like to be able to use
::Google::Ads::GoogleAds::GoogleAdsClient.operation(name, version)
# or maybe something like
proto_lookup = ::Google::Ads::GoogleAds::ProtoLookup.new(version)
proto_lookup.operation(name)

Indeed, creating an operation should not rely on some api configuration triggered during client instantiation.

One way to achieve this would be to have proto_lookup_utils at the class level.

Another way would be to move lookup utils in an independent object.

Would you accept either move?

Batch Processing

Hello, I wanted to know if itยดs possible to work with Batch Processing using ruby client library. I only found examples made in php, so, I'm not sure.

Field search appears to be broken

[2] pry(main)> c
=> #<Google::Ads::GoogleAds::GoogleAdsClient:0x00007f920438fa20
... (redacted)
>
[3] pry(main)> fs = c.service(:GoogleAdsField)
=> #<#<Class:0x00007f9204435538>:0x00007f9204434c00
 @get_google_ads_field=#<Proc:0x00007f9204425070@/Users/samphippen/.gem/ruby/2.5.3/gems/google-gax-1.5.0/lib/google/gax/api_callable.rb:246>,
 @google_ads_field_service_stub=
  #<Google::Ads::GoogleAds::V0::Services::GoogleAdsFieldService::Stub:0x00007f9204425368
   @ch=#<GRPC::Core::Channel:0x00007f92044251b0>,
   @host="googleads.googleapis.com:443",
   @interceptors=
    #<GRPC::InterceptorRegistry:0x00007f9204425160
     @interceptors=
      [#<Google::Ads::GoogleAds::LoggingInterceptor:0x00007f92044354c0
        @logger=
         #<Logger:0x00007f920438f7a0
          @default_formatter=#<Logger::Formatter:0x00007f920438f700 @datetime_format=nil>,
          @formatter=nil,
          @level=1,
          @logdev=#<Logger::LogDevice:0x00007f920438f6b0 @dev=#<IO:<STDERR>>, @filename=nil, @mon_count=0, @mon_mutex=#<Thread::Mutex:0x00007f920438f5e8>, @mon_owner=nil, @shift_age=nil, @shift_period_suffix=nil, @shift_size=nil>,
          @progname=nil>,
        @options={}>]>,
   @propagate_mask=nil,
   @timeout=1969-12-31 18:59:59 -0500>,
 @search_google_ads_fields=#<Proc:0x00007f9204424f58@/Users/samphippen/.gem/ruby/2.5.3/gems/google-gax-1.5.0/lib/google/gax/api_callable.rb:246>>
[4] pry(main)> fs.search_google_ads_fields('')
Google::Gax::RetryError: GaxError Exception occurred in retry method that was not classified as transient, caused by undefined method `customer_id' for #<Google::Ads::GoogleAds::V0::Services::SearchGoogleAdsFieldsRequest:0x00007f92043787a8>
from /Users/samphippen/.gem/ruby/2.5.3/gems/google-gax-1.5.0/lib/google/gax/api_callable.rb:369:in `rescue in block in retryable'
Caused by NoMethodError: undefined method `customer_id' for #<Google::Ads::GoogleAds::V0::Services::SearchGoogleAdsFieldsRequest:0x00007f92043787a8>
from /Users/samphippen/.gem/ruby/2.5.3/gems/google-ads-googleads-0.8.0/lib/google/ads/google_ads/logging_interceptor.rb:34:in `method_missing'
[5] pry(main)> fs.search_google_ads_fields('select * from foo')
Google::Gax::RetryError: GaxError Exception occurred in retry method that was not classified as transient, caused by undefined method `customer_id' for #<Google::Ads::GoogleAds::V0::Services::SearchGoogleAdsFieldsRequest:0x00007f920436fdd8>
from /Users/samphippen/.gem/ruby/2.5.3/gems/google-gax-1.5.0/lib/google/gax/api_callable.rb:369:in `rescue in block in retryable'
Caused by NoMethodError: undefined method `customer_id' for #<Google::Ads::GoogleAds::V0::Services::SearchGoogleAdsFieldsRequest:0x00007f920436fdd8>
from /Users/samphippen/.gem/ruby/2.5.3/gems/google-ads-googleads-0.8.0/lib/google/ads/google_ads/logging_interceptor.rb:34:in `method_missing'
[6] pry(main)>

I would have expected this to correctly dispatch a request, not try and call customer_id on a proto that doesn't have it.

GaxError

Hello,
Sometimes I get this error:
GaxError Exception occurred in retry method that was not classified as transient, caused by undefined method `each' for #String:0x0000000004146118
when I try to get reports

it seems to be random.

GaxError Exception occurred in retry method that was not classified as transient, caused by 13:Internal error encountered. (Google::Gax::RetryError)

Hello,I try to get all keywords to many Accounts but the process launch this exception:

#<Thread:[email protected]:454 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
	11: from reportsDaily.rb:454:in `block (2 levels) in KeywordReportDaily'
	10: from reportsDaily.rb:476:in `threadReportkw'
	 9: from reportsDaily.rb:476:in `each'
	 8: from reportsDaily.rb:492:in `block in threadReportkw'
	 7: from reportsDaily.rb:492:in `count'
	 6: from /usr/local/rvm/gems/ruby-2.5.1/gems/google-gax-1.4.0/lib/google/gax/api_callable.rb:160:in `each'
	 5: from /usr/local/rvm/gems/ruby-2.5.1/gems/google-gax-1.4.0/lib/google/gax/api_callable.rb:173:in `each_page'
	 4: from /usr/local/rvm/gems/ruby-2.5.1/gems/google-gax-1.4.0/lib/google/gax/api_callable.rb:173:in `loop'
	 3: from /usr/local/rvm/gems/ruby-2.5.1/gems/google-gax-1.4.0/lib/google/gax/api_callable.rb:175:in `block in each_page'
	 2: from /usr/local/rvm/gems/ruby-2.5.1/gems/google-gax-1.4.0/lib/google/gax/api_callable.rb:189:in `next_page'
	 1: from /usr/local/rvm/gems/ruby-2.5.1/gems/google-gax-1.4.0/lib/google/gax/api_callable.rb:358:in `block in retryable'
/usr/local/rvm/gems/ruby-2.5.1/gems/google-gax-1.4.0/lib/google/gax/api_callable.rb:369:in `rescue in block in retryable': GaxError Exception occurred in retry method that was not classified as transient, caused by 13:Internal error encountered. (Google::Gax::RetryError)
Traceback (most recent call last):
	11: from reportsDaily.rb:454:in `block (2 levels) in KeywordReportDaily'
	10: from reportsDaily.rb:476:in `threadReportkw'
	 9: from reportsDaily.rb:476:in `each'
	 8: from reportsDaily.rb:492:in `block in threadReportkw'
	 7: from reportsDaily.rb:492:in `count'
	 6: from /usr/local/rvm/gems/ruby-2.5.1/gems/google-gax-1.4.0/lib/google/gax/api_callable.rb:160:in `each'
	 5: from /usr/local/rvm/gems/ruby-2.5.1/gems/google-gax-1.4.0/lib/google/gax/api_callable.rb:173:in `each_page'
	 4: from /usr/local/rvm/gems/ruby-2.5.1/gems/google-gax-1.4.0/lib/google/gax/api_callable.rb:173:in `loop'
	 3: from /usr/local/rvm/gems/ruby-2.5.1/gems/google-gax-1.4.0/lib/google/gax/api_callable.rb:175:in `block in each_page'
	 2: from /usr/local/rvm/gems/ruby-2.5.1/gems/google-gax-1.4.0/lib/google/gax/api_callable.rb:189:in `next_page'
	 1: from /usr/local/rvm/gems/ruby-2.5.1/gems/google-gax-1.4.0/lib/google/gax/api_callable.rb:358:in `block in retryable'
/usr/local/rvm/gems/ruby-2.5.1/gems/google-gax-1.4.0/lib/google/gax/api_callable.rb:369:in `rescue in block in retryable': GaxError Exception occurred in retry method that was not classified as transient, caused by 13:Internal error encountered. (Google::Gax::RetryError)
[ec2-user@ip-172-31-44-96 rbfiles]$ 

I get it only sometimes,

could you help me?
thanks

Querying campaign drafts using draft_id isn't working

I created campaign 2042698994 and then created a draft campaign using the CampaignDraftService.MutateCampaignDrafts , the service call return me [<Google::Ads::GoogleAds::V1::Services::MutateCampaignDraftResult: resource_name: "customers/4983552381/campaignDrafts/2042698994~281474976710656">]

As per documentation this is of the format
customers/{customer_id}/campaignDrafts/{base_campaign_id}~{draft_id}

When I query campaign drafts using the draft_id=281474976710656 I get a totally unrelated draft

#<Object:0x00007f933463b748 @external_id="281474976710656", @resource_name="281474976710656", @status=:REMOVED, @draft_id=281474976710656, @base_campaign="699490231", @name="Test Campaign 50604-exp_3985", @draft_campaign="281475676200887", @has_experiment_running=false, @long_running_operation=nil>

Account hierarchy

I try to fetch account hierarchy for a managed account using a single query.

ga_service = client.service(:GoogleAds)
query = <<~QUERY
SELECT customer_client_link.client_customer, customer.descriptive_name
FROM customer_client_link
QUERY
response = ga_service.search('<MCC_ACCOUNT_ID>', query, page_size: 10)

The descriptive_name returned is the name of the MCC account not client.

How would you do it?

ruby 1.8.7 support

Hello,
May I know what's the latest version of google-ads-ruby that still support ruby 1.8.7?
Thank you.

Beta API feedback, Client#resource

I believe the resources should define getters and setters for all the attributes which do the appropriate wrapper calls rather than expecting the user of the api to tediously call wrapper as in the following

payload = client.resource(:CampaignBudget)
payload.name = client.wrapper.string(name)

which should just be imho

payload.name = name

Similarly, resource and operation should take hashes as args and set the corresponding attributes

payload = client.resource(:CampaignBudget, {name: name, amount_micros: amount, delivery_method: 'ACCELERATED', explicitly_shared: true})

You'll note that I expect the setter for 'delivery_method' to know how to find its enum and lookup the value. (I'm writing our own shims to do this but would prefer to use yours)

Invalid type Google::Ads::GoogleAds::V1::Common::PolicyViolationKey to assign to submessage field ''.

Hi,

I m migrating 2.0.0 code to "3.2.0".

I am specifically trying to add a policy exemption to the payload of a keyword. Here is the code:

factories = Google::Ads::GoogleAds::Factories
keyword = factories.version_alternate_for(:resources).ad_group_criterion
operation = factories.version_alternate_for(:operations).create_resource.ad_group_criterion(keyword)
policy_violation_key = Google::Ads::GoogleAds::V1::Common::PolicyViolationKey.new(policy_name: "pharma", violating_text: "drug")
operation.exempt_policy_violation_keys.push(policy_violation_key)
# => *** Google::Protobuf::TypeError Exception: Invalid type Google::Ads::GoogleAds::V1::Common::PolicyViolationKey to assign to submessage field ''.

It worked on v2.0.0, what must I do now please? there is no relevant stacktrace and the error message is a little confusing.

Thanks in advance.

google_ads_client.rb must cast login_customer_id to string

headers[:"login-customer-id"] = login_customer_id You must add .to_s otherwise it gives an error downstream about headers must be strings

And, you may as well cast it to int if it was passed as string in order to do the bounds check

Infinite loop when using invalid refresh_token

When the refresh token is invalid, client goes into an infinite loop instead of raising exceptions:

[3] pry(main)> client.service(:Customer).list_accessible_customers

W, [2019-04-29T15:28:27.286127 #41]  WARN -- : CID: N/A, Host: googleads.googleapis.com:443, Method: /google.ads.googleads.v1.services.CustomerService/ListAccessibleCustomers, IsFault: yes
I, [2019-04-29T15:28:27.286886 #41]  INFO -- : Outgoing request: Headers: {"x-goog-api-client":"gl-ruby/2.6.3 gapic/1.1.1 gax/1.5.0 grpc/1.20.0","developer-token":"hidden"} Payload: {}
I, [2019-04-29T15:28:27.287015 #41]  INFO -- : Incoming response (errors):
Could not parse error details due to a malformed server response trailer.
W, [2019-04-29T15:28:27.488532 #41]  WARN -- : CID: N/A, Host: googleads.googleapis.com:443, Method: /google.ads.googleads.v1.services.CustomerService/ListAccessibleCustomers, IsFault: yes
I, [2019-04-29T15:28:27.488826 #41]  INFO -- : Outgoing request: Headers: {"x-goog-api-client":"gl-ruby/2.6.3 gapic/1.1.1 gax/1.5.0 grpc/1.20.0","developer-token":"hidden"} Payload: {}
I, [2019-04-29T15:28:27.489125 #41]  INFO -- : Incoming response (errors):
Could not parse error details due to a malformed server response trailer.
W, [2019-04-29T15:28:27.625463 #41]  WARN -- : CID: N/A, Host: googleads.googleapis.com:443, Method: /google.ads.googleads.v1.services.CustomerService/ListAccessibleCustomers, IsFault: yes
I, [2019-04-29T15:28:27.625792 #41]  INFO -- : Outgoing request: Headers: {"x-goog-api-client":"gl-ruby/2.6.3 gapic/1.1.1 gax/1.5.0 grpc/1.20.0","developer-token":"hidden"} Payload: {}
I, [2019-04-29T15:28:27.626775 #41]  INFO -- : Incoming response (errors):
Could not parse error details due to a malformed server response trailer.

Ad service undefined

Hello, i'm trying to update an ad and i'm having some problems.
I can update an ad_group_ad perfectly but i try to update the "final_urls" field of the ad inside the ad_group_ad and it gets an error:

Field 'ad.final_urls' cannot be modified by 'UPDATE' operation.

Then, i try to use the client path of the ad but it's not defined in the "path_lookup_util.rb" file and it gets a NoMethod error:

NoMethodError: undefined method 'ad' for #<Google::Ads::GoogleAds::PathLookupUtil>

And finally, i try to define the method by myself in the gem but it gets another error:

ArgumentError: No service found with name Ad

So, it looks like the service of the Ad resource is not defined and i can't do any operations with them.
Any help? Thanks.

GaxError Exception occurred in retry method that was not classified as transient, caused by 5:Requested entity was not found

When I tried to use keyword_plan_idea_service_client.rb to list keyword ideas, always return this error to me:

Error: 'GaxError Exception occurred in retry method that was not classified as transient, caused by 5:Requested entity was not found.'
Cause: '5:Requested entity was not found.'
Code: 5
Details: 'Requested entity was not found.'
Request-Id: 'MNH7cNiC8MpCzHokdPDu_Q'

Example:

kp_idea_service = client.service(:KeywordPlanIdea)
    
seed = client.resource(:UrlSeed)
seed.url = client.wrapper.string("github.com")

      kp_idea_service.generate_keyword_ideas(
        customer_id,
        client.wrapper.string(client.path.language_constant('en_US')),
        [client.wrapper.string(client.path.geo_target_constant(2076))],
        client.enum(:KeywordPlanNetwork)::GOOGLE_SEARCH,
        url_seed: seed
      )
  
/home/toshi/.rvm/gems/ruby-2.6.0/gems/google-gax-1.5.0/lib/google/gax/api_callable.rb:369:in `rescue in block in retryable'
/home/toshi/.rvm/gems/ruby-2.6.0/gems/google-gax-1.5.0/lib/google/gax/api_callable.rb:358:in `block in retryable'
/home/toshi/.rvm/gems/ruby-2.6.0/gems/google-gax-1.5.0/lib/google/gax/api_callable.rb:230:in `block in create_api_call'
/home/toshi/.rvm/gems/ruby-2.6.0/gems/google-gax-1.5.0/lib/google/gax/api_callable.rb:260:in `block in create_api_call'
/home/toshi/.rvm/gems/ruby-2.6.0/gems/google-ads-googleads-1.1.1/lib/google/ads/google_ads/v1/services/keyword_plan_idea_service_client.rb:245:in `generate_keyword_ideas'
teste.rb:55:in `generate_keyword_ideas'
teste.rb:145:in `<main>'

GoogleAdsError never raised in v1

After the v1.0 update, a query with wrong arguments should expect the next error: Google::Ads::GoogleAds::Errors::GoogleAdsError
But it never raised and, instead, it raises a GRPC::InvalidArgument error.
Is this correct? Thanks.

Logs about request aren't appeared when don't use service created by factories

When I create CampaignService without factory functions, the output of the mutation doesn't contain descriptions of request.

> client.service(:GoogleAds)
=> #<Google::Ads::GoogleAds::V1::Services::GoogleAdsServiceClient:0x00007fd00afd6d30
 @google_ads_service_stub=
  #<Google::Ads::GoogleAds::V1::Services::GoogleAdsService::Stub:0x00007fd00afb4bb8
   @ch=#<GRPC::Core::Channel:0x00007fd00ccb1478>,
   @host="googleads.googleapis.com:443",
   @interceptors=#<GRPC::InterceptorRegistry:0x00007fd00afb4a00 @interceptors=[]>,
   @propagate_mask=nil,
   @timeout=1970-01-01 08:59:59 +0900>,
 @mutate=#<Proc:0x00007fd00afb45c8@/Users/.../vendor/bundle/gems/google-gax-1.5.0/lib/google/gax/api_callable.rb:246>,
 @search=#<Proc:0x00007fd00afb4758@/Users/.../vendor/bundle/gems/google-gax-1.5.0/lib/google/gax/api_callable.rb:246>>

> client.service(:GoogleAds).search(client_id, 'SELECT campaign.name FROM campaign', page_size: 1000)
=> #<Google::Gax::PagedEnumerable:0x00007fd009c80790
 @func=#<Proc:0x00007fd009c7b588@/Users/.../vendor/bundle/gems/google-gax-1.5.0/lib/google/gax/api_callable.rb:353>,
 @page=
  #<Google::Gax::PagedEnumerable::Page:0x00007fd007897e00
   @resource_field="results",
   @response=
    <Google::Ads::GoogleAds::V1::Services::SearchGoogleAdsResponse: results: [<Google::Ads::GoogleAds::V1::Services::GoogleAdsRow: customer: nil, campaign: <Google::Ads::GoogleAds::V1::Resources::Campaign: resource_name: "customers/...">]>
   @response_page_token_field="next_page_token">,
 @request=<Google::Ads::GoogleAds::V1::Services::SearchGoogleAdsRequest: customer_id: "...", query: "SELECT campaign.name FROM campaign", page_token: "", page_size: 1000, validate_only: false>,
 @request_page_token_field="page_token">

On the other hand, when I do same thing with factory function, then I obtain descriptions of request in the outputs.

> client.service.google_ads
=> #<#<Class:0x00007fd00caa9388>:0x00007fd00caa9040
 @google_ads_service_stub=
  #<Google::Ads::GoogleAds::V1::Services::GoogleAdsService::Stub:0x00007fd00af1d740
   @ch=#<GRPC::Core::Channel:0x00007fd00caa9dd8>,
   @host="googleads.googleapis.com:443",
   @interceptors=
    #<GRPC::InterceptorRegistry:0x00007fd00af1d588
     @interceptors=
      [#<Google::Ads::GoogleAds::LoggingInterceptor:0x00007fd00caa9cc0
        @logger=
         #<ActiveSupport::Logger:0x00007fd00c9a3380
          @default_formatter=#<Logger::Formatter:0x00007fd00c9a32e0 @datetime_format=nil>,
          @formatter=#<ActiveSupport::Logger::SimpleFormatter:0x00007fd00ca931c8 @datetime_format=nil, @thread_key="activesupport_tagged_logging_tags:70265771170020">,
          @level=0,
          @local_levels=#<Concurrent::Map:0x00007fd00c9a3178 entries=0 default_proc=nil>,
          @logdev=
           #<Logger::LogDevice:0x00007fd00c9a3290
            @dev=#<File:/Users/.../log/development.log>,
            @filename=nil,
            @mon_count=0,
            @mon_mutex=#<Thread::Mutex:0x00007fd00c9a3218>,
            @mon_owner=nil,
            @shift_age=nil,
            @shift_period_suffix=nil,
            @shift_size=nil>,
          @progname=nil>,
        @options={}>]>,
   @propagate_mask=nil,
   @timeout=1970-01-01 08:59:59 +0900>,
 @mutate=#<Proc:0x00007fd00af1d218@/Users/.../vendor/bundle/gems/google-gax-1.5.0/lib/google/gax/api_callable.rb:246>,
 @search=#<Proc:0x00007fd00af1d330@/Users/.../vendor/bundle/gems/google-gax-1.5.0/lib/google/gax/api_callable.rb:246>>

> client.service.google_ads.search(client_id, 'SELECT campaign.name FROM campaign', page_size: 1000)
CID: ..., Host: googleads.googleapis.com:443, Method: /google.ads.googleads.v1.services.GoogleAdsService/Search, IsFault: no
Outgoing request: Headers: {"x-goog-api-client":"gl-ruby/2.5.5 gapic/2.4.1 gax/1.5.0 grpc/1.21.0","developer-token":"...","login-customer-id":"..."} Payload: {"customerId":"...","query":"SELECT campaign.name FROM campaign","pageSize":1000}
Incoming response: Payload: {"results":[{"campaign":{"resourceName":"customers/.../campaigns/...","name":"..."}},...
=> #<Google::Gax::PagedEnumerable:0x00007fd00c8f0f28
 @func=#<Proc:0x00007fd00c8eae70@/Users/.../gax/api_callable.rb:353>,
 @page=
  #<Google::Gax::PagedEnumerable::Page:0x00007fd00c889238
   @resource_field="results",
   @response=
    <Google::Ads::GoogleAds::V1::Services::SearchGoogleAdsResponse: results: [<Google::Ads::GoogleAds::V1::Services::GoogleAdsRow: customer: nil, campaign: <Google::Ads::GoogleAds::V1::Resources::Campaign: resource_name: "customers/...">]
   @response_page_token_field="next_page_token">,
 @request=<Google::Ads::GoogleAds::V1::Services::SearchGoogleAdsRequest: customer_id: "...", query: "SELECT campaign.name FROM campaign", page_token: "", page_size: 1000, validate_only: false>,
 @request_page_token_field="page_token">

I think those changes might cause the problem. It looks like failed to insert logger.

CampaignDraftService is missing from ruby client library v1.1.1

I wanted to create a campaign experiment and as the first step I need to create a draft campaign. The document says there is CampaignDraftService but the client is missing this service

@client.service(:CampaignDraft)
=> No service found with name CampaignDraft

LoggingInterceptor crashes due missing `request.customer_id` for `get_campaign_budget`

With google-gax v1.5.0

This code is crashing for us:

def request_response(request:, call:, method:, metadata: {})
summary_message =
sprintf("CID: %s, Host: %s, Method: %s",
request.customer_id,
call.instance_variable_get('@wrapped').peer,
method
)

When we call service.get_campaign_budget("customers/#{id1}/campaignBudgets/#{id2}"):

def get_campaign_budget \
resource_name,
options: nil,
&block
req = {
resource_name: resource_name
}.delete_if { |_, v| v.nil? }
req = Google::Gax::to_proto(req, Google::Ads::GoogleAds::V0::Services::GetCampaignBudgetRequest)
@get_campaign_budget.call(req, options, &block)
end

Because Google::Gax::to_proto is not returning an object that responds to customer_id:

[7] pry(#<#<Class:0x00000000068d0300>>)> Google::Gax::to_proto({resource_name: resource_name}, Google::Ads::GoogleAds::V0::Services::GetCampaignBudgetRequest)
=> <Google::Ads::GoogleAds::V0::Services::GetCampaignBudgetRequest: resource_name: "customers/REMOVED_ID1/campaignBudgets/REMOVED_ID2">

compatible versions for gem "faraday"

Bundler could not find compatible versions for gem "faraday". This gem requires minimum v0.12 for faraday and I am using some other gems which require lesser version for faraday, due to which I am unable to install it in my rails application.

inserting 2 different campaign criterions for the same campaign

I created a campaign and inserted a campaign criterion of type LOCATION = US for the it, it was performed successfully. Then I inserted a criterion of type LANGUAGE = English for it which also was performed successfully. But the original LOCATION criterion was deleted.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.