Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yoonchulkoh/5820124 to your computer and use it in GitHub Desktop.
Save yoonchulkoh/5820124 to your computer and use it in GitHub Desktop.
Gmailに届いたメルマガ「堀江貴文のブログでは言えない話」からスケジュールを抽出し、自分のGoogle Calendarに登録するGoogle Apps Script
/*
* メルマガ、堀江貴文のブログでは言えない話よりスケジュールを抜き出し
* Google Calendarに登録する。
*/
var CALENDAR_NAME = 'ホリエモンのメディアスケジュール';
var SEARCH_QUERY = '堀江貴文のブログでは言えない話 3/';
var PUNCTUATION_HEADER = '■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■';
var SCHEDULE_HEADER = '今週のメディアスケジュール';
var PARTS_OF_SCHEDULE_HEADER = '◆◇';
var PARTS_OF_SCHEDULE_FOOTER = '------------------------------';
function registHoriemonCalendar() {
// 指定したカレンダーを取得
var calendars = CalendarApp.getCalendarsByName(CALENDAR_NAME);
var calendar;
if (calendars.length === 0) {
// 存在しなければ作成する
calendar = CalendarApp.createCalendar(CALENDAR_NAME);
} else {
// 存在した場合は配列で返ってくるので1番目を取り出す
calendar = calendars[0];
}
var row = 1;
// Gmailから指定文字列でスレッドを検索する
var threads = GmailApp.search(SEARCH_QUERY, 0, 10);
// スレッドで繰り返し
for (var i = 0; i < threads.length; i++) {
// スレッド内のメッセージを取得
var messages = threads[i].getMessages();
// メッセージで繰り返し
for (var j = 0; j < messages.length; j++) {
Logger.log(messages[j].getSubject());
// メッセージ本文
var body = messages[j].getBody();
// メッセージを改行で一行ずつ分解する
var splitedBody = body.split("\n");
var isMediaSchedule = false;
var isContent = false;
var content = "";
var date = "";
var title = "";
for (var k = 0; k < splitedBody.length; k++) {
// スケジュールの段落かどうか確認する
var schedule = splitedBody[k].indexOf(SCHEDULE_HEADER);
if (schedule != -1) {
var punctuation = splitedBody[k-1].indexOf(PUNCTUATION_HEADER);
if (punctuation != -1) {
// メディアスケジュール開始
isMediaSchedule = true;
}
}
// スケジュールの段落だった場合
if (isMediaSchedule) {
// 見出しを検索
var res = splitedBody[k].indexOf(PARTS_OF_SCHEDULE_HEADER);
// 見出しが見つかった
if (res != -1) {
// 既にコンテント(スケジュールの説明)がある場合は書き出し
if (content !== "") {
var contentWithLf = content.replace(/<br \/>/g, "\n");
// カレンダーに追加する
_addToCalendar(calendar, content, date);
content = "";
date = "";
row++;
}
// 見出しから日付文字列を取り出す 見出し形式:"◆◇ 6/14(fri)◆◇"
date = /\d*\/\d*/.exec(splitedBody[k]);
isContent = true;
}
// 終了見出しを検索
res = splitedBody[k].indexOf(PARTS_OF_SCHEDULE_FOOTER);
// 存在したら終了処理
if (isContent && res != -1) {
// カレンダーに追加する
_addToCalendar(calendar, content, date);
// ループを抜ける
break;
}
// スケジュール情報であればバッファに詰める
if (isContent) {
content += splitedBody[k];
}
}
}
}
}
}
// まとまっているスケジュールを改行で分解する
function _splitContent(content) {
return content.replace(/^.*?\<br \/>/, "").replace(/<br \/>/g, "\n").replace(/\n\n$/, "").split("\n\n");
}
// カレンダーに追加する
function _addToCalendar(calendar, content, date) {
// イベントの日付
var calendarDate = _newDate(date);
// その日のイベント
var eventsForDay = calendar.getEventsForDay(calendarDate);
// 堀江氏のスケジュール
var contents = _splitContent(content);
// 堀江氏のスケジュールを登録する
for (var i = 0; i < contents.length; i++) {
var exsists = false;
// 既存のイベントに存在するか確認する
for (var j = 0; j < eventsForDay.length; j++) {
 // 存在したらフラグを立ててループを抜ける
if (contents[i] === eventsForDay[j].getTitle()) {
exsists = true;
break;
}
}
// 既存のイベントが存在しなかった場合のみイベントを登録する
if (!exsists) {
Logger.log(contents[i]);
Logger.log(calendarDate);
var event = calendar.createAllDayEvent(contents[i], calendarDate, {
description: contents[i]
});
}
}
}
// 日付を生成する(現在の年を付ける)
// TODO:年またぎに対応したい
function _newDate(date) {
var d = new Date();
return new Date(d.getYear() + "/" + date);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment