Skip to content

Commit 85d4d05

Browse files
committed
sync calendar作成
1 parent 6b42ae6 commit 85d4d05

File tree

5 files changed

+160
-0
lines changed

5 files changed

+160
-0
lines changed
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Build & Deploy Sync Calendar
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- packages/sync-calendar/**
9+
workflow_dispatch:
10+
11+
jobs:
12+
deploy:
13+
runs-on: ubuntu-22.04
14+
timeout-minutes: 15
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
19+
- name: Setup Node.js 20.11.0
20+
uses: actions/setup-node@v4
21+
with:
22+
node-version: '20.11.0'
23+
24+
- name: Install Packages
25+
run: |
26+
corepack enable
27+
yarn workspaces focus sync-calendar
28+
29+
- name: Create .clasprc.json
30+
run: |
31+
echo "${{ secrets.CLASP_RC_BASE64 }}" | base64 --decode > ~/.clasprc.json
32+
33+
- name: Create .clasp.json
34+
run: |
35+
cat > ./packages/sync-calendar/.clasp.json <<EOF
36+
{
37+
"scriptId": "${{ secrets.SYNC_CALENDAR_SCRIPT_ID }}",
38+
"rootDir": "./dist"
39+
}
40+
EOF
41+
42+
- name: Build & Deploy
43+
run: |
44+
yarn workspace sync-calendar push
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"timeZone": "Asia/Tokyo",
3+
"dependencies": {
4+
"enabledAdvancedServices": [
5+
{
6+
"userSymbol": "Calendar",
7+
"version": "v3",
8+
"serviceId": "calendar"
9+
}
10+
]
11+
},
12+
"exceptionLogging": "STACKDRIVER",
13+
"runtimeVersion": "V8"
14+
}

packages/sync-calendar/build.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const { GasPlugin } = require("esbuild-gas-plugin");
2+
3+
require("esbuild")
4+
.build({
5+
entryPoints: ["src/main.ts"],
6+
bundle: true,
7+
outfile: "dist/main.js",
8+
plugins: [GasPlugin],
9+
})
10+
.catch(() => process.exit(1));

packages/sync-calendar/package.json

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "sync-calendar",
3+
"version": "0.0.0",
4+
"scripts": {
5+
"build": "node build.js && cp appsscript.json dist/",
6+
"push": "yarn build && clasp push"
7+
},
8+
"devDependencies": {
9+
"@google/clasp": "2.4.2",
10+
"@types/google-apps-script": "1.0.77",
11+
"esbuild": "0.19.6",
12+
"esbuild-gas-plugin": "0.8.0"
13+
},
14+
"dependencies": {
15+
"utils": "workspace:*"
16+
}
17+
}

packages/sync-calendar/src/main.ts

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
function main() {
2+
// スプレッドシートのIDとシート名を設定
3+
const spreadsheetId = "1-Hy-8r_Qoruq_LwpIg1Uxwn0mlixL_X40wXXgW3RHCA";
4+
const sheetName = "シート1"; // シート名を入力
5+
6+
// スプレッドシートを開いてデータを取得
7+
const sheet =
8+
SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName);
9+
const data = sheet?.getDataRange().getValues(); // シートの全データを取得
10+
11+
// ヘッダーを除くデータ部分を処理
12+
const rows = data?.slice(1); // 1行目(ヘッダー)を除外
13+
14+
if (rows === undefined) {
15+
return null;
16+
}
17+
18+
for (const row of rows) {
19+
const name = row[0]; // 名前
20+
const workCalendarId = row[1]; // org_id
21+
const personalCalendarId = row[2]; // personal_id
22+
23+
try {
24+
// 同期対象期間(過去1日から未来30日まで)
25+
const now = new Date();
26+
const startTime = new Date(now.getTime() - 24 * 60 * 60 * 1000); // 過去1日
27+
const endTime = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000); // 未来30日
28+
29+
// カレンダーオブジェクトを取得
30+
const workCal = CalendarApp.getCalendarById(workCalendarId);
31+
const personalCal = CalendarApp.getCalendarById(personalCalendarId);
32+
33+
Logger.log(workCal);
34+
Logger.log(personalCal);
35+
if (!workCal || !personalCal) {
36+
throw new Error("カレンダーが見つかりません");
37+
}
38+
39+
// 個人カレンダーの予定を取得
40+
const personalEvents = personalCal.getEvents(startTime, endTime);
41+
42+
// 社用カレンダーの予定を確認して既存の予定を取得
43+
const workEvents = workCal.getEvents(startTime, endTime);
44+
45+
// 社用カレンダーにコピー済みの予定を識別するための識別子(タイトルにタグを追加)
46+
const SYNC_TAG = "[Synced]";
47+
48+
// 既存の社用カレンダーの予定タイトルを収集
49+
const workEventTitles = new Set(
50+
workEvents.map((event) => event.getTitle()),
51+
);
52+
53+
// 個人カレンダーの予定を社用カレンダーにコピー
54+
for (const event of personalEvents) {
55+
const title = `${SYNC_TAG} ${event.getTitle() || "プライベート予定"}`;
56+
57+
// 同じタイトルの予定が既に社用カレンダーに存在するか確認
58+
if (workEventTitles.has(title)) {
59+
return; // 既存の場合はスキップ
60+
}
61+
62+
// 社用カレンダーに予定を作成
63+
workCal.createEvent(title, event.getStartTime(), event.getEndTime(), {
64+
description: "この予定は個人用カレンダーから同期されています。",
65+
visibility: CalendarApp.Visibility.PRIVATE,
66+
});
67+
}
68+
69+
// ログに出力(デバッグ用)
70+
Logger.log(`同期完了: ${name}`);
71+
} catch (error) {
72+
Logger.log(`エラー発生 (${name}): ${error}`);
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)