LoginSignup
13
0

Go x Google Calendar API x Copilot 、簡易なチーム日程調整を作ってみる

Last updated at Posted at 2023-12-15

この記事は Wano Group Advent Calendar 2023 の16日目の記事です。

概要

最近Copilotの使い方を学び始めました。
ちょうどチームメンバーの日程調整機能を作りたいので、Google Calendar APIとCopilotを使って作ってみました。

先ずはgolangでGoogle Calendar APIを使う

google提供のクイックスタートを通りにやっていくだけで、個別のカレンダー情報を取得できます。さらに、calendar/v3/freeBusy API は複数メンバーのカレンダーの予定時間情報を返します:


	jst, _ := time.LoadLocation("Asia/Tokyo")
	events, err := srv.Freebusy.Query(&calendar.FreeBusyRequest{
		Items: []*calendar.FreeBusyRequestItem{
			{
				Id: "XXXXX1@gmail.com",  // メンバー1カレンダーのメールアドレス
			},
			{
				Id: "XXXXX2@gmail.com",  // メンバー2カレンダーのメールアドレス
			},
		},
        // クエリの間隔の終了時刻
		TimeMax:  time.Date(2023, month, days, 24, 0, 0, 0, jst).Format(time.RFC3339),
        // クエリの間隔の開始時刻
		TimeMin:  time.Date(2023, month, 1, 0, 0, 0, 0, jst).Format(time.RFC3339),
        // レスポンスで使用されるタイムゾーン
		TimeZone: "Asia/Tokyo",
	}).Do()

しかし、複数対象の共通空き時間を取得するAPIがあるかどうかを探しましたが、
残念ですが、そのような機能は提供されていないようですので、この関数を自分で実装してみる。

	// 1ヶ月の分を確認
	for day := 1; day < days; day++ {

		// 確認したいの時間帯 12:00-13:00 / 12:30-13:30 / 13:00-14:00
		checkTimeStructs := make([]CheckTimeStruct, 0)
		checkTimeStructs = append(checkTimeStructs, CheckTimeStruct{
			StartTime: time.Date(2023, month, day, 12, 0, 0, 0, jst),
			EndTime:   time.Date(2023, month, day, 13, 0, 0, 0, jst),
			IsUsable:  true,
		})
		checkTimeStructs = append(checkTimeStructs, CheckTimeStruct{
			StartTime: time.Date(2023, month, day, 12, 30, 0, 0, jst),
			EndTime:   time.Date(2023, month, day, 13, 30, 0, 0, jst),
			IsUsable:  true,
		})
		checkTimeStructs = append(checkTimeStructs, CheckTimeStruct{
			StartTime: time.Date(2023, month, day, 13, 0, 0, 0, jst),
			EndTime:   time.Date(2023, month, day, 14, 0, 0, 0, jst),
			IsUsable:  true,
		})

		// 土日は除外
		if checkTimeStructs[0].StartTime.Weekday() == 0 || checkTimeStructs[0].StartTime.Weekday() == 6 {
			continue
		}

		// メンバーの予定を確認
		for _, item := range events.Calendars {
			for index, _ := range checkTimeStructs {
                // 日付が範囲内にあるかどうかの確認関数
				if checkDateInPeriod(item.Busy, checkTimeStructs[index].StartTime, checkTimeStructs[index].EndTime) {
					checkTimeStructs[index].IsUsable = false
				}
			}
		}

		//結果を出力
		for index, single := range checkTimeStructs {

			if index == 0 && single.IsUsable {
				fmt.Printf("%d日の12:00-13:00は空いています。\n", day)
			}
			if index == 1 && single.IsUsable {
				fmt.Printf("%d日の12:30-13:30は空いています。\n", day)
			}
			if index == 2 && single.IsUsable {
				fmt.Printf("%d日の13:00-14:00は空いています。\n", day)
			}
		}
	}

}

よく使うの関数はCopilotに補完

補完の機能について、基本の操作はこの感じ:
Command + → -> ワードごとの適用
Tab -> サジェスト内容を適用する
Esc -> サジェスト内容を棄却出来る

実際に試したら、すごく便利と思います
例えば:
nb3bw-fr6kt.gif

それを使って時間帯確認周りの関数が簡単に作られた

// 時間帯が範囲内にあるかどうか
func checkDateDuplicated(inStart time.Time, inEnd time.Time, targetStart time.Time, targetEnd time.Time) bool {
	if inStart.Before(targetEnd) && targetStart.Before(inEnd) {
		return true
	}
	return false
}

// 日付が範囲内にあるかどうか
func checkDateInPeriod(in []*calendar.TimePeriod, targetStart time.Time, targetEnd time.Time) bool {

	if len(in) == 0 {
		return false
	}
	for _, v := range in {
		start, _ := time.Parse(time.RFC3339, v.Start)
		end, _ := time.Parse(time.RFC3339, v.End)
		if checkDateDuplicated(start, end, targetStart, targetEnd) {
			return true
		}
	}
	return false
}

// うるう年の判定
func isLeapYear(year int) bool {
	if year%400 == 0 {
		return true
	} else if year%100 == 0 {
		return false
	} else {
		return year%4 == 0
	}
}

// 月の日数を返す
func daysInMonth(year int, month time.Month) int {
	switch month {
	case time.February:
		if isLeapYear(year) {
			return 29
		} else {
			return 28
		}
	case time.April, time.June, time.September, time.November:
		return 30
	default:
		return 31
	}
}

以上の関数は全部Copilotで生成された、結構楽ですね!

最後に

出力した結果がこちらです。

スクリーンショット 2023-12-11 0.20.59.png

いい感じでみんなの空き日時を抽出することを出来ました。

今回はGoogle Calendar API x Copilotを活用して簡易な日程調整を作成しました。
こういう組み合わせると意外と面白いことができると思います。

現在、Wanoグループでは人材募集をしています。興味のある方は下記を参照してください。
JOBS | Wano Group

13
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
0