LoginSignup
1
0

献血バスのスケジュールをGoogleカレンダーに自動反映させてみた

Last updated at Posted at 2024-05-16

初めに

「あ,学校前に献血バス来てる!,けど時間ない!」
ということはありませんか?
こんなとき,事前に献血バスが来ていることがわかっていれば,それを組み込んだ予定を立てられて,便利ですよね.
実は献血バスのスケジュールは,1か月前くらいから発表されています.
献血バス運行スケジュール|東京都赤十字血液センター
(東京都以外も調べれば出てきます.)
しかし,これを自動で通知してくれる機能は存在しません.
そこで,1か月に1回程度,自動で献血バスのスケジュールを取得し,Googleカレンダーに反映させる機能を作りました.

仕様

月に一度,献血バスのスケジュールを取得し,指定したキーワード(例えば「大岡山」)に合致する場所で開催される献血のスケジュールを,指定したGoogleカレンダーに,以下のような形式で追加します.
なお,URLは予約用のリンクです.
image.png

使い方

  1. 後述のプログラムをGAS(Google Apps Script)にコピーする.
  2. スケジュールが掲載されているサイトのurlをtarget_urlに与える.
  3. GoogleカレンダーのIDをcalendar_idに与える.
    (カレンダーIDの取得方法は適宜調べてください.)
  4. 献血会場のキーワードを,keyword_place_arrayに与える.
    (下図の赤で囲んだ部分に含まれるワードです.)
    献血会場のシステム概要.png
  5. 月1回程度(恐らく月末に翌月のスケジュールが発表される?)の時間主導型トリガーを設定する

プログラム

// 献血バスのスケジュールが掲載されているページのURL(東京以外の方は変えてください)
const target_url = 'https://www.bs.jrc.or.jp/ktks/tokyo/place/m1_03_kenbus.html';
// 対象カレンダーのID
const calendar_id = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@group.calendar.google.com';
// 場所のキーワード
const place_keyword_array = ["大岡山"]

// htmlを取得する関数
function get_html(url) {
  var response = UrlFetchApp.fetch(url);
  var htmlContent = response.getContentText("utf-8");
  return htmlContent;
}

// htmlから献血場所を配列として取得する関数
function get_table(html) {
  let doc = Parser.data(html).from('<article class="mod-iconIndent01">').to('</article>').build();
  doc = doc.replace(/\t/g,"");
  doc = doc.replace(/\n/g,"");
  let table_by_day = Parser.data(doc).from('<br><p>').to('</div>').iterate();
  console.log(table_by_day);

  // 日付ごとのループ
  let table = new Array();
  let index = 0;
  for (let i = 0; i < table_by_day.length; i++) {
    const date = Parser.data(table_by_day[i]).from('').to('</p>').build();
    const today = new Date();
    const year = today.getFullYear();
    const month = Number(Parser.data(date).from('').to('').build());
    const day = Number(Parser.data(date).from('').to('').build());

    let table_by_place = Parser.data(table_by_day[i]).from('<tr><td class="tac vam">').to('</td></tr>').iterate();

    console.log(table_by_day[i]);

    // 場所ごとのループ
    for (let k = 0; k < table_by_place.length; k++) {
      table_by_place[k] = '<td class="tac vam">' + table_by_place[k] + '</td>';
      table[index] = {};
      table[index].place = Parser.data(table_by_place[k]).from('<li>').to('</li>').build();
      table[index].booking_url = Parser.data(table_by_place[k]).from('<li><a href="').to('">※Web予約はこちら').build();
      let temp = Parser.data(table_by_place[k]).from('<td class="tac vam">').to('</td>').iterate();
      console.log(temp);
      console.log(table[index]);
      table[index].municipalities = temp[0];
      table[index].time = temp[1].split("<br>");

      // 献血の開始時間,終了時間を取得
      table[index].date = new Array();
      for (let j = 0; j < table[index].time.length; j++) {
        table[index].time[j] = table[index].time[j].replace(/:/g,":"); // たまに,全角":"で区切っているところがあるので修正
        table[index].time[j] = table[index].time[j].replace("-",""); // たまに,"-"で区切っているところがあるので修正
        //console.log(table[index].time[j]);
        const temp = table[index].time[j].split("");
        
        table[index].date[j] = {};
        table[index].date[j].start_time = Utilities.parseDate(year+"/"+month+"/"+day+" "+temp[0], 'JST', 'yyyy/M/d HH:mm');
        table[index].date[j].end_time   = Utilities.parseDate(year+"/"+month+"/"+day+" "+temp[1], 'JST', 'yyyy/M/d HH:mm');

        //console.log(table[index].date[j])
      }
      index++;
    }
  }
  console.log(table);
  return table;
}

// カレンダーに反映する関数
function add_calendar(calendar_id, keyword, table) {
  let target_calendar = CalendarApp.getCalendarById(calendar_id);
  for (item of table) {
    if (item.place.includes(keyword)) {
      console.log(item.place);
      for (time_zone of item.date) {
        target_calendar.createEvent("献血バス "+item.place, time_zone.start_time, time_zone.end_time,{description:item.booking_url});
      }
    }
  }
}

function main() {
  // htmlを取得
  let html = get_html(target_url);

  // htmlから献血場所を配列として取得
  let table = get_table(html);

  // カレンダーに反映
  for (place_keyword of place_keyword_array) {
    add_calendar(calendar_id, place_keyword, table);
  }
}
1
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
1
0