LoginSignup
8
8

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-08-08

2015/12/15
DirectoryAPIにCalenarResourceAPIが追加されました。

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

※こちらの記事のコードはスクリプトでサポートが終了した 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"};
}
8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8