Image Ad Upload

413 views
Skip to first unread message

testa...@geeks.ltd.uk

unread,
Sep 25, 2014, 7:21:24 AM9/25/14
to adwor...@googlegroups.com
Hi All,

I am trying to use the following code, in C#, to upload some ImageAds to AdWords; however, it appears that I am using the wrong service. However, using a MediaService forces me to change method from mutate to upload, the argument from List<AdGroupAdOperation> to Media[], and then I have to change the type from ImageAd to Image, otherwise I can't put it in the array, and then I can't assign certain information, such as AdGroupId, which I need to specify.

Does anyone know where I'm going wrong or what I should be doing instead to achieve my goal of putting certain ImageAds in a certain AdGroup?

Thanks,
Conor

========================== Code ==========================
        var operations = new List<AdGroupAdOperation>();

        foreach (var generatedAd in generatedAds)
        {
            // create a new image to put in the imageAd
            var image = new Image
            {
                data = generatedAd.Image.FileData,
                type = MediaMediaType.IMAGE
            };

            // create a new image ad
            var imageAd = new ImageAd
            {
                image = image,
                displayUrl = DisplayURL,
                url = generatedAd.Ad.Url
            };

            var imageAdGroupAd = new AdGroupAd
            {
                adGroupId = (long)generatedAd.Ad.AdwordsAdGroupId
            };

            // prepare to add the new image ad to the ad words group
            var operation = new AdGroupAdOperation
            {
                @operator = Operator.ADD,
                operand = imageAdGroupAd
            };

            operations.Add(operation);
        }

        try
        {
            ((AdGroupAdService)user.GetService(AdWordsService.v201406.AdGroupAdService))
                .mutate(operations.ToArray());
        }
========================== Code ==========================

Anash P. Oommen (AdWords API Team)

unread,
Sep 25, 2014, 9:19:46 AM9/25/14
to adwor...@googlegroups.com
Hi,

To create an imageAd, you'd need to upload the image first using MediaService (see https://github.com/googleads/googleads-dotnet-lib/blob/master/examples/AdWords/CSharp/v201406/Miscellaneous/UploadImage.cs), then use that media id to create an image Ad.

Cheers,
Anash P. Oommen,
AdWords API Advisor.

testa...@geeks.ltd.uk

unread,
Sep 25, 2014, 10:26:52 AM9/25/14
to adwor...@googlegroups.com
HI Anash,

Thanks for your help. I am slightly lost though as to how to create an ImageAd, from start to finish. So I upload the Image to AdWords, and get the media id of that image. Then what do I do with it? I'm looking at the API here https://developers.google.com/adwords/api/docs/reference/v201406/AdGroupAdService.ImageAd and can't see where I should put the id. I also don't know what the following steps are.

I have downloaded the AdWords examples for C# but there are no references to ImageAd, so I can't see how it's done.

Thanks,
Conor

Anash P. Oommen (AdWords API Team)

unread,
Sep 26, 2014, 4:01:48 PM9/26/14
to adwor...@googlegroups.com
Hi Conor,

This is a code example from an old version of the client library. Let me know if it works for you.

      // Create your image ad.
      ImageAd imageAd = new ImageAd();
      imageAd.name = "My Image Ad";
      imageAd.displayUrl = "www.example.com";
      imageAd.url = "http://www.example.com";

      // Load your image into data field.
      string imageUrl = "https://sandbox.google.com/sandboximages/image.jpg";

      WebRequest request = HttpWebRequest.Create(imageUrl);
      WebResponse response = request.GetResponse();

      MemoryStream memStream = new MemoryStream();
      using (Stream responseStream = response.GetResponseStream()) {
        byte[] strmBuffer = new byte[4096];

        int bytesRead = responseStream.Read(strmBuffer, 0, 4096);
        while (bytesRead != 0) {
          memStream.Write(strmBuffer, 0, bytesRead);
          bytesRead = responseStream.Read(strmBuffer, 0, 4096);
        }
      }

      imageAd.image = new Image();
      imageAd.image.data = memStream.ToArray();

      // Set the AdGroup Id.
      AdGroupAd imageAdGroupAd = new AdGroupAd();
      imageAdGroupAd.adGroupId = adGroupId;
      imageAdGroupAd.adGroupIdSpecified = true;
      imageAdGroupAd.ad = imageAd;

Cheers,
Anash P. Oommen,
AdWords API Advisor.

testa...@geeks.ltd.uk

