Edited at

GASからCalendarResourceAPIを叩いてみた(+XmlServiceの説明)

More than 3 years have passed since last update.

2015/12/15

DirectoryAPIにCalenarResourceAPIが追加されました。

http://qiita.com/mistolteen/items/e15e7f80c0bf1d701b95


こちらの記事は動作しません

※こちらの記事のコードはスクリプトでサポートが終了した OAuthConfigを使用しているため現在は動作しません。

詳しくは http://goo.gl/IwCSaV をご覧ください。


概要

GoogleAppsScriptから認証してAPIを叩くやり方を試してみました。

今回はCalendarResourceAPIを使いました。(ついでにxmlの解析も。)

なお、このコードを実行するにはGoogleAppsの管理者である必要があります。


処理の流れ


  1. 認証

  2. APIアクセス

  3. 取得したxmlからリソースカレンダーの情報を取得


認証とAPIアクセス

認証部分はGoogleOAuth_の部分です。なかなかズバリこれというサンプルがなかったので…。

scopeとURLを変更すれば他のGoogleのAPIも叩ける(はず)。


GoogleOAuth_

//Google oAuth

function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey("anonymous");
oAuthConfig.setConsumerSecret("anonymous");
return {oAuthServiceName:name, oAuthUseToken:"always"};
}

取得自体は認証したあとにCalendarResourceAPIのURLをUrlFetchAppで叩くだけです。


XMLからデータを取得

APIを叩くと、結果はxmlで返されるので後はこれを解析してデータを取り出すだけです。

取得したXMLの構造は下記のようになっています。

root下のentry1つ1つがリソースカレンダー情報になっています。その中にapps:propertyにresourceIdなどがAttributeとしてnameとvalueのペアで格納されています。

resource.png


XMLについて

XmlServiceでparseしたxmlから子要素を取得するには、名前と名前空間が必要です。

例えばrootからentryの子要素のみを抜き出そうとすると、getChildrenの引数に名前(entry)とデフォルト名前空間を指定します。

namespaceはXmlService.getNamespaceを使います。デフォルト名前空間なので、引数がprefixのみの物を使います。(xmlの頭にあるxmlns。ここでは'http://www.w3.org/2005/Atom' )


getChildren

var xml = XmlService.parse(response.getContentText());

var root = xml.getRootElement();
var entries = root.getChildren('entry', XmlService.getNamespace('http://www.w3.org/2005/Atom'));

また、最終的に取得したい部分はentry以下のapps:propertyとなっています。

appsという名前空間内にあるので、appsという名前空間と'property'という名前で取得することができます。

(これもxmlファイルの頭にxmlns:appsとして記述されています。)


appsns

var appsns = XmlService.getNamespace("apps", "http://schemas.google.com/apps/2006");

for(var i = 0; i < entries.length; i++){
var entry = entries[i];
var properties = entry.getChildren('property', appsns);
}


取得したい値はapps:propertyタグの中にあるのでGetAttributeを使います。

今回はnameもvalueも中に入っているので、nameのvalueでどのプロパティか判断してvalueのvalueを割り当てるという判断をしています。

※他にうまいやり方がある?


getAttribute


// 取得可能プロパティ
var resourceId = '',
resourceCommonName = '',
resourceEmail = '',
resourceDescription = '',
resourceType = '';

for(var j = 0; j < properties.length; j++){
var property = properties[j];

var name = property.getAttribute("name").getValue();
switch(name){
case 'resourceId':
resourceId = property.getAttribute("value").getValue();
break;
case 'resourceCommonName':
resourceCommonName = property.getAttribute("value").getValue();
break;
case 'resourceEmail':
resourceEmail = property.getAttribute("value").getValue();
break;
case 'resourceDescription':
resourceDescription = property.getAttribute("value").getValue();
break;
case 'resourceType':
resourceType = property.getAttribute("value").getValue();
break;
default:
break;
}
}



全体ソース

Webアプリとして取得したXMLを表示するソースです。

※サンプルの{domain name}を自分のドメイン名に変えてください。


all

function doGet(e){

var scope = "https://apps-apis.google.com/a/feeds/calendar/resource/";
//oAuth
var fetchArgs = googleOAuth_('cal', scope);
var url = "https://apps-apis.google.com/a/feeds/calendar/resource/2.0/{domain name}";
var response = UrlFetchApp.fetch(url, fetchArgs);

var xml = XmlService.parse(response.getContentText());
var root = xml.getRootElement();

var entries = root.getChildren('entry', XmlService.getNamespace('http://www.w3.org/2005/Atom'));

var appsns = XmlService.getNamespace("apps", "http://schemas.google.com/apps/2006");

var calendars = new Array();

for(var i = 0; i < entries.length; i++){
var entry = entries[i];
var properties = entry.getChildren('property', appsns);

// 取得可能プロパティ
var resourceId = '',
resourceCommonName = '',
resourceEmail = '',
resourceDescription = '',
resourceType = '';

for(var j = 0; j < properties.length; j++){
var property = properties[j];

var name = property.getAttribute("name").getValue();
switch(name){
case 'resourceId':
resourceId = property.getAttribute("value").getValue();
break;
case 'resourceCommonName':
resourceCommonName = property.getAttribute("value").getValue();
break;
case 'resourceEmail':
resourceEmail = property.getAttribute("value").getValue();
break;
case 'resourceDescription':
resourceDescription = property.getAttribute("value").getValue();
break;
case 'resourceType':
resourceType = property.getAttribute("value").getValue();
break;
default:
break;
}
}

calendars.push({
resourceId: resourceId,
resourceCommonName: resourceCommonName,
resourceEmail: resourceEmail,
resourceDescription: resourceDescription,
resourceType: resourceType
});
}

Logger.log(calendars);

return ContentService.createTextOutput(response.getContentText()).setMimeType(ContentService.MimeType.XML);
}

//Google oAuth
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey("anonymous");
oAuthConfig.setConsumerSecret("anonymous");
return {oAuthServiceName:name, oAuthUseToken:"always"};
}