Creating Mobile App Engaement Ads in bulk

148 views
Skip to first unread message

sebastia...@despegar.com

unread,
Aug 12, 2015, 10:12:46 AM8/12/15
to AdWords API Forum
Hello,
I have a couple of questions regarding the creation of Mobile App Engagement Ads.

1) As of my understanding, the AdWords Editor does not allow you to upload many Mobile App Engagement Ads in a bulk. Is that so?

2) Because of this limitation, we are going to use the AdWords API. Mobile App Engagment Ads can be created as TemplateAds. I have one question for this procedure: is iwhat Josh Radcliff said in this question still true?

"When creating a TemplateAd and providing an Image object, you must populated the Image.data attribute directly"

Is this the right way to use the API?
What if I need to upload 500 ads and all use the same image?

Thanks,
seb.

Josh Radcliff (AdWords API Team)

unread,
Aug 13, 2015, 3:02:51 PM8/13/15
to AdWords API Forum
Hi seb,

Have you tried using the TemplateAd.originAdId field to copy the image from the first TemplateAd? Using that approach, you could supply the Image.data directly on the first ad, then copy it over to all of the subsequent ads.

Thanks,
Josh, AdWords API Team

sebastia...@despegar.com

unread,
Aug 18, 2015, 8:52:41 AM8/18/15
to AdWords API Forum
Hi Josh,
I am trying to do what you said but I get the following error:

Exception in thread "main" AxisFault
 faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server
 faultSubcode:
 faultString: [InternalApiError.UNEXPECTED_INTERNAL_API_ERROR @ com.google.ads.api.services.common.error.InternalApiError.<init>(InternalApiErro]
 faultActor:
 faultNode:
 faultDetail:
    {https://adwords.google.com/api/adwords/cm/v201502}ApiExceptionFault:<message>[InternalApiError.UNEXPECTED_INTERNAL_API_ERROR @ com.google.ads.api.services.common.error.InternalApiError.&lt;init&gt;(InternalApiErro]</message><ApplicationException.Type>ApiException</ApplicationException.Type><errors xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="InternalApiError"><fieldPath/><trigger/><errorString>InternalApiError.UNEXPECTED_INTERNAL_API_ERROR</errorString><ApiError.Type>InternalApiError</ApiError.Type><reason>UNEXPECTED_INTERNAL_API_ERROR</reason></errors>

[InternalApiError.UNEXPECTED_INTERNAL_API_ERROR @ com.google.ads.api.services.common.error.InternalApiError.<init>(InternalApiErro]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at java.lang.Class.newInstance(Class.java:442)
    at org.apache.axis.encoding.ser.BeanDeserializer.<init>(BeanDeserializer.java:104)
    at org.apache.axis.encoding.ser.BeanDeserializer.<init>(BeanDeserializer.java:90)
    at com.google.api.ads.adwords.axis.v201502.cm.ApiException.getDeserializer(ApiException.java:143)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.axis.encoding.ser.BaseDeserializerFactory.getSpecialized(BaseDeserializerFactory.java:154)
    at org.apache.axis.encoding.ser.BaseDeserializerFactory.getDeserializerAs(BaseDeserializerFactory.java:84)
    at org.apache.axis.encoding.DeserializationContext.getDeserializer(DeserializationContext.java:464)
    at org.apache.axis.encoding.DeserializationContext.getDeserializerForType(DeserializationContext.java:547)
    at org.apache.axis.message.SOAPFaultDetailsBuilder.onStartChild(SOAPFaultDetailsBuilder.java:157)
    at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1035)
    at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl.parse(Unknown Source)
    at org.apache.axis.encoding.DeserializationContext.parse(DeserializationContext.java:227)
    at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:696)
    at org.apache.axis.Message.getSOAPEnvelope(Message.java:435)
    at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnderstandChecker.java:62)
    at org.apache.axis.client.AxisClient.invoke(AxisClient.java:206)
    at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
    at org.apache.axis.client.Call.invoke(Call.java:2767)
    at org.apache.axis.client.Call.invoke(Call.java:2443)
    at org.apache.axis.client.Call.invoke(Call.java:2366)
    at org.apache.axis.client.Call.invoke(Call.java:1812)
    at com.google.api.ads.adwords.axis.v201502.cm.AdGroupAdServiceSoapBindingStub.mutate(AdGroupAdServiceSoapBindingStub.java:1389)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.google.api.ads.common.lib.soap.SoapClientHandler.invoke(SoapClientHandler.java:110)
    at com.google.api.ads.common.lib.soap.axis.AxisHandler.invokeSoapCall(AxisHandler.java:221)
    at com.google.api.ads.common.lib.soap.SoapServiceClient.callSoapClient(SoapServiceClient.java:64)
    at com.google.api.ads.common.lib.soap.SoapServiceClient.invoke(SoapServiceClient.java:94)
    at com.sun.proxy.$Proxy14.mutate(Unknown Source)
    at com.despegar.sem.adwords.ads.mobile.TemplateAdUploader.main(TemplateAdUploader.java:60)