unread,
Sep 29, 2014, 5:53:10 AM9/29/14
to adwor...@googlegroups.com
Hi Anash,

Thank you for your reply. I made a couple of changes to my code, so it now looks like this:

        var operations = new List<AdGroupAdOperation>();

        foreach (var generatedAd in generatedAds)
        {
            // create a new image to put in the imageAd
            var image = new Image
            {
                data = generatedAd.Image.FileData,
                type = MediaMediaType.IMAGE
            };

            // create a new image ad
            var imageAd = new ImageAd
            {
                image = image,
                name = generatedAd.Image.FileName,
                displayUrl = Config.Get("DisplayURL"),
                url = generatedAd.Ad.Url
            };

            var imageAdGroupAd = new AdGroupAd
            {
                ad = imageAd,
                adGroupId = (long)generatedAd.Ad.AdwordsAdGroupId,
                
            };

            // prepare to add the new image ad to the ad words group
            var operation = new AdGroupAdOperation
            {
                @operator = Operator.ADD,
                operand = imageAdGroupAd
            };

            operations.Add(operation);
        }

        try
        {
            ((AdGroupAdService)user.GetService(AdWordsService.v201406.AdGroupAdService))
                .mutate(operations.ToArray());
        }

However, running this code now results in an exception being thrown. The main exception message is 'The underlying connection was closed: An unexpected error occurred on a send.', and the inner exception message is 'An existing connection was forcibly closed by the remote host.'. Have these errors come up before in AdWords? Is there a particular way to handle them?

Thanks,
Conor

Anash P. Oommen (AdWords API Team)

unread,
Sep 29, 2014, 9:20:47 AM9/29/14
to adwor...@googlegroups.com
Hi Conor,

See if you can replicate this one - connection getting closed is sometimes related to a bad ISP connection, sometimes it happens due to your calls happening when a server update is happening.

Cheers,
Anash P. Oommen,
AdWords API Advisor.

testa...@geeks.ltd.uk

unread,
Sep 29, 2014, 9:36:23 AM9/29/14
to adwor...@googlegroups.com
Hi Anash,

I have managed to replicate this error several times now. Same exception and inner exception each time. What should I do?

Thanks,
Conor

Anash P. Oommen (AdWords API Team)

unread,
Sep 29, 2014, 3:37:00 PM9/29/14
to adwor...@googlegroups.com
Hi Conor,

I'd need some additional details, please share them by using the "Reply to Author" option. DO NOT post any of these details online.

1. Your customer ids (client and API MCC accounts).
2. When was this call made? (timestamp)
3. Outgoing and incoming http request body. You can capture one using Fiddler (http://docs.telerik.com/fiddler/Configure-Fiddler/Tasks/FirefoxHTTPS)
4. Can you actually access the wsdl url from a browser? e.g. https://adwords.google.com/api/adwords/cm/v201406/CampaignService?wsdl
5. Provide the output when you do a tracert from your server to AdWords server. tracert adwords.google.com
6. What is your machine's IP? (output of ipconfig /all). Another option is to visit these urls and provide the output


Cheers,
Anash P. Oommen,
AdWords API Advisor.

testa...@geeks.ltd.uk

unread,
Oct 2, 2014, 8:49:54 AM10/2/14
to adwor...@googlegroups.com
Hi Anash,

Has there been any progress?

Thanks again for your help.

Best wishes,
Conor

testa...@geeks.ltd.uk

unread,
Oct 2, 2014, 12:20:40 PM10/2/14
to adwor...@googlegroups.com
Just as a note, on some occasions, the inner exception changes to 'Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.' rather than 'Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.'.

No pattern is immediately obvious to explain this.

Thanks,
Conor

testa...@geeks.ltd.uk

unread,
Oct 7, 2014, 7:04:09 AM10/7/14
to adwor...@googlegroups.com
For posterity, this was resolved by a combination of adding the following code to the web.config, as well as trying to upload fewer as in one go.

  <system.net>
    <settings>
      <servicePointManager expect100Continue="false"/>
    </settings>
  </system.net>

Thanks,
Conor

Anash P. Oommen (AdWords API Team)

unread,
Oct 8, 2014, 10:48:49 AM10/8/14
to adwor...@googlegroups.com
Hi Conor,

That's odd, are you sure you don't have a proxy in between that doesn't know how to handle Expect 100 continue headers? Not that it matters for the API server, just curious.

Cheers,
Anash
Reply all
Reply to author
Forward
0 new messages