2015/12/15
DirectoryAPIにCalenarResourceAPIが追加されました。
#こちらの記事は動作しません
※こちらの記事のコードはスクリプトでサポートが終了した OAuthConfigを使用しているため現在は動作しません。
詳しくは http://goo.gl/IwCSaV をご覧ください。
#概要
GoogleAppsScriptから認証してAPIを叩くやり方を試してみました。
今回はCalendarResourceAPIを使いました。(ついでにxmlの解析も。)
なお、このコードを実行するにはGoogleAppsの管理者である必要があります。
#処理の流れ
- 認証
- APIアクセス
- 取得したxmlからリソースカレンダーの情報を取得
##認証とAPIアクセス
認証部分はGoogleOAuth_の部分です。なかなかズバリこれというサンプルがなかったので…。
scopeとURLを変更すれば他のGoogleのAPIも叩ける(はず)。
//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のペアで格納されています。
##XMLについて
XmlServiceでparseしたxmlから子要素を取得するには、名前と名前空間が必要です。
例えばrootからentryの子要素のみを抜き出そうとすると、getChildrenの引数に名前(entry)とデフォルト名前空間を指定します。
namespaceはXmlService.getNamespaceを使います。デフォルト名前空間なので、引数がprefixのみの物を使います。(xmlの頭にあるxmlns。ここでは'http://www.w3.org/2005/Atom' )
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として記述されています。)
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を割り当てるという判断をしています。
※他にうまいやり方がある?
// 取得可能プロパティ
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}を自分のドメイン名に変えてください。
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"};
}