(更新: 2026.03.25)

定期予定の作成を「毎週水曜」で可能にした

定期予定の作成を「毎週水曜」で可能にした

「毎週水曜9時に朝会」「毎月末にシフト作成」みたいな定期予定を、自然言語で登録できるようにした。

なぜ定期予定が必要なのか

毎週やるタスク

  • 毎週土曜:座席表作成
  • 毎週月曜:週次報告
  • 毎週水曜:チームMTG

毎月やるタスク

  • 毎月28日:シフト未提出者への催促
  • 毎月末:請求書提出

これらを毎回手動で登録するのは面倒

実装

1. 定期パターンの検出

// parse_recurring.js
const detectRecurring = (text) => {
  if (/毎週/.test(text)) {
    return { type: 'weekly', interval: 1 };
  }
  if (/毎月/.test(text)) {
    return { type: 'monthly', interval: 1 };
  }
  if (/毎日/.test(text)) {
    return { type: 'daily', interval: 1 };
  }
  return null;
};

2. 曜日の抽出

const extractDayOfWeek = (text) => {
  const days = {
    '月曜': 'MO',
    '火曜': 'TU',
    '水曜': 'WE',
    '木曜': 'TH',
    '金曜': 'FR',
    '土曜': 'SA',
    '日曜': 'SU'
  };

  for (const [day, code] of Object.entries(days)) {
    if (text.includes(day)) {
      return code;
    }
  }
  return null;
};

3. Google Calendar の繰り返しルール(RRULE)生成

const generateRRule = (recurringInfo, dayOfWeek) => {
  if (recurringInfo.type === 'weekly' && dayOfWeek) {
    return `RRULE:FREQ=WEEKLY;BYDAY=${dayOfWeek}`;
  }
  if (recurringInfo.type === 'monthly') {
    return 'RRULE:FREQ=MONTHLY';
  }
  if (recurringInfo.type === 'daily') {
    return 'RRULE:FREQ=DAILY';
  }
  return null;
};

4. Googleカレンダーに登録

const createRecurringEvent = async (title, startDate, rrule) => {
  const event = {
    summary: title,
    start: {
      dateTime: startDate.toISOString(),
      timeZone: 'Asia/Tokyo',
    },
    end: {
      dateTime: new Date(startDate.getTime() + 60 * 60 * 1000).toISOString(),
      timeZone: 'Asia/Tokyo',
    },
    recurrence: [rrule],
  };

  await calendar.events.insert({
    calendarId: 'primary',
    resource: event,
  });
};

使用例

例1:毎週水曜9時に朝会

入力: 毎週水曜9時に朝会
→ カレンダー登録:
  - タイトル: 朝会
  - 開始: 毎週水曜 9:00
  - 繰り返し: RRULE:FREQ=WEEKLY;BYDAY=WE

例2:毎月末にシフト作成

入力: 毎月末にシフト作成
→ カレンダー登録:
  - タイトル: シフト作成
  - 開始: 毎月末
  - 繰り返し: RRULE:FREQ=MONTHLY

詰まったポイント

「毎月末」の扱い

GoogleカレンダーのRRULEでは、「毎月末」を直接指定できない。

対処法:毎月28日に設定して、ユーザーが手動で調整する運用にした。

終了条件

「いつまで繰り返すか」を指定しないと、永遠に繰り返す

デフォルトで1年後までに設定した:

const endDate = new Date();
endDate.setFullYear(endDate.getFullYear() + 1);
rrule += `;UNTIL=${endDate.toISOString()}`;

まとめ

定期予定は一度設定すれば、以降は自動で登録されるので便利。

毎週・毎月のルーチンタスクを自然言語で登録できるだけで、運用がかなり楽になる。

タグ: #自動化 #カレンダー #定期タスク