GoogleAppsScriptとCybozuのGaroon APIを使って掲示板の情報を取得

# 概要
GoogleAppsScriptとCybozuのGaroon APIを使って掲示板の情報を取得し、
GoogleAppsScriptのログにカテゴリIDと掲示板のタイトル、投稿者を表示させます。

# SOAPの使用
Garoonと他のシステムの連携を行うにはSOAPを使用する必要があります。
SOAP APIの定義はWSDLに記述されており、下記のURLで確認できます。

```
・Garoon on cybozu.com：
　https://（サブドメイン名）.cybozu.com/g/index.csp?WSDL

・パッケージ版 Windows 環境：
　http://（インストールしたサーバーの IP アドレスまたはホスト名）/scripts/（インストール識別子）/grn.exe?WSDL

・パッケージ版 Linux 環境：
　`http://（インストールしたサーバーの IP アドレスまたはホスト名）/cgi-bin/（インストール識別子）/grn.cgi?WSDL
```

# レスポンスの確認
ChromeのAdvanced Rest Clientを使ってレスポンスの内容の確認を行います。

POSTを選択

```lang:URL
https://（サブドメイン名）.cybozu.com/g/cbpapi/bulletin/api.csp?
```

```lang:Payload
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:base_services="http://wsdl.cybozu.co.jp/base/2008">
 <SOAP-ENV:Header>
  <Action SOAP-ENV:mustUnderstand="1"
  xmlns="http://schemas.xmlsoap.org/ws/2003/03/addressing">
   BulletinGetTopicByIds
  </Action>
  <Security xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"
  SOAP-ENV:mustUnderstand="1"
  xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext">
   <UsernameToken wsu:Id="id">
    <Username>xxxxxxxxx</Username>
    <Password>xxxxxxxxx</Password>
   </UsernameToken>
  </Security>
  <Timestamp SOAP-ENV:mustUnderstand="1" Id="id"
  xmlns="http://schemas.xmlsoap.org/ws/2002/07/utility">
   <Created>2010-08-12T14:45:00Z</Created>
   <Expires>2037-08-12T14:45:00Z</Expires>
  </Timestamp>
  <Locale>jp</Locale>
 </SOAP-ENV:Header>
 <SOAP-ENV:Body>
  <BulletinGetTopicByIds>
   <parameters>
    <topics xmlns="" topic_id="485" is_draft="false"></topics>
   </parameters>
  </BulletinGetTopicByIds>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
```

Headersには何も記入しません。
UsernameとPasswordはログイン時にお使いのものを入れてください。
BulletinGetTopicByIdsはGaroon APIの掲示板の詳細情報を取得するAPIです。
topics内のtopic_idには情報を取得したい掲示板のtopic_idを入れてください。
**Send**をクリックするとレスポンスが表示されます。

```lang:Response
<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope>
 <soap:Header>
  <vendor>Cybozu</vendor>
  <product>Garoon</product>
  <product_type>2</product_type>
  <version>4.2.0</version>
  <apiversion>1.6.0</apiversion>
 </soap:Header>
 <soap:Body>
  <bulletin:BulletinGetTopicByIdsResponse>
   <returns>
    <topic id="485" version="1445905889" category_id="3" can_follow="true" subject="掲示板のタイトル" is_draft="false" published="true" unread="false" expired="false">
     <th:content body="http://japan.cnet.com/news/service/35072493/ 
　　　　　ここに投稿内容が表示されます。
     " />
     <th:creator user_id="25" name="投稿者名" date="2015-10-27T00:31:29Z" />
     <th:modifier user_id="25" name="更新者名" date="2015-10-27T00:31:29Z" />
    </topic>
   </returns>
  </bulletin:BulletinGetTopicByIdsResponse>
 </soap:Body>
</soap:Envelope>
```

これでXMLを送って返ってくる内容が確認できました。

# GoogleAppsScriptでスクリプト作成
スプレッドシートを開き、「ツール」→「スクリプトエディタ」を選択してださい。
今回function名にはAPI名を付けています。

## Advanced Rest ClientのPayloadで入力したXMLを宣言

```
function BulletinGetTopicByIds() {
  
    const payload =
        "\
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://www.w3.org/2003/05/soap-envelope\"
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"
xmlns:base_services=\"http://wsdl.cybozu.co.jp/base/2008\">
・
・
・
</SOAP-ENV:Envelope>
"
```
XML内で改行をする場合は「\n\」と入力してください。

## 送信方法とURLを定義

```
var options = {
        "method": "post",
        "contextType": "application/soap+xml",
        "muteHttpExceptions": true,
        "payload": payload
    };
var url = "https://（サブドメイン名）.cybozu.com/g/cbpapi/bulletin/api.csp?";
```

URLはAdvanced Rest ClientのURLで入力したものと同じです。

## レスポンスの取得及びパース

```
var response = UrlFetchApp.fetch(url, options);
var doc = XmlService.parse(response.getContentText());
```

## ノード解析
Advanced Rest Clientでリクエストを送り、ResponseのXMLを見て
表示したい項目がどこにあるのかを確認します。
今回はカテゴリIDと掲示板のタイトル、投稿者を表示するため、
どこのタグの中にあるか追っていきます。
もう一度上記にあるResponseを見てみると
**Envelope→Body→BulletinGetTopicByIdsResponse→returns→topic**と
降りていきtopicタグの中に投稿者以外の項目があることが分かります。

```
var bulletin = doc
          .getRootElement()
          .getChild('Body', XmlService.getNamespace('http://www.w3.org/2003/05/soap-envelope'))
          .getChild('BulletinGetTopicByIdsResponse', XmlService.getNamespace('http://wsdl.cybozu.co.jp/bulletin/2008'))
          .getChild('returns', XmlService.getNamespace(''))
          .getChild('topic');
```

getRootElement()でEnvelopeを呼び出し、その後はgetChildでtopicまで降りていきます。

## カテゴリID、タイトル、投稿者の取得

```
var category_id = bulletin.getAttribute("category_id").getValue();
var subject = bulletin.getAttribute("subject").getValue();
var name = bulletin.getChild('creator',XmlService.getNamespace('http://schemas.cybozu.co.jp/bulletin/2008')).getAttribute("name").getValue();
```

投稿者のみ他のタグ内に含まれているためもう一度getChildで一つ降ります。

## ログに表示
表示項目の取得ができたため、ログに表示します。

```
Logger.log(category_id);
Logger.log(subject);
Logger.log(name);
```

## try～catchで囲む
最後にurlを定義した後から最後までをtryで囲み、

```
catch(e){
    Logger.log(e);
}
```
と例外のログを出力するように記述したら完成です。


# 参考
[SOAP APIの共通仕様](https://cybozudev.zendesk.com/hc/ja/articles/202228464-SOAP-API%E3%81%AE%E5%85%B1%E9%80%9A%E4%BB%95%E6%A7%98)
[掲示板を取得する](https://cybozudev.zendesk.com/hc/ja/articles/202474540-%E6%8E%B2%E7%A4%BA%E6%9D%BF%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B)
[Cybozu ガルーン API を使ってみる](http://qiita.com/yamasaki-masahide/items/fff1c84e65043ac4caf7)
[Class Element](https://developers.google.com/apps-script/reference/xml-service/element)