Josh Radcliff (AdWords API Team)

unread,
Aug 18, 2015, 8:56:53 AM8/18/15
to AdWords API Forum
Hi seb,

Could you send over the requestId from the response in that failed request? That will help me track down the root cause of the exception.

Thanks,
Josh, AdWords API Team

sebastia...@despegar.com

unread,
Aug 18, 2015, 9:11:02 AM8/18/15
to AdWords API Forum
Hi Josh,
My program fails right after calling AdGroupAdServiceInterface#mutate(AdGroupAdOperation[]) and I don't get a response.
I can send you the serialized Exception if you want (I could not attach it to this post).

Josh Radcliff (AdWords API Team)

unread,
Aug 18, 2015, 4:51:08 PM8/18/15
to AdWords API Forum
Hi seb,

Based on the logs I found, it looks like you are trying to create a TemplateAd with template ID 455. If so, could you elaborate on why an image is relevant here? The template fields for 455 do not include any IMAGE elements.

If I'm mistaken about which type of ad you're creating, could you send over your SOAP request? You can send it only to me clicking Reply privately to author on this post.

Thanks,
Josh, AdWords API Team

Josh Radcliff (AdWords API Team)

unread,
Aug 19, 2015, 1:43:33 PM8/19/15
to AdWords API Forum
Hi seb,

Thanks for sending more details to me privately. I noticed in your code that you are setting the adAsImage field, and that's the only place where you use an Image object. However, I'm pretty sure that the adAsImage field is being ignored since that field is meant to provide you a preview of the ad in image form, and that preview for template ID 455 is simply based on the other fields in the ad that identify your app.

Does the image you provided actually appear on the ad in the AdWords user interface?

Now to the other questions you sent over:
  • What would happen if I use this method to create 500 ads when they all use the same image?
    • Per the above, I don't think you actually need to specify the image for this template, but please let me know if you see otherwise.
    • In general, if you are creating a large # of similar ads (e.g., all for the same app), you can use the originAdId to specify an existing ad to copy from. You'll still have to supply some required fields in the new TemplateAd. Based on experimentation, it looks like the minimal set of fields is: name, displayUrl, finalUrls
  • Is there a way to upload the image only once via any other method (such as with the MediaServiceInterface) and reuse it?
    • You can upload images (but not audio or video) using MediaService.upload, then you should be able to use the resulting Media.mediaId value when creating other TemplateAds. Note that this will not work for creating ImageAds.
  • Is it possible to upload ads in a bulk via AdWords Editor?
    • Unfortunately, I'm not an AdWords Editor expert. You may want to post this question to the AdWords Community to see if the (non-API) product experts there have any suggestions.

Thanks,
Josh, AdWords API Team

sebastia...@despegar.com

unread,
Aug 20, 2015, 7:45:50 AM8/20/15
to AdWords API Forum
Hi Josh,


I noticed in your code that you are setting the adAsImage field, and that's the only place where you use an Image object. However, I'm pretty sure that the adAsImage field is being ignored since that field is meant to provide you a preview of the ad in image form, and that preview for template ID 455 is simply based on the other fields in the ad that identify your app.
Does the image you provided actually appear on the ad in the AdWords user interface?
 
No it doesn't, but the UI doesn't show the image when I create one manually either. If I download the report for two "Image app engagement ad's", one created manually via the AdWords UI and one created automatically with the program I sent you the structure is the same. These arguments seem to favor, in my view, that the adAsIamge is not being ignored.

In general, if you are creating a large # of similar ads (e.g., all for the same app), you can use the originAdId to specify an existing ad to copy from.
 
Right. But I had the Error I posted two posts ago.


You can upload images (but not audio or video) using MediaService.upload, then you should be able to use the resulting Media.mediaId value when creating other TemplateAds. Note that this will not work for creating ImageAds.

Good. This is also what the API reference says. I tried it and it doesn't work though.

I must have not explained my problem very clearly so I would like to go straight down to the point with the next question.
Can you give me a proper example on how to create an "Image app engagement ad" for an AdGroup within a "Display Network only - Mobile app engagement"-Campaign? As you said, the program I sent you does not reflect the proper usage of the API for this goal.

