GASで祝日一覧(年月日と祝日名)データをJSON出力するAPIを作成
PHPのシステム案件で祝日を取得し、処理を行う箇所があった。GoogleカレンダーのAPIに接続してどうこうしようかと考えたが、カレンダーAPIを使ったことが無いのと、GoogleMapsAPIみたいにAPIキーが必須だった場合、クライアント様にキーを発行いただく必要がありその辺りが面倒だった。結局のところ他所様のAPIを使用して実装したが、よくよく考えればこういった時こそGoogle Apps Scriptの出番じゃないかと思った。以下に祝日APIの作成方法をメモ。
目次
やりたいこと
今年と来年の祝日一覧(年月日と祝日名)をJSON出力するAPIを作成したい。
APIリクエスト時にGoogleログイン認証は不要だが、GoogleMapsAPIのAPIキーのようにGETパラメータをつけることで認証させたい。もちろんキーが無い場合はデータを返さない。
法改正等による祝日の変更を考慮し、1日に1回Googleカレンダーから祝日データを引っ張ってきてスプレッドシートに保存・更新したい。
GAS側の作業
必要な作業はプログラムの作成、トリガーの設定、デプロイになる。
プログラムの作成
//スプレッドシートに祝日データを書き込む関数
function setHoliday(){
//開始年月日と終了年月日の指定
const now = new Date();
const start = now.getFullYear() + '-01-01';
const end = (now.getFullYear() + 1) + '-12-31';
//Googleカレンダーから祝日取得
const calendar = CalendarApp.getCalendarById('ja.japanese#holiday@group.v.calendar.google.com').getEvents(new Date(start), new Date(end));
//祝日データを整形して配列に格納
const result = [];
for( var i = 0; i < calendar.length; i++ ){
result[i] = [
Utilities.formatDate(calendar[i].getStartTime(), 'JST', 'yyyy-MM-dd'),
calendar[i].getTitle()
];
}
//正常にデータが取得できた場合、スプレッドシートに書き込み
if( result.length ){
//スプレッドシートの読み込み
const sheet = SpreadsheetApp.getActiveSpreadsheet();
//シートを指定
const holidaySheet = sheet.getSheetByName('holiday');
//シートにまとめて書き込み
holidaySheet.getRange(1, 1, result.length, result[0].length).setValues(result);
}
}
//祝日データをJSON出力
function getHoliday(){
//スプレッドシートの読み込み
const sheet = SpreadsheetApp.getActiveSpreadsheet();
//シートを指定
const holidaySheet = sheet.getSheetByName('holiday');
//シートのデータを取得
const holidaySheetVal = holidaySheet.getDataRange().getValues();
//年月日の整形
for( let i = 0; i < holidaySheetVal.length; i++ ){
holidaySheetVal[i][0] = Utilities.formatDate(holidaySheetVal[i][0], 'JST', 'yyyy-MM-dd');
}
//データをJSON化
const payload = JSON.stringify(holidaySheetVal);
//Textoutputオブジェクトを生成
const output = ContentService.createTextOutput();
//Mime TypeをJSONに設定
output.setMimeType(ContentService.MimeType.JSON);
//データ出力
output.setContent(payload);
return output;
}
//API呼び出し時に動作する関数
function doGet(e){
const key = e.parameter.key;
const apiKey = 'xxxxxxxxxxxxxxxx';
if( key != apiKey ){
return ContentService.createTextOutput('アクセスできませんでした。');
}
return getHoliday();
}
カレンダーデータ取得部分のエラー
「CalendarApp.getCalendarById('ja.japanese#holiday@group.v.calendar.google.com')」の部分が動かず、以下のようなエラーメッセージが表示された。
TypeError: Cannot find function getEvents in object
GASで使うGoogleアカウントが最近取得したばかりでGoogleカレンダーを作成していなかった。Googleカレンダーを作成することで上記エラーが改善された。
他には以下のような場合もある模様。
https://teratail.com/questions/189134
http://syasuda.com/d/blog/2016/11/googleid.html
API呼び出し時
「const apiKey = 'xxxxxxxxxxxxxxxx';」の部分は適宜変更する。
年月日のフォーマット
「Utilities.formatDate(年月日データ, 'JST', 'yyyy-MM-dd')」でフォーマットする。フォーマット指定文字は以下の通り。
https://sites.google.com/site/gasgaidobukku/utilities/formatdate
APIリクエスト時のGETパラメータ取得
APIリクエスト時はdoGet関数が動作する。GETパラメータを取得したい場合は「e.parameter.パラメータのキー」で取得できる。リファレンスは以下の通り。
https://developers.google.com/apps-script/guides/web
トリガーの設定
setHoliday関数が1日1回動作するようトリガーを設定しておく。
デプロイ
「右上のデプロイボタン→新しいデプロイ」に進み「説明」は適当、「種類の選択」はウェブアプリ、「次のユーザーとしての実行」を自分、「アクセスできるユーザー」を全員で設定する。何故か初回デプロイ時は「アクセスできるユーザー」に全員の選択肢が無かった。「デプロイを管理→アーカイブ」で削除すると2回目以降からは全員を選択できた。
デプロイが完了するとURLが発行されるのでブラウザから開いてみると正常に動作した。尚、APIキーをGETパラメータとして付与するのを忘れないよう注意する。
API利用時の注意
GASの利用制限や上限にひっかからないよう、API利用時はデータを取得後にファイル化するのが良さそう。データとは別にファイルの有効期限を設定しておき、有効期限が切れていれば再度APIからデータを取得するような形が望ましいかと思われる。ざっくりとだけど以下のような形。
//祝日APIにリクエスト
$api = file_get_contents('http://api.com/');
$holiday = json_decode($api, true);
//JSONファイル用の制限時間
$holiday['limit'] = date('Y-m-d H:i:s', strtotime('+1 day'));
//JSONファイル上書き保存
file_put_contents('./holiday.json', json_encode($holiday));
所感
GASはイマイチ業務での使いどころが思いつかないなぁ、とか考えながら勉強していたがやっと役に立ちそうなケースが出てきて嬉しい。
関連記事
-
-
GASを利用してGmailに届いたメール内容をGoogleスプレッドシートに記入する方法
WordPressのContact Form7から送信した内容をGmailで受け ...
-
-
GASとLINEを連携させて通知メッセージを送る方法のメモ
Google Apps ScriptとLINEを連携させ、LINEに何らかの通知 ...
-
-
GoogleスプレッドシートとPHPを連携させデータを取得・追記する方法
GoogleスプレッドシートとPHPプログラムを連携させたいという案件をたまに見 ...
-
-
GASとGoogleカレンダを連携し暦通りではない店休日を取得する方法
小売店等のサイトで営業日カレンダーみたいなものを表示させる際に今まではPHPで管 ...
-
-
GASで「小説家になろう」サイトの更新通知をLINEに送る方法
Google Apps Scriptの勉強として「小説家になろう」サイトの特定小 ...