グリフォン Advent Calendar 2018 25日目の記事を担当しました、CTOの川村です。この記事ではGoogleAppsScriptからConfluence APIを使用する方法をご紹介します。
※この記事はGRIPHONE Advent Calendar 2018 25日目の記事です。
https://adventar.org/calendars/3147
https://qiita.com/advent-calendar/2018/griphone
GoogleAppsScript(GAS)とは
GoogleAppsScript(以下GAS)とは、Googleが提供しているJavaScriptベースのプログラム環境です。
非常に手軽にwebアプリを開発することが出来るため、弊社ではちょっとした自動化や効率化ツールにGASを用いるケースが多々あります。
以前このブログでご紹介したシャッフルランチのツールもGASで作られています。
Confluence API
弊社では情報共有ツールとしてConfluenceを使用しています。
ConfluenceはREST APIが公開されています。このAPIを使用してページの参照、作成、更新等を実行することが出来ます。
【REST APIドキュメント:https://developer.atlassian.com/cloud/confluence/rest/】
GASからConfluence APIを使用する
それではここから早速サンプルコードです。
※2つ目以降、それ以前のサンプルコードと重複する部分は省略しています
1. ページ参照の例
【該当ドキュメント:https://developer.atlassian.com/cloud/confluence/rest/#api-content-id-get】
var API_BASE_URL = 'https://XXXXX.atlassian.net/wiki';
function create_auth_data(user_id, password) {
return Utilities.base64Encode(user_id + ':' + password);
}
function create_headers(auth_data) {
return {
'content-type' : 'application/json',
'Authorization' : 'Basic ' + auth_data
};
}
function get_content_sample(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;
}
function sample1() {
var auth_data = create_auth_data('user_id', 'password');
var headers = create_headers(auth_data);
var content_json = get_content_sample(headers, '00000', 'body.storage');
Logger.log(content_json);
}
ページのIDを指定してその内容を取得する、シンプルな例です。
『expand』パラメータで取得する情報の範囲を指定しています。デフォルトでは『space,history,version』が設定されます。ページ内容を取得するには『body.storage』が必要になります。
2. ページ作成の例
【該当ドキュメント:https://developer.atlassian.com/cloud/confluence/rest/#api-content-post】
function post_content_sample(headers, page_space_key, ancestors_page_id, page_title, page_body, expand_string) {
var payload = {
'type' : 'page',
'space' : {'key' : page_space_key},
'ancestors' : [{'id' : ancestors_page_id}],
'title' : page_title,
'body' : {
'storage' : {
'value' : page_body,
'representation' : 'storage'
}
}
};
payload = JSON.stringify(payload);
var options = {
'headers' : headers,
'payload' : payload,
'method' : 'post'
};
var api_url = API_BASE_URL + '/rest/api/content/' + '?expand=' + expand_string;
var response = UrlFetchApp.fetch(api_url, options).getContentText('UTF-8');
var content_json = JSON.parse(response);
return content_json;
}
function sample2() {
var auth_data = create_auth_data('user_id', 'password');
var headers = create_headers(auth_data);
var content_json = post_content_sample(headers, 'space_key', '00000', 'ページタイトル', 'ページ内容', null);
Logger.log(content_json);
}
REST APIなので新規登録系の処理はHTTPメソッドが『post』になります。
ページを作成するスペース、親となるページを指定し、新規作成ページのタイトル名と内容をパラメータとして渡します(『payload』の部分)。
親ページの指定が無ければスペース直下にページが作成されます。
スペース指定は表示名ではなく『キー』を指定することに注意です。キーはそのスペースのURL、もしくはSpace Settingsから確認出来ます。
既に存在するタイトル名を指定するとエラーになることにも注意しましょう。
3. ページ更新の例
【該当ドキュメント:https://developer.atlassian.com/cloud/confluence/rest/#api-content-id-put】
function put_content_sample(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;
}
function sample3() {
var auth_data = create_auth_data('user_id', 'password');
var headers = create_headers(auth_data);
// 現在のバージョンを調べるため、更新対象のページ情報を取得
var old_content_json = get_content_sample(headers, '00000', 'version');
// 更新
var content_json = put_content_sample(headers, '00000', old_content_json['version']['number'], '新ページタイトル', '新ページ内容', null);
Logger.log(content_json);
}
REST APIなので更新系の処理はHTTPメソッドが『put』になります。
更新の際は『version』をインクリメントする必要があるので、『old_content_json』取得時に『expand』に『version』を指定しています。versionが正しくインクリメントされていないとエラーとなってしまいます。
4. CQLを使った検索の例
【該当ドキュメント:https://developer.atlassian.com/cloud/confluence/rest/#api-content-search-get】
function search_content_sample(headers, cql_string, expand_string) {
var options = {
'headers' : headers,
'method' : 'get',
};
var api_url = API_BASE_URL + '/rest/api/content/search?cql=' + cql_string + '&expand=' + expand_string;
var response = UrlFetchApp.fetch(api_url, options).getContentText('UTF-8');
var content_json = JSON.parse(response);
return content_json;
}
function sample4() {
var auth_data = create_auth_data('user_id', 'password');
var headers = create_headers(auth_data);
var content_json = search_content_sample(headers, 'parent=00000 order by created desc', null);
Logger.log(content_json);
}
ConfluenceにはCQL(Confluence Query Language)という専用のクエリ言語が提供されており、自由度の高い検索が可能となっています。
CQLについての詳細はこちらのドキュメントをご確認下さい。
https://ja.confluence.atlassian.com/confcloud/confluence-search-syntax-724765423.html
サンプルでは、あるページの子ページのリストを、作成時間の降順で取得しています。
'parent=00000 order by created desc'
SQLと同じノリで書けるのが便利ですね!
まとめ
弊社ではこのAPIを使用し、定例MTGの議事録ページを自動生成したり、議事録のサマリーを自動生成する等しています。地味に面倒なルーティン作業が減り、業務効率化が進みました!
今回はcontent系のAPIのみの紹介となりましたが、ドキュメントを見てみると非常に様々なAPIがあることが分かります。色んな可能性を感じますね!Confluenceを使用されている方には、このAPIの活用を強くオススメします!