(前記事の流れを完全に無視して)
backlogのwiki記事を自動作成するGASです!
概要
- Backlogプロジェクトのwikiについて、指定URL配下に記事を作成する。
- テンプレートを元に作成記事単位でシートを作成、必要情報記入する(Spreadsheet例については後述)。
- 月~金曜日朝に実行され(トリガー自体は毎朝実行設定)、シート内容通りのタイミングで記事を作成する。
- 定例MTGの議事録定期作成が前提のため、ページ名はすべて日付で作成される。
- 作成結果はGoogleChatへ投稿される。
コード
コードはこんな感じ、技術的に特別なことはしていないので説明は省略。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function createLogPageMain() { | |
let nowDate = new Date() | |
//月~金のみ処理する。 | |
if(!(isExecutionDay(nowDate))){ | |
return | |
} | |
//設定内容シート群を取得 | |
let targetSheets = SpreadsheetApp.getActiveSpreadsheet().getSheets() | |
let createdLogStrings = "" | |
//シートごとにループ | |
targetSheets.forEach(function(targetSheet){ | |
if (targetSheet.getName() == "説明書" || targetSheet.getName() == "テンプレート"){ | |
return | |
} | |
let parametersBuf = targetSheet.getRange(1,2,8,1).getValues() | |
let parameters = { | |
projectID:parametersBuf[0][0], | |
span:parametersBuf[1][0], | |
weekScaleDate1:parametersBuf[2][0], | |
weekScaleDate2:parametersBuf[3][0], | |
monthScaleDate:parametersBuf[4][0], | |
rootPath:parametersBuf[5][0], | |
notice:parametersBuf[6][0], | |
contents:parametersBuf[7][0] | |
} | |
//処理対象日か判定 | |
if (isCreateDate(nowDate,parameters)){ | |
//対象日の場合記事を作成 | |
let logURL = createLogPage(nowDate,parameters) | |
createdLogStrings = "<" + logURL + "|" + targetSheet.getName() + ">" + "\n" | |
} | |
}) | |
//作成結果をチャットへ投稿 | |
postResult(createdLogStrings) | |
} | |
function isExecutionDay(nowDate){ | |
//処理当日が月~金か判定 | |
if ( nowDate.getDay() >= 1 && nowDate.getDay() <= 5 ){ | |
return true | |
} else { | |
return false | |
} | |
} | |
function isCreateDate(nowDate,parameters){ | |
//シートの設定内容から、処理当日が作成対象日か判定する。 | |
//日次 | |
if(parameters.span == "日次"){ | |
return true | |
} | |
//週次 | |
if(parameters.span == "週次" && isWeek1(nowDate,parameters.weekScaleDate1)){ | |
return true | |
} | |
//隔週 | |
if(parameters.span == "隔週" && isWeek2(nowDate,parameters.weekScaleDate2)){ | |
return true | |
} | |
//月末 | |
if(parameters.span == "月次" && isMonth(nowDate,parameters.monthScaleDate)){ | |
return true | |
} | |
} | |
function createLogPage(nowDate,parameters){ | |
//BacklogAPIで議事録を作成 | |
var url = "https://hoge.backlog.com/api/v2/wikis?apiKey=hoge"; | |
var payload = { | |
"projectId" : Number(parameters.projectID), | |
"name" : String(parameters.rootPath + "/" + getDateStrings(nowDate)), | |
"content" : String(parameters.contents), | |
"mailNotify" : parameters.notice | |
} | |
var options = { | |
"method" : "POST", | |
"contentType": "application/json", | |
"payload" : JSON.stringify(payload) | |
} | |
var response = UrlFetchApp.fetch(url, options); | |
return response.getAllHeaders().Location | |
} | |
function isWeek1(nowDate,weekScaleDate1){ | |
let dayDictionary = { | |
"月":1, | |
"火":2, | |
"水":3, | |
"木":4, | |
"金":5 | |
} | |
if ( nowDate.getDay() == dayDictionary[weekScaleDate1] ){ | |
return true | |
} else { | |
return false | |
} | |
} | |
function isWeek2(nowDate,weekScaleDate2){ | |
//処理当日が基準日から数えて14の倍数日目の場合true | |
let dateTo = new Date(nowDate.getFullYear(),nowDate.getMonth(),nowDate.getDate()) | |
let dateFrom = new Date(weekScaleDate2.getFullYear(),weekScaleDate2.getMonth(),weekScaleDate2.getDate()) | |
let termDay = (dateTo - dateFrom) / 86400000; | |
if (termDay % 14 == 0) { | |
return true | |
}else{ | |
return false | |
} | |
} | |
function isMonth(nowDate,monthScaleDate){ | |
//基準日の設定に基づいて日付を算出、処理当日か判定 | |
let dateYYYYMMDD = new Date(nowDate.getFullYear(),nowDate.getMonth(),nowDate.getDate()) | |
//各指定日を算出 | |
let targetDate | |
switch(monthScaleDate){ | |
case "1": | |
case "初月": | |
case "初火": | |
case "初水": | |
case "初木": | |
case "初金": | |
let monthStartDate = getMonthStartDate(nowDate) | |
targetDate = getMonthTargetDate(monthScaleDate,monthStartDate) | |
break; | |
case "末月": | |
case "末火": | |
case "末水": | |
case "末木": | |
case "末金": | |
let monthEndDate = getMonthEndDate(nowDate) | |
targetDate = getMonthTargetDate(monthScaleDate,monthEndDate) | |
break; | |
default: | |
targetDate = null | |
} | |
//算出した日付と処理当日が等しければtrue | |
if(dateYYYYMMDD.getTime() === targetDate.getTime()){ | |
return true | |
}else{ | |
return false | |
} | |
} | |
function getMonthStartDate(nowDate){ | |
return new Date(nowDate.getFullYear(),nowDate.getMonth(),1) | |
} | |
function getMonthEndDate(nowDate){ | |
return new Date(nowDate.getFullYear(),nowDate.getMonth()+1,0) | |
} | |
function getMonthTargetDate(monthScaleDate,monthDate){ | |
let dayDictionary = { | |
"月":1, | |
"火":2, | |
"水":3, | |
"木":4, | |
"金":5 | |
} | |
if(monthScaleDate == "1"){ | |
return monthDate | |
}else if(monthScaleDate.slice(0,1)=="初"){ | |
let targetDayNumber = dayDictionary[monthScaleDate.slice(-1)] | |
let monthStartDayNumber = monthDate.getDay() | |
if(targetDayNumber >= monthStartDayNumber){ | |
return new Date(monthDate.getFullYear(),monthDate.getMonth(),1 + targetDayNumber - monthStartDayNumber ) | |
}else{ | |
return new Date(monthDate.getFullYear(),monthDate.getMonth(),1 + targetDayNumber - monthStartDayNumber + 7) | |
} | |
}else{ | |
let targetDayNumber = dayDictionary[monthScaleDate.slice(-1)] | |
let monthEndDayNumber = monthDate.getDay() | |
if(targetDayNumber >= monthEndDayNumber){ | |
return new Date(monthDate.getFullYear(),monthDate.getMonth() + 1,0 + targetDayNumber - monthEndDayNumber - 7 ) | |
}else{ | |
return new Date(monthDate.getFullYear(),monthDate.getMonth() + 1,0 + targetDayNumber - monthEndDayNumber) | |
} | |
} | |
} | |
function getDateStrings(nowDate){ | |
return nowDate.getFullYear() + "/" + String(nowDate.getMonth() + 1) + "/" + nowDate.getDate() | |
} | |
function postResult(createdLogStrings){ | |
//作成した議事録が無ければチャットへ投稿しない | |
if (createdLogStrings == "") { | |
return | |
} | |
var message = "【本日下記の議事録をBacklogへ作成しました。】\n\n" + createdLogStrings | |
var url = "webhookのURL"; | |
var payload = { | |
"text" : message | |
} | |
var json = JSON.stringify(payload); | |
var options = { | |
'method': 'POST', | |
'contentType': 'application/json; charset=UTF-8', | |
"payload" : json | |
}; | |
var response = UrlFetchApp.fetch(url, options); | |
} |
強いて言えば、月次処理の日付算出方法は少し考えました。
APIキー方式なのでOAuth方式に変更できると安心かな?
エラー処理も入れてないし、ツギハギな上にコードレビュー一切してないので、きれいにしたい方はご自由にー。
今後はパラメーターバリデーションを入れる予定。
なお設定するパラメーターは下記の通り、Spreadsheetも公開しておきますー。
使用時はテンプレートをコピーしてください。
「説明書」シートと「テンプレート」シート以外を読み取って記事を作成します。
- プロジェクトID:作成先プロジェクトのIDを設定。IDは課題一覧のURLやソースから取れます。
- スパン:作成スパンの設定、「日次、週次、隔週、月次」が設定可能。
- 日次の場合は月~金曜日のみ作成する。
- 週次基準曜日:週次設定時の作成曜日。
- 隔週基準日:隔週設定時の初回作成日。これを基準日として、処理当日との日数を算出、日数が14の倍数日目だった場合に作成する。
- 例:2021/4/1(木)を基準日とした場合、4/15(木)は14日目、4/29(木)は28日目と14の倍数日目のため作成する。
- 月次基準日:1日か、月初各曜日(月~金)、月末最終各曜日(月~金)が設定可能。
- 親ページ:作成する記事の格納先を設定。設定必須。
- 設定例:議事録/改善MTG"
- (ページ名):自動設定。定期作成が前提のため、ページ名単独での設定はなく、処理当日でページ名を作成する。
- 記事内容:Backlogのwiki記法に沿う、Backlog上で要確認。
- メール通知:True/False、Backlog本体からの作成通知メールを送信するかしないか。
0 件のコメント:
コメントを投稿