自动添加 12306 火车行程到 Google Calendar
月初短短几天乘了 8 趟火车,反复调出 App 页面看登车信息很麻烦,由此起了念头,可否在下单后就自动添加行程到 Google Calendar 呢?
我的想法是,收到 12306 购票或改签成功的邮件后自动读取邮件内容,若乘车人是我的名字就把时间、车站、班次等信息加到 Google Calendar 的 Event 里,并且设置一个提前两小时的提醒。
在 Gmail 中设置 filter
首先在 Gmail 中创建一个 filter,筛选出发件人是 12306 并且内容是购票或改签成功的邮件,自动将它们移到 RailwaySchedules
的 label 下。
创建 Google Apps Script
在 Google Apps Script 中创建新的 script,复制以下代码。
function autoAddRailwayEvent() {
try {
// Define the Gmail label that stores the filtered emails
var label = GmailApp.getUserLabelByName("RailwaySchedules");
if (!label) {
Logger.log("Label not found: 'RailwaySchedules'");
return;
}
// Get only unread threads (emails)
var threads = label.getThreads();
var calendar = CalendarApp.getDefaultCalendar();
// Iterate through all unread threads (emails)
for (var i = 0; i < threads.length; i++) {
var message = threads[i].getMessages()[0];
if (!message.isUnread()) {
continue; // Skip already read messages
}
var body = message.getBody()
Logger.log("Processing email body: " + body); // Log email body for debugging
// Check if the body contains the expected information
if (body.includes("张三,")) {
// Extract the paragraph after "name" and before "ticket"
var infoSection = body.split('张三,')[1].split(',电子客票。')[0].trim();
// Extract details by splitting the paragraph based on commas
var details = infoSection.split(',');
if (details.length < 2) {
Logger.log("Unexpected format in infoSection: " + infoSection);
continue;
}
var dateTime = details[0];
var station = details[1];
var description = details.slice(2).join(','); // Join the rest as description
// Parse the date and time
var year = dateTime.substring(0, 4);
var month = dateTime.substring(5, 7) - 1; // Months are zero-indexed
var day = dateTime.substring(8, 10);
var hour = dateTime.substring(11, 13);
var minute = dateTime.substring(14, 16);
var eventDate = new Date(year, month, day, hour, minute);
// Add the event to Google Calendar with a 2-hour reminder
calendar.createEvent(station, eventDate, new Date(eventDate.getTime() + 60 * 60 * 1000))
.setDescription(description)
.addPopupReminder(120); // Reminder 2 hours before
Logger.log("Event created for: " + station + " at " + eventDate);
// Mark the email as read after processing
threads[i].markRead();
} else {
Logger.log("Email does not contain expected ticket info: " + body);
}
}
} catch (e) {
Logger.log("Error: " + e.message);
}
}
将 张三
替换成自己的名字,命名该 script 后保存。
这个脚本会执行以下动作:
- 检查邮箱
RailwaySchedules
标签下是否有未读邮件 - 遍历未读邮件,若含有指定姓名,则截取邮件中
张三,
到,电子客票。
部分内容为infoSection
- 用
,
来 splitinfoSection
,将得到的array[0]
转换为日期和时间,array[1]
为车站。 - 将车站信息作为标题、其余内容为描述添加到 Google Calendar Event,设置时间日期并提前两小时提醒
- 将对应邮件标为已读
12306 的邮件模板通常如上图,所以用 张三,
和 ,电子客票。
作为 split 的分隔字符能保证恰好截取到自己的购票信息。
创建定时 Trigger
偷懒用 ChatGPT 原话。我设置的是每小时运行一次。
Go to Google Apps Script or from your Gmail/Google Calendar, click the gear icon in the top-right corner and select See all settings > Advanced > Google Apps Script.
In the Apps Script editor, click on the clock icon on the left-side panel (called Triggers).
Click the + Add Trigger button at the bottom right.
Set up the trigger as follows:
- Choose which function to run: Select the function that processes the Gmail label (in this case,
checkLabelAndProcessEmails
) - Choose which deployment should run: Select “Head” (the default).
- Select event source: Choose “Time-driven.”
- Select type of time-based trigger: Choose an interval, such as “Minute timer,” “Hour timer,” or “Day timer.”
- Select time interval: Choose how frequently you want the script to run (e.g., every 10 minutes, once an hour, or once a day)
运行试试看,Google Calendar 里已经有相应 event 了呢!
总结
感觉代码可能有疏漏,但之后发现再说吧。这个法子也适用于其他购票提醒,对 script 做针对性修改就可以,暂时我没有更多需要大量处理的行程,姑且就先这样。
Comments