Google Calendar統合でタスク管理を進化:DASHとの連携実装
はじめに
タスク管理システム(DASH)とGoogle Calendarを統合することで、タスク登録・期限管理・リマインダーを一元化できます。この記事では、複数Googleアカウントを扱いながらカレンダー連携を実現する実装を紹介します。
統合の目的
タスク追加時の自動カレンダー登録
DASHにタスクを追加すると、自動的にGoogle Calendarにも登録されます。
ユーザー: 「3/30までにニチギワールド様対応」
↓
DASHに登録(tasks.json)
↓
Google Calendar(クロスリンク)に自動登録
複数アカウント対応
アカウント判定に基づいて、適切なGoogle Calendarに振り分けます。
- クロスリンク → work@example.com
- プログラミングスクール → school@example.com
実装:Calendar API統合
認証設定
各アカウントのOAuth2トークンを管理します。
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
CALENDAR_SCOPES = ['https://www.googleapis.com/auth/calendar']
def authenticate_calendar(account):
"""
アカウント別のCalendar API認証
"""
token_map = {
"crosslink": "token_calendar_crosslink.json",
"programming_school": "token_calendar_programming.json"
}
token_path = token_map[account]
creds = Credentials.from_authorized_user_file(token_path, CALENDAR_SCOPES)
return build('calendar', 'v3', credentials=creds)
タスク→カレンダーイベント変換
def task_to_calendar_event(task):
"""
DASHタスクをGoogle Calendarイベントに変換
"""
event = {
"summary": task["title"],
"description": f"チーム: {task['team']}\n優先度: {task['priority']}\n推定時間: {task['estimated_minutes']}分",
"colorId": get_color_by_priority(task["priority"])
}
# 期限あり → 終日イベント
if task["due_date"]:
event["start"] = {"date": task["due_date"]}
event["end"] = {"date": task["due_date"]}
# 時刻指定あり → 時刻付きイベント
if task.get("due_time"):
start_datetime = f"{task['due_date']}T{task['due_time']}:00+09:00"
end_datetime = calculate_end_time(start_datetime, task["estimated_minutes"])
event["start"] = {"dateTime": start_datetime, "timeZone": "Asia/Tokyo"}
event["end"] = {"dateTime": end_datetime, "timeZone": "Asia/Tokyo"}
return event
def get_color_by_priority(priority):
"""
優先度に応じた色ID
"""
color_map = {
"high": "11", # 赤
"medium": "5", # 黄
"low": "2" # 緑
}
return color_map.get(priority, "1")
自動登録フロー
def add_task_with_calendar_sync(task_text):
"""
タスクを追加し、Google Calendarにも登録
"""
# 1. AI判定でタスク分類
task = add_task_auto(task_text)
# 2. Google Calendarに登録
try:
service = authenticate_calendar(task["account"])
event = task_to_calendar_event(task)
result = service.events().insert(
calendarId='primary',
body=event
).execute()
# カレンダーイベントIDを保存
task["calendar_event_id"] = result["id"]
save_task(task)
print(f"📅 Google Calendarに登録完了: {task['title']}")
except Exception as e:
print(f"⚠️ カレンダー登録失敗: {e}")
print(" タスクはDASHに保存済み")
return task
カレンダー→タスク同期
外部イベントの取り込み
Google Calendarに直接追加されたイベントをDASHに取り込みます。
def sync_calendar_to_dash(account, days_ahead=7):
"""
Google Calendarの新規イベントをDASHに同期
"""
service = authenticate_calendar(account)
# 今後N日間のイベントを取得
now = datetime.now().isoformat() + 'Z'
end = (datetime.now() + timedelta(days=days_ahead)).isoformat() + 'Z'
events_result = service.events().list(
calendarId='primary',
timeMin=now,
timeMax=end,
singleEvents=True,
orderBy='startTime'
).execute()
events = events_result.get('items', [])
for event in events:
event_id = event['id']
# 既にDASHに登録済みか確認
if is_event_in_dash(event_id):
continue
# 新規イベント → DASHに追加
task = calendar_event_to_task(event, account)
add_task_to_dash(task)
print(f"📥 カレンダーから取り込み: {task['title']}")
イベント→タスク変換
def calendar_event_to_task(event, account):
"""
Google CalendarイベントをDASHタスクに変換
"""
title = event.get('summary', '無題')
description = event.get('description', '')
# 開始日時の取得
start = event['start'].get('date') or event['start'].get('dateTime', '').split('T')[0]
task = {
"id": f"task-calendar-{event['id'][:8]}",
"title": title,
"account": account,
"team": "general", # 外部イベントはgeneral扱い
"priority": "medium",
"status": "todo",
"due_date": start,
"calendar_event_id": event['id'],
"source": "calendar",
"created_at": datetime.now().isoformat(),
"notes": description
}
return task
リマインダー機能
30分前通知
Cronジョブでカレンダーをチェックし、開始30分前にリマインド通知します。
#!/bin/bash
# calendar_integration.sh remind <minutes>
MINUTES=${1:-30}
python3 << 'EOF'
import sys
from datetime import datetime, timedelta
from google_calendar_api import authenticate_calendar, get_upcoming_events
minutes = int(sys.argv[1]) if len(sys.argv) > 1 else 30
now = datetime.now()
end_time = now + timedelta(minutes=minutes)
# 両アカウントをチェック
for account in ['crosslink', 'programming_school']:
service = authenticate_calendar(account)
events = get_upcoming_events(service, now, end_time)
if events:
for event in events:
start_str = event['start'].get('dateTime', event['start'].get('date'))
print(f"📅 {account.upper()}: {event['summary']} ({start_str})")
if not any_events:
print("✅ 予定なし")
EOF
Cron設定
{
"name": "会議準備リマインダー(30分前)",
"schedule": {
"kind": "every",
"everyMs": 900000
},
"sessionTarget": "isolated",
"payload": {
"kind": "agentTurn",
"message": "cd ~/.openclaw/workspace/dash && bash calendar_integration.sh remind 30"
},
"delivery": {
"mode": "announce"
}
}
双方向同期
タスク完了時のカレンダー更新
DASHでタスクを完了すると、カレンダーイベントも完了ステータスに更新します。
def complete_task_with_calendar_sync(task_id):
"""
タスク完了時、カレンダーイベントも更新
"""
task = get_task(task_id)
# DASHで完了
task["status"] = "done"
task["completed_at"] = datetime.now().isoformat()
save_task(task)
# カレンダーイベントを更新(色を灰色に)
if task.get("calendar_event_id"):
try:
service = authenticate_calendar(task["account"])
event = service.events().get(
calendarId='primary',
eventId=task["calendar_event_id"]
).execute()
event["colorId"] = "8" # 灰色(完了)
event["summary"] = f"✅ {event['summary']}"
service.events().update(
calendarId='primary',
eventId=task["calendar_event_id"],
body=event
).execute()
print(f"📅 カレンダーも完了に更新: {task['title']}")
except Exception as e:
print(f"⚠️ カレンダー更新失敗: {e}")
カレンダーイベント削除時の同期
カレンダーからイベントを削除したら、DASHタスクも削除します(定期チェックで検出)。
def detect_deleted_calendar_events():
"""
カレンダーから削除されたイベントを検出し、DASHからも削除
"""
tasks = load_tasks()
for task in tasks["tasks"]:
if not task.get("calendar_event_id"):
continue
try:
service = authenticate_calendar(task["account"])
event = service.events().get(
calendarId='primary',
eventId=task["calendar_event_id"]
).execute()
except Exception as e:
if "deleted" in str(e).lower() or "404" in str(e):
# カレンダーから削除済み → DASHからも削除
delete_task(task["id"])
print(f"🗑️ カレンダー削除に同期: {task['title']}")
まとめ
DASHとGoogle Calendarを統合することで、タスク管理が飛躍的に効率化されます。複数アカウント対応・双方向同期・リマインダー機能により、見落としやダブルブッキングを防げます。
関連記事:
– AI駆動タスク自動振り分け
– Gmail重要メール監視システム構築
– OpenClaw Cronジョブ活用術