Editor's note: this announcement is cross-posted from the Google Ads Developer Blog, which caters to AdWords, AdSense, DoubleClick and AdMob developers. We hope you enjoy this latest addition to Google Apps Script — Ryan Boyd
Starting today, the AdSense Management API is available as part of AdSense Services in Google Apps Script. This means that you’ll be able to do things like:
Accessing the API from Google Apps Scripts is very easy. The following snippet of code shows how to generate a report and populate columns of a spreadsheet with the data retrieved:
function generateReport() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheetByName('Reports'); var startDate = Browser.inputBox( "Enter a start date (format: 'yyyy-mm-dd')"); var endDate = Browser.inputBox( "Enter an end date (format: 'yyyy-mm-dd')"); var args = { 'metric': ['PAGE_VIEWS', 'AD_REQUESTS', 'MATCHED_AD_REQUESTS', 'INDIVIDUAL_AD_IMPRESSIONS'], 'dimension': ['MONTH']}; var report = AdSense.Reports.generate(startDate, endDate, args).getRows(); for (var i=0; i<report.length; i++) { var row = report[i]; sheet.getRange('A' + String(i+2)).setValue(row[0]); sheet.getRange('B' + String(i+2)).setValue(row[1]); sheet.getRange('C' + String(i+2)).setValue(row[2]); sheet.getRange('D' + String(i+2)).setValue(row[3]); sheet.getRange('E' + String(i+2)).setValue(row[4]); } }
function generateLineChart() { var doc = SpreadsheetApp.getActiveSpreadsheet(); var startDate = Browser.inputBox( "Enter a start date (format: 'yyyy-mm-dd')"); var endDate = Browser.inputBox( "Enter an end date (format: 'yyyy-mm-dd')"); var adClientId = Browser.inputBox("Enter an ad client id"); var args = { 'filter': ['AD_CLIENT_ID==' + adClientId], 'metric': ['PAGE_VIEWS', 'AD_REQUESTS', 'MATCHED_AD_REQUESTS', 'INDIVIDUAL_AD_IMPRESSIONS'], 'dimension': ['MONTH']}; var report = AdSense.Reports.generate(startDate, endDate, args).getRows(); var data = Charts.newDataTable() .addColumn(Charts.ColumnType.STRING, "Month") .addColumn(Charts.ColumnType.NUMBER, "Page views") .addColumn(Charts.ColumnType.NUMBER, "Ad requests") .addColumn(Charts.ColumnType.NUMBER, "Matched ad requests") .addColumn(Charts.ColumnType.NUMBER, "Individual ad impressions"); // Convert the metrics to numeric values. for (var i=0; i<report.length; i++) { var row = report[i]; data.addRow([row[0],parseInt(row[1]),parseInt(row[2]), parseInt(row[3]),parseInt(row[4])]); } data.build(); var chart = Charts.newLineChart() .setDataTable(data) .setTitle("Performances per Month") .build(); var app = UiApp.createApplication().setTitle("Performances"); var panel = app.createVerticalPanel() .setHeight('350') .setWidth('700'); panel.add(chart); app.add(panel); doc.show(app); }
Google Apps domain administrators have access to a number of APIs to automate their management activities or to integrate with third-party applications, including the Provisioning API to manage user accounts and groups, the Admin Audit API, Admin Settings API, and the Reporting API.
These APIs were only available in Google Apps for Business, Education and ISP editions but many administrators of the free version of Google Apps also requested access to them. I’m glad to say that we listened to your feedback and, starting today, we made the these APIs available to all Google Apps editions.
Please check the documentation as the starting point to explore the possibilities of the APIs and post on our forum if you have questions or comments.
When we launched the Google Apps Marketplace in March last year, one of our goals was to make it easy for developers to build, integrate, and sell their apps to Google Apps users. Since then, each vendor in the Google Apps Marketplace has handled their own billing and keeps the revenue they generate. Today, we are making that the official Marketplace policy moving forward: Google will not require vendors to adopt a Google billing API or share any portion of their revenue with us. This will keep more revenue in developers’ pockets, and brings the Google Apps Marketplace policy in line with the Chrome Web Store.
So it’s business as usual -- developers can continue to “bring their own billing” to the Marketplace. Developers retain full control over application pricing and billing, and continue to keep all revenue from Google Apps Marketplace customers.
If you’re in need of a billing solution, we encourage you to try Google Checkout and In-App Payments. Or use one of the many other commercial billing and subscription services available online.
Please join us at our next Google Apps Developer Office Hours on Google+ Hangouts on December 19th at 12 PM PST time to discuss the Google Apps Marketplace and any questions you may have about these changes.
2-Legged OAuth is a useful authorization mechanism for apps that need to manipulate calendars on behalf of users in an organization. Both developers building apps for the Google Apps Marketplace and domain administrators writing tools for their own domains can benefit. Let’s take a look at how to do this with the new Calendar API v3 and Java client library 1.6.0 beta.
To get started as a domain administrator, you need to explicitly enable the new Google Calendar API scopes under Google Apps cPanel > Advanced tools > Manage your OAuth access > Manage third party OAuth Client access:
The scope to include is:
https://www.googleapis.com/auth/calendar
To do the same for a Marketplace app, include the scope in your application's manifest.
Calendar API v3 also needs an API access key that can be retrieved in the APIs Console. Once these requirements are taken care of, a new Calendar service object can be initialized:
public Calendar buildService() { HttpTransport transport = AndroidHttp.newCompatibleTransport(); JacksonFactory jsonFactory = new JacksonFactory(); // The 2-LO authorization section OAuthHmacSigner signer = new OAuthHmacSigner(); signer.clientSharedSecret = "<CONSUMER_SECRET>"; final OAuthParameters oauthParameters = new OAuthParameters(); oauthParameters.version = "1"; oauthParameters.consumerKey = "<CONSUMER_KEY>"; oauthParameters.signer = signer; Calendar service = Calendar.builder(transport, jsonFactory) .setApplicationName("<YOUR_APPLICATION_NAME>") .setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() { @Override public void initialize(JsonHttpRequest request) { CalendarRequest calendarRequest = (CalendarRequest) request; calendarRequest.setKey("<YOUR_API_KEY>"); } }).setHttpRequestInitializer(oauthParameters).build(); return service; }
Once the Calendar service object is properly initialized, it can be used to send authorized requests to the API. To access calendar data for a particular user, set the query parameter xoauth_requestor_id to a user’s email address:
xoauth_requestor_id
public void printEvents() { Calendar service = buildService(); // Add the xoauth_requestor_id query parameter to let the API know // on behalf of which user the request is being made. ArrayMap customKeys = new ArrayMap(); customKeys.add("xoauth_requestor_id", "<USER_EMAIL_ADDRESS>"); List listEventsOperation = service.events().list("primary"); listEventsOperation.setUnknownKeys(customKeys); Events events = listEventsOperation.execute(); for (Event event : events.getItems()) { System.out.println("Event: " + event.getSummary()); } }
Additionally, if the same service will be used to send requests on behalf of the same user, the xoauth_requestor_id query parameter can be set in the initializer:
// … Calendar service = Calendar.builder(transport, jsonFactory) .setApplicationName("<YOUR_APPLICATION_NAME>") .setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() { @Override public void initialize(JsonHttpRequest request) { ArrayMap customKeys = new ArrayMap(); customKeys.add("xoauth_requestor_id", "<USER_EMAIL_ADDRESS>"); calendarRequest.setKey("<YOUR_API_KEY>"); calendarRequest.setUnknownKeys(customKeys); } }).setHttpRequestInitializer(oauthParameters).build(); // ...
We hope you’ll try out 2-Legged OAuth and let us know what you think in the Google Calendar API forum.
With the Google Documents List API, there are two ways to identify resources: typed and untyped resource identifiers. Typed resource identifiers prefix a string of characters with the resource type. Untyped resource identifiers are similar, but do not have a type prefix. For example:
drawing:0Aj01z0xcb9
0Aj01z0xcb9
Client applications often need one type of identifier or the other. For instance, some applications use untyped resource IDs to access spreadsheets using the Google Spreadsheets API. Automatically generated API URLs in the Documents List API use typed or untyped resource IDs in certain situations.
Having two types of resource IDs is something that we will resolve in a future version of the API. Meanwhile, we strongly recommend that instead of using resource identifiers, clients always use URLs provided in feeds and entries of the Google Documents List API. The only time that manual URL modification is required is to add special parameters to a URL given by the API, for instance to search for a resource by title.
For example, the API issues self links along with each entry. To request an entry again, simply GET the self link of the entry. We recommend against constructing the link manually, by inserting the entry’s resource ID into the link.
Common links on entries include:
Accessing these links from a client library is simple. For instance, to retrieve the alternate link in Python, one uses:
resource = client.GetAllResources()[0] print resource.GetHtmlLink()
More information on these links is available in the documentation. For any questions, please post in the forum.
$apiClient = new apiClient(); $apiClient->setUseObjects(true);
$event = $service->events->get("primary", "eventId"); echo $event->getSummary();
result = client.execute( :api_method => service.events.get, :parameters => {'calendarId' => 'primary', 'eventId' => 'eventId'}) print result.data.summary
import randomimport timedef GetResourcesWithExponentialBackoff(client): """Gets all of the resources for the authorized user Args: client: gdata.docs.client.DocsClient authorized for a user. Returns: gdata.docs.data.ResourceFeed representing Resources found in request. """ for n in range(0, 5): try: response = client.GetResources() return response except: time.sleep((2 ** n) + (random.randint(0, 1000) / 1000)) print "There has been an error, the request never succeeded." return None