GASでGoogle Sitesにページを生成する

## GDG中国のサイトにGolang Cafeのまとめページを作らなければいけない！
最近、GDG中国のイベントとして、Golang Cafeを開催しているのですが、
私が忙しかったのでまとめページを作っていませんでした。

そこで、一気にGoogle Sitesに反映しなければいけなかったので、
GASを使って生成してみました。

## コードのポイント

### 編集するSiteの取得
Google Sitesを編集する場合は、SitesAppを使います。すでに存在している場合は、以下のコードでSitesを取得できますが、新規で生成する場合は、SitesApp.createSite()を使います。（ただし、ドメインを指定しなければいけないので、Google Appsアカウントじゃないとダメかも…？）
`var site = SitesApp.getSite(siteName);`

### ページを作る場所の取得
Google SitesはWebページの下にページを作るという事ができますので、階層を指定したい場合は、site.getChildByName()を使って、Webページを取得して下さい。
`var golangcafeSite = site.getChildByName(category).getChildByName("golang-cafe");`

### ページの作成
ページを作成する場合は、ページの種類に合わせてAPIを呼び出して下さい。

* site.createWebPage() - Webページ
* site.createAnnouncementsPage() - アナウンスページ
* site.createFileCabinetPage() - ファイルキャビネットページ
* site.createListPage() - リストページ
* site.createPageFromTemplate() - テンプレートからページを生成

### コンテンツの生成
単純にHTML文字列をcreateWebPage()に設定すれば良いのですが、わざわざ、HtmlServiceを使ってしまいました。この辺はコードをごらんください。（Google Sitesの自動生成されるタグをベースに作ったので、マークアップはボロボロです…。）

### URLやタイトルなどのデータ
Objectとしてまとめておきました。それだけです。JavaScriptベースなので、適当にまとめるのは便利ですね。

## 今回のコード

