Posts tagged with java

I'm trying to create a remarketing userList add some users into it using the Java implementation for Google Ads Api.

The custom audience creation part looks fine, I can see it created in the Ads plataform, but looks like the users wasn't included into it.

Print screen: Empty custom audience inside google ads plataform

I'm sending a JsonArray with 2000 user as parameter and hashing it inside this function, and used this samples as reference.

I'm not sure if I misunderstood the documentation or if I'm including the userList in a wrong way or anything like that.

    public JsonArray uploadJsonList(String customerId, JsonArray jsonUsers) throws Exception {                List<Member> members = new ArrayList<>();         JsonObject hashedObj = new JsonObject();         JsonArray arrayJsonHashed = new JsonArray();                          for (JsonValue jsonValue : jsonUsers) {                          JsonObject obj = jsonValue.asObject();             hashedObj = new JsonObject();                          //Getting user data             String normalizedEmail = textUtils.toNormalizedString(obj.get("PESSOA_EMAIL1").toString());             String normalizedPhone = textUtils.toNormalizedString(obj.get("PESSOA_CELULAR").toString());              String normalizedId = obj.get("PESSOA_ID").toString();              normalizedId = removeFirstandLast(normalizedId);                      //Hashing user data             hashedObj.add("pessoa_email1", textUtils.toSHA256String(normalizedEmail));             hashedObj.add("pessoa_celular", textUtils.toSHA256String(normalizedPhone));             hashedObj.add("pessoa_id",normalizedId);             arrayJsonHashed.add(hashedObj);                          //Creating a member list             Member member = new Member();             member.setHashedEmail(textUtils.toSHA256String(normalizedEmail));             member.setHashedPhoneNumber(textUtils.toSHA256String(normalizedPhone));             members.add(member);                  }                  //starting ads services         AdWordsServices adWordsServices = new AdWordsServices();         Customer[] customers = getCustomers(adWordsServices, session);         session.setClientCustomerId(customerId);         AdwordsUserListServiceInterface userListService = adWordsServices.get(session, AdwordsUserListServiceInterface.class);                  // Create a user list.         CrmBasedUserList userList = new CrmBasedUserList();         userList.setName("Test Remarketing Custom Audience - " + System.currentTimeMillis());         userList.setDescription("A list of customers that was readed from big query");                  // CRM-based user lists can use a membershipLifeSpan of 10000 to indicate unlimited; otherwise         // normal values apply.         userList.setMembershipLifeSpan(100L);         userList.setUploadKeyType(CustomerMatchUploadKeyType.CONTACT_INFO);                                  // Create operation.         UserListOperation operation = new UserListOperation();         operation.setOperand(userList);         operation.setOperator(Operator.ADD);         // Add user list.         UserListReturnValue result = userListService.mutate(new UserListOperation[]{operation});         // Display user list.         UserList userListAdded = result.getValue(0);         System.out.printf(                 "User list with name '%s' and ID %d was added.%n",                 userListAdded.getName(), userListAdded.getId());         // Get user list ID.         Long userListId = userListAdded.getId();         // Create operation to add members to the user list based on email addresses.         MutateMembersOperation mutateMembersOperation = new MutateMembersOperation();         MutateMembersOperand operand = new MutateMembersOperand();         operand.setUserListId(userListId);         operand.setMembersList(members.toArray(new Member[members.size()]));                     mutateMembersOperation.setOperand(operand);         mutateMembersOperation.setOperator(Operator.ADD);                  // Add members to the user list based on email addresses.         MutateMembersReturnValue mutateMembersResult =                 userListService.mutateMembers(new MutateMembersOperation[]{mutateMembersOperation});         // Display results.         // Reminder: it may take several hours for the list to be populated with members.         for (UserList userListResult : mutateMembersResult.getUserLists()) {             System.out.printf(                     "%d email addresses were uploaded to user list with name '%s' and ID %d "                             + "and are scheduled for review.%n",                             members.size(), userListResult.getName(), userListResult.getId());         }                          return arrayJsonHashed;     } 

I want to use Google Ads API with service account I managed to create a session using this Java code configuration:

ClassLoader classLoader = this.getClass().getClassLoader();         File configFile = new File(classLoader.getResource("ads.properties").getFile());         GoogleAdsClient googleAdsClient = GoogleAdsClient.newBuilder()                 .fromEnvironment()                 .fromPropertiesFile(configFile)                 .build();         GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient(); 

I want to use this connection to make a request using this code:

AdWordsSession session = null;         try {             // Generate a refreshable OAuth2 credential.             Credential oAuth2Credential = new OfflineCredentials.Builder()                             .forApi(Api.ADWORDS)                             .fromFile()                             .build()                             .generateCredential();             // Construct an AdWordsSession.             session =                     new AdWordsSession.Builder().fromFile().build();         } catch (ConfigurationLoadException cle) {             System.err.printf(                     "Failed to load configuration from the %s file. Exception: %s%n",                     DEFAULT_CONFIGURATION_FILENAME, cle);             return;         } catch (ValidationException ve) {             System.err.printf(                     "Invalid configuration in the %s file. Exception: %s%n",                     DEFAULT_CONFIGURATION_FILENAME, ve);             return;         } catch (OAuthException oe) {             System.err.printf(                     "Failed to create OAuth credentials. Check OAuth settings in the %s file. "                             + "Exception: %s%n",                     DEFAULT_CONFIGURATION_FILENAME, oe);             return;         }         AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();         try {             runExample(adWordsServices, session);         } catch (ApiException apiException) {             System.err.println("Request failed due to ApiException. Underlying ApiErrors:");             if (apiException.getErrors() != null) {                 int i = 0;                 for (ApiError apiError : apiException.getErrors()) {                     System.err.printf("  Error %d: %s%n", i++, apiError);                 }             }         } catch (RemoteException re) {             System.err.printf(                     "Request failed unexpectedly due to RemoteException: %s%n", re);         } 

AdWordsServicesInterface adWordsServices, AdWordsSession session) throws RemoteException { // Get the TrafficEstimatorService. TrafficEstimatorServiceInterface trafficEstimatorService = adWordsServices.get(session, TrafficEstimatorServiceInterface.class);

Full source: https://developers.google.com/adwords/api/docs/samples/java/basic-operations

Do you know how I can use service account into the above code?

We've followed the advice given here: https://developers.google.com/google-ads/api/docs/client-libs/java/logging

Neither of the proposed solutions have any visible effect on what is logged to the console, either in dev or in deployment.

Specifically:

  • added to pom.xml:

      <dependency>       <groupId>org.slf4j</groupId>       <artifactId>slf4j-log4j12</artifactId>       <version>1.7.25</version>   </dependency> 
  • added -Dlog4j.configuration=googleads-logging/log4j.properties to the launch command

no effect.

  • added to pom.xml:

      <dependency>       <groupId>org.slf4j</groupId>       <artifactId>slf4j-jdk14</artifactId>       <version>1.7.25</version>   </dependency> 
  • created jdk-logger.properties in various places, from example found here

  • added -Djava.util.logging.config.file= to the launch command

no effect whatsoever.

We are desperately trying to sort out this issue before Google sunsets the googleads v2 API on October 21. It would be really nice to see exactly what is happening, but so far all we've managed to determine is the endpoint server: googleads.googleapis.com:443

Any advice highly appreciated!

I am trying to connect to the google ads api using a service account. For analytics there is a good article named Hello Analytics API: Java quickstart for service accounts which explains how to set this up. For Google ads I can't find any documentation online.

So my two questions are:

  1. Is it possible to access the Google Ads API using a service account?
  2. If so, is there something like a Hello Ads API: Java quickstart for service accounts page with information on how to connect to the api with a service account?

UPDATE 2/10

I succeeded in passing the authentication fase. I do get an error when trying to fetch data from the API.

curl.exe --request POST "https://googleads.googleapis.com/v5/customers/******/googleAds:searchStream" --header "Content-Type: application/json"  --header "Authorization: Bearer ******"  --header "developer-token: ******"  --data "{'query': 'SELECT * FROM campaign WHERE segments.date DURING YESTERDAY'}" [{   "error": {     "code": 401,     "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",     "status": "UNAUTHENTICATED",     "details": [       {         "@type": "type.googleapis.com/google.ads.googleads.v5.errors.GoogleAdsFailure",         "errors": [           {             "errorCode": {               "authenticationError": "NOT_ADS_USER"             },             "message": "User in the cookie is not a valid Ads user."           }         ]       }     ]   } } ] 

The google docs say this error is because the account is not associated with an google ads account (https://developers.google.com/google-ads/api/docs/best-practices/common-errors#not_ads_user). The request are being processed by the api, I know this because the request are counted in the google ads api console as errors.

In the Credentials compatible with this API for the google ads Api my service account is listed. I am a little puzzled by the error. The service-account is associated with the google ads account as far as I could tell.