0
0

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 1 year has passed since last update.

コンフルページをcopyしたら

Last updated at Posted at 2023-02-19

背景・状況

現チームでは、日常的なスクラムイベントで利用するコンフルページが1スプリントで新規作成する。
イメージ的には、こいう感じです。
前スプリントのページをコピーし、タイトルを当日の日付を書き換えるという作業だった。

上記手順は定形作業であるが地味にめんどくさい作業だった。
固定作業となっているコンフルの作成タスクを軽減する目的で、自動化ソースが公開してくれていたため、この場で共有させてください。

できること

基本的には下記のGASを定期実行しています。

コードを読んでもらうのが早いですが、やっているところは

  1. 日時でGASを実行(トリガー)
  2. 営業日かどうか判断してAPI投げるかを判断
  3. コンフルAPIを投げて、作成したいページの前回のコンフルページを検索(本文とタイトルを取得)
  4. 作成したい当日のコンフルページを作成。作成の際にbodyに本文やタイトルを入れてページを作成

簡単に言うと、翌週のMTG用ページを実行週のページをコピーする形で作成

例:

  1. 2023年2月20日の夜にGasのMain関数が動く
  2. 営業日なので、コンフルページ作成用のコードを動かす
  3. 今週分である「2023-02-20週PO/SMデイリー」のページを検索し本文とタイトルを取得
  4. 日付をインクリメントして「2023-02-27週PO/SMデイリー」というページを作成するAPIを投げる

起動時間の登録は画面左側の時計のアイコン”トリガー”より設定が可能
agile.png

// 指定された日が営業日か(営業日 = 「土日でない」「祝日カレンダーに予定がない」)
// 営業日 = true
function isWorkday (targetDate) {

  // targetDate の曜日を確認、月曜以外は休む (false)
  var rest_or_work = ["REST","mon","REST","REST","REST","REST","REST"]; // 日〜土
  var youbi_num = targetDate.getDay() //取得した日付の曜日が0~6の数字で返却される
  if ( rest_or_work [youbi_num] == "REST" ) { //rest_or_workのリストは月曜日以外はRESTとしている
    console.log("実行しません")
    return false;
  }; 

  // // 祝日カレンダーを確認する
  // var calJpHolidayUrl = "ja.japanese#holiday@group.v.calendar.google.com";
  // var calJpHoliday = CalendarApp.getCalendarById (calJpHolidayUrl);
  // if (calJpHoliday.getEventsForDay (targetDate).length != 0) {
  //   // その日に予定がなにか入っている = 祝祭日 = 営業日じゃない (false)
  //   return false;
  // } ;

  // 全て当てはまらなければ営業日 (True)
  return true;
}

// main
function main () {

  var today = new Date ();

  // 実行日であれば実行
  if (isWorkday (today) == true) {
  post_content();
  console.log("実行します")
  }
}
const API_BASE_URL = "https://API_BASE_URL.atlassian.net/wiki";
// // API情報を定義
// // APIで表示及び更新したいコンフルのワークスペース
var user_id = {Googleアカウント};
var token = {Google Token};
// コンテンツ作成
function post_content() {
  var page_title = "週 PO/SMデイリー"
  var stringtoday = getToday().toString(); 
  var next_monday = getSevenDaysLater();
  var id = get_contentid(page_title,stringtoday);
  console.log("コピー元ページのid", id);
  var body = get_contentbody(page_title,stringtoday);
  var response = create_contents(id,next_monday,page_title,body);
 return;
}
// コンテンツID取得
function get_contentid(page_title,stringtoday) {
  var options = {
    'headers': create_headers(user_id, token),
    'method': 'get',
    'muteHttpExceptions': true,
  };

  var title =  "\"" + stringtoday + page_title + "\"";
  console.log(title);
  var space = "\"AUTHRESTORED\"";
  var api_url = "https://spacename.atlassian.net/wiki/rest/api/content/search?expand=ancestors&cql=space="+space+ "+and+title=";
  var urlEncoded = encodeURI(api_url)+encodeURIComponent(title);
  var response = UrlFetchApp.fetch(urlEncoded, options).getContentText('UTF-8');
  //console.log(response);
  var content_json = JSON.parse(response);

  var length = Object.keys(content_json.results[0].ancestors).length;
  console.log(content_json.results[0].ancestors[length - 1].id)
  return content_json.results[0].ancestors[length - 1].id;
}
// コンテンツボディ取得
function get_contentbody(page_title,stringtoday) {
    
 var options = {
    'headers': create_headers(user_id, token),
    'method': 'get',
    'muteHttpExceptions': true,
 };

 var sprint = "SP#";
 var title =  "\"" + stringtoday + page_title + "\""; 
 console.log("取得したページタイトル", title)
 var space = “\”{コンフル該当スペース名}\””;

 var api_url = "https://spacename.atlassian.net/wiki/rest/api/content/search?expand=body.storage&cql=space="+space+ "+and+title=";
 var urlEncoded = encodeURI(api_url)+encodeURIComponent(title)+encodeURI("&?expand=body.storage");
 var response = UrlFetchApp.fetch(urlEncoded, options).getContentText('UTF-8');
 console.log(api_url+title+"&?expand=body.storage");
 console.log(urlEncoded);
 console.log(response);
 var content_json = JSON.parse(response);
 console.log(content_json.results[0]);
  return content_json.results[0].body;
}
//コンテンツ作成
function create_contents(id,next_monday,page_title,body){
  var payload = {
    'type': 'page',
    'space': { 'key': "コンフル該当スペース名" },
    'ancestors': [{ 'id': id }],
    'title': next_monday + page_title,
    'body': body,
    "metadata": {
            "properties": {
                "editor": {
                    "key": "editor",
                    "value": "v2"
                }
            }
          }
  };
  payload = JSON.stringify(payload);
  var options = {
    'headers': create_headers(user_id, token),
    'payload': payload,
    'muteHttpExceptions': true,
    'method': 'post'
  };
  var expand_string = "body.storage";
  var api_url = API_BASE_URL + '/rest/api/content/' + '?expand=' + expand_string;
  console.log(api_url);
  var response = UrlFetchApp.fetch(api_url, options).getContentText('UTF-8');
  content_json = JSON.parse(response);
  return content_json;
}
/* 認証ヘッダー作成関数 */
function create_headers(user_id, token) {
  return {
    'content-type': 'application/json',
    'Authorization': 'Basic ' + Utilities.base64Encode(user_id + ':' + token)
  };
}

// 日付取得関数
function getToday() {
  var dt = new Date();
  var d1 = Utilities.formatDate(dt, 'Asia/Tokyo', 'yyyy-MM-dd');
  return d1;
  
}

// 一週間後の日付を取得(週初めの日付取得なので来週月曜日の日付を取得)
function getSevenDaysLater() {
  var dt = new Date();
  dt.setDate(dt.getDate() + 7);
  var d2 = Utilities.formatDate(dt, 'Asia/Tokyo', 'yyyy-MM-dd');
  return d2
}

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?