こんにちは、七瀬カイ(@7se_kai)です。
今回は「こんなスクリプトあったら業務捗るよね」って思い、実際に仕事で作成したコードを紹介するよ。
任意のスプレッドシートから特定列を最終行まで取得して、一致した日付があれば隣のセルの情報を取得してSlackにIncoming Webhookを利用してPOSTするスクリプトです。
社内にて、当番制で回している仕事の担当者を、毎週の週初めにSlackで通知するbotを制作するために作成しました。
参考までに、今回使用するスプレッドシートは以下のような形式のものを想定しています。
コード概要
スクリプト全文
以下がコードの全文となります。
function CleanInCharge() {
var date = new Date();
var y_date = date.getFullYear();
var m_date = ('0' + (date.getMonth() + 1)).slice(-2);
var d_date = ('0' + (date.getDate())).slice(-2);
var date = y_date + "年" + m_date + "月" + d_date + "日";
var sheet = SpreadsheetApp.openById('スプレッドシートのID');
var ss = sheet.getSheets()[0];
var POSTURL = 'Incoming WebHooksで発行されたURL'
const lastRow = ss.getLastRow();
for(let i = 4; i<= lastRow; i++) {
var range = ss.getRange(i, 3);
var range2 = ss.getRange(i, 2);
var today = range.getDisplayValue();
var person = range2.getValue();
if(today === date) {
var message = '今週の当番は' + person + 'さんです。';
var jsonData = {
'text':message
};
var payload = JSON.stringify(jsonData);
var options = {
'method':'post',
'contentType':'application/json',
'payload':payload
};
UrlFetchApp.fetch(POSTURL, options);
}
}
}
トリガーの設定について
週初めの始業後1時間以内に通知したいので、毎日9:00-10:00の間に1度実行するようにトリガーを設定しています。
毎週月曜日ではなく毎日起動にしている理由としては、月曜日が祝日で火曜日に通知したい場合にも対応するためです。
コード各行についての解説
2~9行目:取得したDate型をString型に変換し、対象のスプレッドシートを定義
var date = new Date();
var y_date = date.getFullYear();
var m_date = ('0' + (date.getMonth() + 1)).slice(-2);
var d_date = ('0' + (date.getDate())).slice(-2);
var date = y_date + "年" + m_date + "月" + d_date + "日";
var sheet = SpreadsheetApp.openById('スプレッドシートのID');
var ss = sheet.getSheets()[0];
new Date()で現在の日時を取得できるので、変数dateに現在日時を格納します。
続いて変数dateから、getFullYear()メソッドを使って、現在日時の年を4桁の整数で取得して変数y_dateに格納します。
var m_date = ('0' + (date.getMonth() + 1)).slice(-2);
var d_date = ('0' + (date.getDate())).slice(-2);
上記のように、同じ要領でgetMonth()メソッド、getDate()メソッドを使用して月日を1桁もしくは2桁の整数で取得します。
ちなみにgetMonth()メソッドでは「1月を0、2月を1…」とカウントするので、+1してあげる必要があります。
ちなみに変数の中身が、なぜ「(date.getDate()」ではなく「(‘0’ + (date.getDate() )).slice(-2)」かというと、getMonth()メソッドは0-11、getDate()メソッドは1-31の1桁もしくは2桁で表されるため、そのまま取得してしまうと桁数がズレてしまう場合があるためです。
そこで先頭に0を追加して、下2桁を取り出すことによって、必ず2桁表示で統一するようにしています。
1月の場合:1→01→01
12月の場合:12→012→12
そして最後に「y_date」「m_date」「d_date」の3つを使ってdateを再定義することで、String型に変換することができます。
var sheet = SpreadsheetApp.openById('スプレッドシートのID');
var ss = sheet.getSheets()[0];
こちらの2行で、情報の取得元であるスプレッドシートを定義しています。
スプレッドシートIDは、URLの以下の部分に当たります。
ちなみにsheet.getSheets()[0];の0とは、シートの1枚目のことを指すので、仮に2枚目なら1、3枚目なら2、といった風に適宜修正してください。
11~13行目:slackへ通知するための連携と、最終行の設定
var POSTURL = 'Incoming WebHooksで発行されたURL'
const lastRow = ss.getLastRow();
Slackで通知したいチャンネルのIncoming Webhook URLを取得して、任意の変数(今回の例ではPOSTURL)に定義します。
getLastRow()で、最終行が何行目かを数値で取得できるので、以降のコードで出てくるfor文の条件式で使用するために任意の変数(今回はlastRow)で定義します。
15~34行目:for文で最終行まで探索し、一致した日付があれば隣のセルの入力情報を元にSlackへPOST
for(let i = 4; i<= lastRow; i++) {
var range = ss.getRange(i, 3);
var range2 = ss.getRange(i, 2);
var today = range.getDisplayValue();
var person = range2.getValue();
if(today === date) {
var message = '今週の当番は' + person + 'さんです。';
var jsonData = {
'text':message
};
var payload = JSON.stringify(jsonData);
var options = {
'method':'post',
'contentType':'application/json',
'payload':payload
};
UrlFetchApp.fetch(POSTURL, options);
}
}
4行目に最初の日付が入力されているので、for文の初期値をi=4で定義し、最終行まで繰り返し処理させます。
変数todayでgetValue()メソッドではなく、getDisplayValue()メソッドを使用することで、String型で定義した変数dateと一致させます。
そして、if文でtodayとdateが一致した場合に、SlackでPOSTさせるようにしています。
if文の中身はSlackにPOSTするための定型文みたいなものなので、messageの中身とPOSTURLのみ自身で設定した変数に置き換えたら完成です。
まとめ
今回のスクリプトを作成するにあたって、自分なりに「こういったスクリプトがあればいいな」というものを心がけて、分かりやすいように解説させていただいたつもりです。よく分からない箇所がある場合や、実際にカスタマイズしても動作しなかった場合にはコメントやお問い合わせをいただければ、回答させていただきます。
X(@7se_kai)で直接質問をいただいても大丈夫ですので、ぜひ、フォローもしていただければと思います。
コメント