```js:コード.gs
function myFunction() {
  var category = "sourcereading";
  var siteName = "gdgchugokuofficial";

  var events = [ {no: 3, date: "2013/11/10", theme: "GoroutineとChannelの使い方を紹介します。"
                  , zusaar: "http://www.zusaar.com/event/1547005"
                  , blogs: [
                     {title:"Golang Cafe #3を開催しました。"
                     ,url:"http://takashi-yokoyama.blogspot.jp/2013/11/golang-cafe-3.html"}
                    ,{title:"Golang Cafe #3 まとめ"
                     ,url:"http://d.hatena.ne.jp/taknb2nch/20131115"}
                    ,{title:"Golang Cafe #3"
                     ,url:"http://qt-luigi.blogspot.jp/2013/11/golang-cafe-3.html"}
                    ,{title:"Golang Cafe #3 - Togetter"
                     ,url:"http://togetter.com/li/588577"}
                  ]}
                ,{no: 4, date: "2013/11/17", theme: "database/sqlパッケージをいじる会になります。"
                  , zusaar: "http://www.zusaar.com/event/1707009"
                  , blogs: [
                     {title:"Golang Cafe #4を開催しました"
                     ,url:"http://takashi-yokoyama.blogspot.jp/2013/11/golang-cafe-4.html"}
                    ,{title:"Golang Cafe #4 まとめ データベースアクセス（PostgreSQL編）"
                     ,url:"http://d.hatena.ne.jp/taknb2nch/20131123"}
                    ,{title:"Golang Cafe #4"
                     ,url:"http://qt-luigi.blogspot.jp/2013/11/golang-cafe-4.html"}
                    ,{title:"Golang Cafe #4 - Togetter"
                     ,url:"http://togetter.com/li/591974"}
                  ]}
                ,{no: 5, date: "2013/11/24", theme: "osパッケージをいじる会になります。"
                  , zusaar: "http://www.zusaar.com/event/1987003"
                  , blogs: [
                     {title:"Golang Cafe #5を開催しました"
                     ,url:"http://takashi-yokoyama.blogspot.jp/2013/11/golang-cafe-5.html"}
                    ,{title:"Golang Cafe #5 まとめ osパッケージを読む"
                     ,url:"http://d.hatena.ne.jp/taknb2nch/20131129/1385700866"}
                    ,{title:"Golang Cafe #5"
                     ,url:"http://qt-luigi.blogspot.jp/2013/11/golang-cafe-5.html"}
                    ,{title:"Golang Cafe #5 - Togetter"
                     ,url:"http://togetter.com/li/594474"}
                  ]}
                ,{no: 6, date: "2013/12/01", theme: "text/templateパッケージをいじる会になります。"
                  , zusaar: "http://www.zusaar.com/event/2177012"
                  , blogs: [
                     {title:"Golang Cafe #6を開催しました"
                     ,url:"http://takashi-yokoyama.blogspot.jp/2013/12/golang-cafe-6.html"}
                    ,{title:"Golang Cafe #6 まとめ text/templateパッケージを試す"
                     ,url:"http://d.hatena.ne.jp/taknb2nch/20131205/1386227745"}
                    ,{title:"Golang Cafe #6"
                     ,url:"http://qt-luigi.blogspot.jp/2013/12/golang-cafe-6.html"}
                    ,{title:"Golang Cafe #6 - Togetter"
                     ,url:"http://togetter.com/li/597591"}
                  ]}
                ,{no: 7, date: "2013/12/08", theme: "Go1.2の新機能の紹介"
                  , zusaar: "http://www.zusaar.com/event/2337013"
                  , blogs: [
                     {title:"Golang Cafe #7を開催しました"
                     ,url:"http://takashi-yokoyama.blogspot.jp/2013/12/golang-cafe-7.html"}
                    ,{title:"Golang Cafe #7 まとめ 1.2での変更ほか"
                     ,url:"http://d.hatena.ne.jp/taknb2nch/20131213/1386910792"}
                    ,{title:"Golang Cafe #7"
                     ,url:"http://qt-luigi.blogspot.jp/2013/12/golang-cafe-7.html"}
                    ,{title:"Golang Cafe #7 - Togetter"
                     ,url:"http://togetter.com/li/601366"}
                  ]}
                ,{no: 8, date: "2013/12/15", theme: "Go年会！"
                  , zusaar: "http://www.zusaar.com/event/2437003"
                  , blogs: [
                     {title:"Golang Cafe #8を開催しました"
                     ,url:"http://takashi-yokoyama.blogspot.jp/2013/12/golang-cafe-8.html"}
                    ,{title:"Golang Cafe #8 まとめ プレGo年会ほか"
                     ,url:"http://d.hatena.ne.jp/taknb2nch/20131216/1387167755"}
                    ,{title:"Golang Cafe #8"
                     ,url:"http://qt-luigi.blogspot.jp/2013/12/golang-cafe-8.html"}
                    ,{title:"Golang Cafe #8 - Togetter"
                     ,url:"http://togetter.com/li/603438"}
                  ]}
                ,{no: 9, date: "2013/12/22", theme: "Go言語のデザインパターンの実装例を紹介します。"
                  , zusaar: "http://www.zusaar.com/event/2607003"
                  , blogs: [
                     {title:"Golang Cafe #9を開催しました"
                     ,url:"http://takashi-yokoyama.blogspot.jp/2013/12/golang-cafe-9.html"}
                    ,{title:"Golang Cafe #9 まとめ Go言語でデザインパターン"
                     ,url:"http://d.hatena.ne.jp/taknb2nch/20131231/1388485191"}
                    ,{title:"Golang Cafe #9"
                     ,url:"http://qt-luigi.blogspot.jp/2013/12/golang-cafe-9.html"}
                    ,{title:"Golang Cafe #9 - Togetter"
                     ,url:"http://togetter.com/li/606390"}
                  ]}
                ,{no: 10, date: "2013/12/29", theme: "imageパッケージをいじる会になります。"
                  , zusaar: "http://www.zusaar.com/event/2767008"
                  , blogs: [
                     {title:"Golang Cafe #10を開催しました"
                     ,url:"http://takashi-yokoyama.blogspot.jp/2013/12/golang-cafe-10.html"}
                    ,{title:"Golang Cafe #10 まとめ imageパッケージをみる"
                     ,url:"http://d.hatena.ne.jp/taknb2nch/20131231/1388500659"}
                    ,{title:"Golang Cafe #10"
                     ,url:"http://qt-luigi.blogspot.jp/2013/12/golang-cafe-10.html"}
                    ,{title:"Golang Cafe #10 - Togetter"
                     ,url:"http://togetter.com/li/609453"}
                  ]}
                ,{no: 11, date: "2014/01/05", theme: "archiveパッケージをいじる会になります。"
                  , zusaar: "http://www.zusaar.com/event/2857003"
                  , blogs: [
                     {title:"Golang Cafe #11を開催しました"
                     ,url:"http://takashi-yokoyama.blogspot.jp/2014/01/golang-cafe-11.html"}
                    ,{title:"Golang Cafe #11 まとめ archiveパッケージ"
                     ,url:"http://d.hatena.ne.jp/taknb2nch/20140109/1389259972"}
                    ,{title:"Golang Cafe #11"
                     ,url:"http://qt-luigi.blogspot.jp/2014/01/golang-cafe-11.html"}
                    ,{title:"Golang Cafe #11 - Togetter"
                     ,url:"http://togetter.com/li/612538"}
                  ]}
                ,{no: 12, date: "2014/01/12", theme: "compressパッケージをいじる会になります。"
                  , zusaar: "http://www.zusaar.com/event/3027003"
                  , blogs: [
                     {title:"Golang Cafe #12を開催しました"
                     ,url:"http://takashi-yokoyama.blogspot.jp/2014/01/golang-cafe-12.html"}
                    ,{title:"Golang Cafe #12 まとめ compressパッケージ"
                     ,url:"http://d.hatena.ne.jp/taknb2nch/20140117/1389938135"}
                    ,{title:"Golang Cafe #12"
                     ,url:"http://qt-luigi.blogspot.jp/2014/01/golang-cafe-12.html"}
                    ,{title:"Golang Cafe #12 - Togetter"
                     ,url:"http://togetter.com/li/615290"}
                  ]}
                ,{no: 13, date: "2014/01/19", theme: "containerパッケージをいじる会になります。"
                  , zusaar: "http://www.zusaar.com/event/3127004"
                  , blogs: [
                    {title:"Golang Cafe #13"
                     ,url:"http://qt-luigi.blogspot.jp/2014/01/golang-cafe-13.html"}
                    ,{title:"Golang Cafe #13 - Togetter"
                     ,url:"http://togetter.com/li/618337"}
                  ]}
               ];
  
  var site = SitesApp.getSite(siteName);
  var golangcafeSite = site.getChildByName(category).getChildByName("golang-cafe");
  for(var i = 0; i < events.length; i++) {
    var content = createHtmlPage(events[i]);
    golangcafeSite.createWebPage("Golang Cafe #" + events[i].no, events[i].no, content);
  }
}


function createHtmlPage(event) {
  var html = HtmlService.createHtmlOutput();
  html.append("<p><span style=\"font-family:arial,sans-serif;font-size:14px;line-height:normal\">" + event.theme + "</span></p>");
  html.append("<div>参加申込：</div>");
  html.append("<div><a href=\"" + event.zusaar + "\">" + event.zusaar + "</a></div>");
  html.append("<div><br>");
  html.append("</div>");
  html.append("<div>場所：<a href=\"http://r.gnavi.co.jp/y236847/\" rel=\"nofollow\" style=\"background-color:transparent;line-height:1.6;font-size:10pt\">倉式珈琲店青江店</a></div>");
  html.append("<div>日時：" + event.date + "（日） 18:00〜20:00</div>");
  html.append("<div><br>");
  html.append("</div>");
  html.append("<div>当日参加者のブログ記事、Togetterまとめです。次回以降で参加される方は参考にして下さい。</div>");
  for(var i = 0; i < event.blogs.length; i++) {
    html.append("<div>" + event.blogs[i].title + "</div>");
    html.append("<div><a href=\"" + event.blogs[i].url + "\">" + event.blogs[i].url + "</a></div>");
  }
  
  return html.getContent();
}

```