Created
April 4, 2021 05:22
-
-
Save jenssss/1d17319085f89c91f5967c518b08fac0 to your computer and use it in GitHub Desktop.
Automatically update google and timetree calendars from gmail using google apps script
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 readFoodAndPutInCalendar() { | |
var foods = readFoods(); | |
for (var i = 0; i < foods.length; i++) { | |
if (isThisANewFood(foods[i])){ | |
putFoodInGCalendar(foods[i]); | |
putFoodInTimetree(foods[i]); | |
} | |
} | |
} | |
function printFoodsToLog(){ | |
var foods = readFoods(); | |
Logger.log(foods); | |
for (var i = 0; i < foods.length; i++) { | |
Logger.log(parseFood(foods[i])); | |
} | |
} | |
function readFoods(){ | |
var yoshiLabel = GmailApp.getUserLabelByName("Receipts/Yoshikei"); | |
var yoshiThreads = yoshiLabel.getThreads(0, 5); | |
var yoshiThread = yoshiThreads[0]; | |
var foods = getFoodsFromThread(yoshiThread); | |
if (! foods.length){ | |
yoshiThread = yoshiThreads[1]; | |
foods = getFoodsFromThread(yoshiThread); | |
} | |
return foods; | |
} | |
function getFoodsFromThread(yoshiThread){ | |
var messages = yoshiThread.getMessages(); | |
var message; | |
var foods = []; | |
for (var i = 0; i < messages.length; i++) { | |
message = messages[i].getPlainBody(); | |
foods = foods.concat(getFoods(message)); | |
} | |
return foods; | |
} | |
function parseFoodDate(dateString){ | |
var miliSecsPerHour = 3600*1000; | |
var date = new Date(Date.parse(dateString.substr(0, 10))+19*miliSecsPerHour); | |
var endTime = new Date(date.getTime()+2*miliSecsPerHour); | |
return [date, endTime]; | |
} | |
function parseFoodName(foodString){ | |
var foodArray = foodString.replace(/\s+/g, " ").replace(":", " ").split(" "); | |
var foodName = foodArray[foodArray.length - 2]; | |
foodName = foodName.split("(")[0] | |
return foodName; | |
} | |
function parseFood(food){ | |
const [date, endTime] = parseFoodDate(food[0]); | |
const foodName = parseFoodName(food[1]); | |
return [date, endTime, foodName]; | |
} | |
function getFoods(message) { | |
var matches = []; | |
var divideMatchString = "下記内容が、ご注文週の最終注文内容となります。"; | |
var n = message.search(divideMatchString); | |
if (n != -1){ | |
message = message.substring(n); | |
// This regexp matches to a date in yyyy/mm/dd format, then parenthesis with any character followed by line break | |
// After that any character until line break are matched | |
var matchString = "([0-9]{4}/[0-9]{2}/[0-9]{2}(.))(.*)"; | |
var match = message.match(matchString); | |
var i=0; | |
while(match != null && i<10){ | |
var dateString = match[1]; | |
var foodString = match[2]; | |
matches.push([dateString, foodString]); | |
message = message.substr(match.index+match[0].length); | |
match = message.match(matchString); | |
i = i + 1 | |
} | |
} | |
return matches; | |
} | |
var userProperties = PropertiesService.getUserProperties(); | |
const oldFoodName = "old_foods"; | |
function clearOldFoods(){ | |
var old_foods = []; | |
userProperties.setProperty(oldFoodName, JSON.stringify(old_foods)); | |
} | |
function isThisANewFood(food){ | |
var old_foods = userProperties.getProperty(oldFoodName); | |
if (old_foods == null){ | |
old_foods = []; | |
} else{ | |
old_foods = JSON.parse(old_foods) | |
} | |
if (old_foods.includes(food[0])){ | |
Logger.log("Already did this food, not doing that again") | |
return false | |
}else{ | |
Logger.log("New food!"); | |
old_foods.push(food[0]); | |
userProperties.setProperty(oldFoodName, JSON.stringify(old_foods)); | |
return true | |
} | |
} | |
function putFoodInGCalendar(food){ | |
const [date, endTime, foodName] = parseFood(food); | |
var calId = "**********"; | |
var cal = CalendarApp.getCalendarById(calId); | |
var eventsThatDay = cal.getEventsForDay(date, {search:"ヨシケイ"}); | |
if (eventsThatDay.length == 0) { | |
cal.createEvent(foodName, date, endTime, {"description": "ヨシケイ"}); | |
Logger.log(date); | |
Logger.log("Created event"); | |
} else { | |
Logger.log(date); | |
Logger.log("Event already exists"); | |
} | |
} | |
function putFoodInTimetree(food){ | |
const [date, endTime, foodName] = parseFood(food); | |
Logger.log(date) | |
var AccessToken = "**********"; | |
var CalendarID = "**********" | |
var me_ID1 = "**********"; | |
var me_ID2 = "**********"; | |
var me = {"id":me_ID1,"type":"user"}; | |
var headers = {"Accept" : "application/vnd.timetree.v1+json", | |
"Authorization" : "Bearer "+AccessToken}; | |
var event_data = { | |
"data": { | |
"attributes": { | |
"category": "schedule", | |
"title": foodName, | |
"all_day": false, | |
"start_at": date.toISOString(), | |
"end_at": endTime.toISOString(), | |
"description": "ヨシケイ", | |
"location": "Home", | |
"url": "https://www2.yoshikei-dvlp.co.jp/webodr/" | |
}, | |
"relationships": { | |
"label": { | |
"data": { | |
"id": meID2, | |
"type": "label" | |
} | |
}, | |
"attendees": { | |
"data": [ | |
me | |
] | |
} | |
}, | |
} | |
}; | |
var event_data_str = JSON.stringify(event_data); | |
headers["Content-Type"] = "application/json;" | |
var options = {"method": "POST", | |
"headers": headers, | |
"payload": event_data_str, | |
"muteHttpExceptions": true}; | |
var response = UrlFetchApp.fetch("https://timetreeapis.com/calendars/"+CalendarID+"/events", options); | |
var insertedEvent = response.getContentText(); | |
Logger.log(insertedEvent); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment