Goでicalendarを生成してみた

はじめに

Goでicalendarを生成してみたいけどどうやるんだっけ?って人向けの記事です(多分そんなにいないと思いますが……)

背景

仕事のコードで予約されているデータなどをGoogleカレンダーなどへ連携されるようにしたいという話が出たのが事のきっかけです。
で、同僚の人と「どうしましょうかー」と話してて、「icalendarを使えばよさそう」となり、実際に実装してみた感じです。

作ったもの

github.com

凄くシンプルに実装したサンプルになります。

使っているライブラリとしては以下のものを使っています。

  • gin-gonic/gin(APIサーバー用)

github.com

github.com

やったこと

基本的にシンプルなginのサーバーを書いて、

func main() {
    err := godotenv.Load(".env")
    if err != nil {
        fmt.Printf("can not load .env!")
    }

    r := gin.Default()
    r.GET("/icals", func(c *gin.Context) {
        ical := generateIcal()
        c.String(http.StatusOK, ical)
    })
    r.Run()
}

あとはただgolang-ical使って構造体経由でカレンダーデータを作成した感じですね。

type Calendar struct {
    Title string
    StartAt time.Time
    EndAt time.Time
    ZoomURL string
}

func generateIcal() string {
    cal := ical.NewCalendar()
    cal.SetMethod(ical.MethodRequest)

    var calendars []Calendar

    for i := 0; i < 10; i++ {
        calendar := Calendar{
            Title: fmt.Sprintf("HALO %d", i),
            StartAt: time.Now().Add(time.Duration(i) * time.Hour),
            EndAt: time.Now().Add(time.Duration(i + 1) * time.Hour),
            ZoomURL: os.Getenv("ZOOM_URL"),
        }

        calendars = append(calendars, calendar)
    }

    for _, calendar := range calendars {
        event := cal.AddEvent(calendar.Title)
        event.SetStartAt(calendar.StartAt)
        event.SetEndAt(calendar.EndAt)
        event.SetSummary(calendar.Title)
        event.SetDescription(calendar.Title)
        event.SetDescription(calendar.ZoomURL)
        event.SetURL(calendar.ZoomURL)
        event.SetLocation(calendar.ZoomURL)
    }

    return cal.Serialize()
}

実用性とか考えるとZoomとかのURLも添付できたら面白そうだったのでZoomのURLとかも追加してる感じですね。 意外と癖なくサクッと作れたので簡単なカレンダーAPIとかGoで書くのも面白そうです。

あとは、ngrokを使って、Googleカレンダーとかに追加できるようにして動作確認したりくらいですね。

ngrok http 8080

今後

実際に仕事で使うコードにするとなると色々考えないといけないことも多いですが、すごく簡単にicalendarsを生成できたのでいい感じです。