sebastia...@despegar.com

unread,
Aug 20, 2015, 9:15:38 AM8/20/15
to AdWords API Forum


El jueves, 20 de agosto de 2015, 8:45:50 (UTC-3), sebastia...@despegar.com escribió:
Hi Josh,

I noticed in your code that you are setting the adAsImage field, and that's the only place where you use an Image object. However, I'm pretty sure that the adAsImage field is being ignored since that field is meant to provide you a preview of the ad in image form, and that preview for template ID 455 is simply based on the other fields in the ad that identify your app.
Does the image you provided actually appear on the ad in the AdWords user interface?
 
No it doesn't, but the UI doesn't show the image when I create one manually either. If I download the report for two "Image app engagement ad's", one created manually via the AdWords UI and one created automatically with the program I sent you the structure is the same. These arguments seem to favor, in my view, that the adAsIamge is not being ignored.

UPDATE:
Yes, it does show the image in the AdWords UI. Initially when I said no was because I was using Firefox, but in Chrome it does show the image in both cases (manually created Ad, and created with the program I sent you).

Josh Radcliff (AdWords API Team)

unread,
Aug 20, 2015, 2:46:55 PM8/20/15
to AdWords API Forum
Hi,

I finally get it. :) The key points are:
  1. For the Image app engagement ad (455) and Image app install ad (432), you must set the Image for the ad via the TemplateAd.adAsImage attribute, as you were doing in your code.
  2. When setting the Image, you should be able to simply pass an Image object with its mediaId set to an existing image in order to reuse that image. Unfortunately, this doesn't work right now. I have raised this issue and we're looking into it.
  3. Although using mediaId doesn't work, I have good news! You can set originAdId to an existing ad that uses the same template, and AdWords will copy all of the template elements and the Image from the origin ad to your new ad.
#3 means that for your use case of creating 500 ads, you can create one ad by setting the Image.data and using that for the adAsImage field. To create the other 499 ads, you can specify the first ad's ID for originAdId, and skip the rest. This will work even if you are creating ads in a different ad group from the first ad.

Note that when creating the TemplateAds using originAdId, you should do the following:
  • set url, displayUrl, templateId, name, and originAdId
  • do not set templateElements, dimensions, or adAsImage
I think that covers everything, but let me know if you still have questions. Thanks for bearing with me while I was trying to understand your use case. :)

Cheers,
Josh, AdWords API Team

sebastia...@despegar.com

unread,
Aug 21, 2015, 7:09:33 AM8/21/15
to AdWords API Forum
Hi Josh,

OK, I see we are finally talking about the same use case.

I tried using originAdId and now it seems to work (although when I had the error I posted before I was doing the exact same thing and got an "InternalApiError.UNEXPECTED_INTERNAL_API_ERROR"; maybe it was another problem from our side).



When setting the Image, you should be able to simply pass an Image object with its mediaId set to an existing image in order to reuse that image. Unfortunately, this doesn't work right now. I have raised this issue and we're looking into it.

I'm glad that you have a new issue for this. I think it's the most intuitive way to reuse media, and also this will be consistent with the API reference.

Thanks for your guidance on how to use the API properly,
seb.

sebastia...@despegar.com

unread,
Aug 28, 2015, 7:36:21 AM8/28/15
to AdWords API Forum
Hello again,
I am having a problem after I upload "App Engagement Image Ads" and "App Engagement Text Ads",
From th AdWords UI I can see they are created but the preview can no longer be shown when I click "View full size display ad." I attach an image to this post with the error message I am getting.
This used to work a couple of days ago after I uploaded Ads with the same program. Is it possible that I am not uploading well-formed ad's and this is the reason the UI cannot generate a preview for them?
Strangely enough, when I click the ad to modify it, I can click "save" and after I do that the UI becomes able to show the preview. Can somebody explain this to me?
error.png

sebastia...@despegar.com

unread,
Aug 28, 2015, 11:21:27 AM8/28/15
to AdWords API Forum
I also have a problem when creating "App Engagement Text Ads".
Apparently the "Call to Action" field is loaded correctly but when shown in the preview it is not refresh accordingly. I attach an image  this post so you can understand the problem. In the image, where it says "INSTALL" it should say what the "Call to Action" field says, but this is not what I get.
calltoaction.png

sebastia...@despegar.com

unread,
Aug 28, 2015, 11:44:27 AM8/28/15
to AdWords API Forum
I started a new question with these new problems here.
Reply all
Reply to author
Forward
0 new messages