Probably most of you have heard about AdSense, the ad serving program run by Google. It is very simple to have a website to display ads using AdSense, as you only need to include an external script with a few parameters (that mainly configure the size and colors of the ads). For each click in a banner of the website, the associated AdSense account gets a bit of money.
However, this is not the only way to get AdSense in your pages. Google has the "AdSense API", which consists in several web services that allow sharing the revenue of the banners between the website owner and the content publisher. That way, website with user generated content can pay their users if their content is useful.
A customer asked me to modify their website so they can share some of the benefits of their banners with the creators of the articles in their site using the AdSense API. I’ll detail some of my experiences with the integration of the AdSense API in the webpage.
As I had to deal with web services, and I was comfortable with the web service support present in the .NET Framework 2.0, the easiest thing to do for me was to follow that route. However, I always try to learn new stuff when I can, so it was an excellent chance for me to learn WCF. Creating a proxy for a web service in WCF is as easy as in .NET Framework 2.0. However, the problems started really soon. For some unknown reason, the Google guys require some SOAP headers in the web service calls that are not exposed in the AdSense’s WSDL. Reading some of the comments in the AdSense Group revealed that the SOAP headers were exposed previously but they were removed without giving any reason. I found this to be really annoying and. It can be fixed adding the headers to the OutgoingMessageHeaders in the current OperationScope. Only for this detail the Adsense API can be labeled as unfriendly for the developers.
Once you set the headers manually, it is easy to call to the different methods to create AdSense accounts, associate them with a publisher and generate the code to display ads. However, I found very confusing some parts of the documentation, specially all the ids available (you end up using clientId, publisherId, synServiceId, developerId, and in some methods having to pass the same id twice).
Inspecting the generated code for the WCF proxy, I found one thing I didn’t like about WCF. The DataContractSerializer does not handle bare arrays, so the generated code was using the XmlSerializer for a lot of things that need directly or indirectly to handle bare arrays in the AdSense API. The official statement of Microsoft about this seems to be that bare arrays do not support the distinction between null arrays and empty arrays, so the best is to use a wrapped collection.
The AdSense API has a technical requirements page that informs you how to proceed in some interactions with the users and how to react to error conditions. The AdSense API methods expose the fault details as specified in the AdSenseApiException. When an error happens when your WCF proxy is calling to the AdSense API, a FaultException is generated. I was expecting the proxy to receive a FaultException< AdSenseApiException> instead so I could easily access to the exception details but that wasn’t the case (maybe that only works in WCF to WCF scenarios?). I tried to create a generic error handler in order to convert the SOAP faults to the FaultException<AdSenseApiException> type, but the information I found about WCF error handling in the web was only talking about server side error handling using the IErrorHandler interface. It was clear that I needed more in depth knowledge of WCF in order to do that. After some research I bought Inside Windows Communication Foundation:
The book was exactly what I was looking for. Good and detailed internal information about how WCF worked.
Thanks to the book I was able to make my proxy generate the FaultException<AdSenseApiException> transparently, but it wasn’t easy. Well, it is not difficult but you have to create a lot of classes to do something simple.
A channel exposes a method called GetProperty<T>. When an exception is generated in the channel, the GetProperty<T> method is called with a parameter of type FaultConverter. The method should return an an instance of a FaultConverter, which creates the appropriate exception/fault type. To solve my problem I created an AdSenseFaultConverter:
However, in order to expose the AdSenseFaultConverter I had to create a ChannelFactory (AdSenseChannelFactory), a channel (AdSenseChannelBase and AdSenseRequestChannel), a Binding (AdSenseHttpBinding), and a BindingElement (AdSenseBindingElement). A lot of classes with little added value just to override the GetProperty<T> method in the channel. Also, to be able to use the configuration instead of setting up the communication programmatically, I had to create a configuration BindingElement(AdSenseHttpBindingElement) and a CollectionBindingElement (AdSenseHttpBindingCollectionElement). As I said before, it is a lot of code.
One thing that I haven’t commented yet is that your AdSense API implementation needs to be reviewed in order to be able to serve live ads, and you need to follow some policy requirements that you need to carefully study as they want to control even the help pages you put in your web site. One of the requirements to be eligible to participate in the AdSense API program is to have more than 100000 daily page views. This is a showstopper for most of the web sites making the AdSense API useless for 99.9% of the people.
Another negative point of the AdSense API is that the WSDL has been broken for more than a month. I planned to write this article a couple of months ago so I don’t know if the WSDL of the AdSense API is still invalid or not, but having it broken for more than a month can give you an idea of the overall satisfaction I have with the AdSense API.
To finish talking about the AdSense API, I have to mention the Sandbox. The development web services don’t behave exactly as the live web services (something that I hate), so some methods need to have additional headers when testing the API to work properly. Why? Well, basically because they do not have a decent sandbox. They just have the development version of the web services and you have to live with that. No GUI for managing the developers accounts, payments or something similar to the AdSense account webpage. If you compare this to other sandboxes like the paypal one where you can even receive the IPN confirmation messages you can clearly see the difference.
And the last rant of the post is about Google policies regarding to AdWords and AdSense. If you are an European citizen and you want to advertise using AdWords, Google forces you to pay in Euros. However, when you have AdSense in your page, Google will pay you in dollars. Judging by the prices of the ads in AdWords and the money you receive with AdSense, Google is taking advantage of the European citizens by charging a 60% more for an ad in AdWords and paying a 60% less for it (the exchange rate is approximately 1 euro = 1.60 dollars). Is the European commission too busy fining Microsoft for including free products with Windows to investigate things like this?
To sum up, I’m completely disappointed with Google and their AdSense API. If some people ever had the illusion that Google was a non evil company that did the things the right way, they need to wake up.