8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GoogleAppsScriptでConfluenceのページを定期的に更新

Last updated at Posted at 2019-06-12

はじめに

Confluence」はAtlassianが提供する共有ワークスペース。
現在、社内の情報共有の場として、使用していますが、
アドインや提携しているサービスが豊富で、自由度は**無限大!!**のように感じます。

Confluenceのページ定期更新にいたる背景

とある先輩社員Nさんのつぶやきから、始まりました…。

Nさん:「コンフルのページにイベントまで○○日みたいなカウントダウンのやつ欲しいんだけどー」

私:「イイネ!!やってみよう!(htmlマクロあるっぽいし、Javascriptでおけでしょ)」

--- 問題発生 ---

  • 社内で使用しているクラウド版コンフルでは、「htmlマクロ」が使えない?
  • クラウド版でも代替のアドインがあった!だが…私はコンフルの管理者権限を持っていないので、勝手に追加はできない…。(しかも、こんなことのために管理者様の手を煩わせるわけにはいかない…)

--- かすかな希望 ---

  • コンフルにはAPI(GET,POST,PUT,DELETE)が存在する。
  • 個人単位でAPIキーが発行できる。(管理者様の手を煩わせず、1人で完結できる!)
  • 1日毎に定期更新すれば、あたかも毎日勝手にカウントダウンしているように見せれる!?

Nさん:「無理そうならいいやー、ちょっと言ってみただけー」

(無理なことなんてない、かすかな希望があるんです)
APIをたたくスクリプトを用意して、1日おきに定期実行で該当箇所更新させたる!

て、ことで、長くなりましたが、
Google Apps Script(以下GAS)で、コンフルAPIをたたいて、ページを更新させたいとなりました。
加えて、定期実行も!(GASをチョイスしたのは、定期実行が簡単に設定できるからです。※1)

※1 後述しますが、毎日の定期実行が簡単に設定できるのは、1時間単位。
  なので、0時ぴったりなど、クリティカルな時間調整が必要な場合には向いていません。

やってみよう

ConfluenceRESTAPIドキュメント:https://developer.atlassian.com/cloud/confluence/rest/

1.APIキーの取得

まずは、ATTLASSIANアカウント管理ページに遷移し、「APIトークンを作成する」をクリック。
image.png

その後、ラベルに任意の値を入力して、「作成」をクリック。
image.png

作成後、2度と見れないからなとかなり脅されるので、黙ってコピーして、保管する。
image.png

2. GASにスクリプトを記述

○ソースコード1

以下の3点を認証ヘッダに付与してAPIリクエストを行うので、定義&ヘッダ作成関数を用意する。

  • APIの対象となるワークスペース
  • アクセスに使用するユーザー
  • APIキー
コード.gs
// API情報を定義
// APIで表示及び更新したいコンフルのワークスペース
var API_BASE_URL = 'https://xxxxxxxxx/wiki'; 
var user_id = 'メールアドレス';
var password = '1.で取得したAPIキー';

// 更新対象のページIDを定義
var page_id = '111111111';
 
/* 認証ヘッダー作成関数 */
function create_headers(user_id, password) {
  return {
    'content-type'  : 'application/json',
    'Authorization' : 'Basic ' + Utilities.base64Encode(user_id + ':' + password)
  };
}
○ソースコード2

GET時のパラメータであるexpandはGET時に何を取得するかをカンマ区切りで指定する。

キー 取得するもの
space 取得対象のページが所属するスペース
version 取得対象のページのバージョン
history 取得対象のページの履歴
body 取得対象のページ本文
コード.gs
/* コンフルのGETAPI呼び出し関数 */
function get_previous_content(headers, page_id, expand_string) {
  var options = {
    'headers'  : headers,
    'method'  : 'get'
  };
 
  // 記事内容を取得
  var api_url      = API_BASE_URL + '/rest/api/content/' + page_id + '?expand=' + expand_string;
  var response     = UrlFetchApp.fetch(api_url, options).getContentText('UTF-8');
  var content_json = JSON.parse(response);
  
  return content_json;
}

/* コンフルのPUTAPI呼び出し関数 */
function put_content(headers, page_id, current_version, new_page_title, new_page_body, expand_string) {
  var new_version = current_version + 1; // バージョンを更新
  // 更新内容を定義
  var payload = {
    'type'    : 'page',
    'version' : {'number' : new_version},
    'title'   : new_page_title,
    'body'    : {
      'storage' : {
        'value'          : new_page_body,
        'representation' : 'storage'
      }
    }
  };
  payload = JSON.stringify(payload);
  
  options = {
    'headers' : headers,
    'payload' : payload,
    'method'  : 'put'
  };
  
  // 記事内容を更新
  var api_url      = API_BASE_URL + '/rest/api/content/' + page_id;
  var response     = UrlFetchApp.fetch(api_url, options).getContentText('UTF-8');
  var content_json = JSON.parse(response);
 
  return content_json;
}

○ソースコード3

Mainとなる関数。
現在の記事内容を取得して、
**<strong>~日</strong>**の部分を1日減算して、ページを更新する処理を定義する。
正規表現の部分を変更すれば、どんな箇所でも更新可能です。

コード.gs
/* 記事を更新する関数 */
function updateContent() {
  // 現在の記事内容を取得
  var headers      = create_headers(user_id, password);
  var prev_content = get_previous_content(headers, page_id, 'body.storage,version');
  
  // 記事内容を変更
  var pattern_match = prev_content.body.storage.value.match(/<strong>([\s\S]*?)日<\/strong>/);
  
  // 数値部分を抜粋
  var day = parseInt(pattern_match[0].replace(/[^0-9^\.]/g, ""), 10);
  // 0よりも大きければ、日数を減算
  if (day > 0) {
    day -= 1;
    // 更新後コンテンツを定義
    var new_page_content = prev_content.body.storage.value.replace(/<strong>([\s\S]*?)日<\/strong>/, "<strong>" + day + "日</strong>");
    // 更新
    var content_json = put_content(headers, page_id, prev_content.version.number, prev_content.title, new_page_content, null);
  }
}

3. スクリプトを実行

実行関数にupdateContentを指定して実行!!
image.png

意図したページになっているかを確認。

4. GASを定期実行する。

赤枠の「トリガー」をクリックして、トリガー設定画面に進む。
image.png

トリガーを追加をクリックして、トリガーの詳細を設定。
image.png

今回の詳細は、
updateContent関数を1日に1回午前0時~1時の間に実行する。
午前0時~1時の間に」→この部分が前述したGASがクリティカルな時間調整が必要な場合には向いていない理由
何分に実行するかどうかまでは、指定できません。

image.png

これで、定期実行設定完了!
あとは、明日の実行結果を待つのみ。

まとめ

  • コンフルに管理者権限等がなくてもAPIキーは発行できるので、個人ベースでAPIを使用できる。
  • GASの記法はほぼJavascriptなので、学習コストが抑えられる。
  • GASでhtmlを扱うのは少々困難。(私が正規表現苦手なだけ…??何度もデバックして確認しました…。)
  • GASなら定期実行も簡単にできる。
  • 間違っても、定期実行で1分おきとかにしないように!!(通知を受けている人がいると、えらいことに…。)
8
4
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
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?