iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0
SideProject30

行事曆不再NG:Notion API&Google Calendar跨平台整合發想系列 第 27

Day 27 Notion API & Google Calendar API Integration - Sync Google Calendar to Notion

  • 分享至 

  • xImage
  •  

今天小改了一下code,最近上班比較忙,但這幾天還是會盡量趕一下進度

main.go

func main() {
	r := gin.Default()

	c := controller.NewController()

	v1 := r.Group("/api/v1")
	{
		notion := v1.Group("/notion")
		{
			notion.POST("/createDatabase/:pageId", c.CreateNotionDatabase)
			notion.POST("/queryDatabase/:databaseId", c.QueryNotionDatabase)
			notion.POST("/createDBPage/:databaseId", c.CreateNotionDBPage)
		}
		googleCalendar := v1.Group("/googleCalendar")
		{
			googleCalendar.GET("/getEventList/:calendarId", c.GetGoogleCalendarEventList)
		}
		sync := v1.Group("/sync")
		{
			sync.POST("/syncNotionToGoogleCalendar/:databaseId/:calendarId", c.SyncGoogleCalendarToNotion)
		}
...

首先先在main.go的地方加上sync這個api,主要就是用來sync google calendar到notion

calendarModel.go

package domainmodel

import "time"

type CalendarDomain struct {
	Event     string    `json:"event"`
	StartTime time.Time `json:"startTime"`
	EndTime   time.Time `json:"dateTime"`
}

在model的地方加上了一下calendarModel.go,主要是要讓兩隻api有可以溝通的model

notion.go

func (c *Controller) QueryNotionDatabase(ctx *gin.Context) {
	databaseId := ctx.Param("databaseId")

	var requests requestModel.NotionQueryDatabaseRequest
	if err := ctx.ShouldBindJSON(&requests); err != nil {
		ctx.JSON(400, gin.H{"error": err.Error()})
		return
	}

	response := infra.QueryNotionDatabaseService(databaseId, requests)

	ctx.JSON(http.StatusOK, response)
}

func (c *Controller) CreateNotionDBPage(ctx *gin.Context) {
	databaseId := ctx.Param("databaseId")

	var requests requestModel.NotionCreateDBPageRequest
	if err := ctx.ShouldBindJSON(&requests); err != nil {
		ctx.JSON(400, gin.H{"error": err.Error()})
		return
	}

	response := infra.CreateNotionPageService(databaseId, requests)

	ctx.JSON(http.StatusOK, response)
}

再來是notion controller的地方,把主要的內容抽出來,改成function

這樣sync這隻api在call的時候才有function可以呼叫,所以將中間抽出來的內容改在infra的地方

infra

package infra

import (
	"time"

	"github.com/gin-gonic/gin"
	"github.com/guancioul/NotionGoogleCalendarIntegration/model/responseModel"
	"github.com/guancioul/NotionGoogleCalendarIntegration/util"
	"google.golang.org/api/calendar/v3"
	"google.golang.org/api/option"
)

func GetGoogleCalendarEventListService(calendarId string, timeMin string, timeMax string, ctx *gin.Context) *calendar.Events {
	configHandler := util.NewConfigHandler()
	auth := configHandler.GetSecretConfig().Get("GoogleSecretKey")

	calendarService, err := calendar.NewService(ctx, option.WithAPIKey(auth.(string)))
	if err != nil {
		panic(err)
	}

	eventList := &calendar.Events{}
	switch {
	case timeMin != "" && timeMax != "":
		eventList, err = calendarService.Events.List(calendarId).TimeMin(timeMin).TimeMax(timeMax).Do()
	case timeMax != "":
		eventList, err = calendarService.Events.List(calendarId).TimeMax(timeMax).Do()
	case timeMin != "":
		eventList, err = calendarService.Events.List(calendarId).TimeMin(timeMin).Do()
	default:
		eventList, err = calendarService.Events.List(calendarId).Do()
	}
	if err != nil {
		panic(err)
	}

	var response responseModel.CalendarEvents
	response.Kind = eventList.Kind
	response.Etag = eventList.Etag
	response.Summary = eventList.Summary
	response.Description = eventList.Description
	response.Updated = eventList.Updated
	response.TimeZone = eventList.TimeZone
	response.AccessRole = eventList.AccessRole
	response.NextSyncToken = eventList.NextSyncToken

	for _, item := range eventList.Items {
		response.Items = append(response.Items, responseModel.Event{
			Kind:     item.Kind,
			Etag:     item.Etag,
			Id:       item.Id,
			Status:   item.Status,
			HtmlLink: item.HtmlLink,
			Created:  item.Created,
			Updated:  item.Updated,
			Summary:  item.Summary,
			Creator: struct {
				Email string `json:"email"`
			}{
				Email: item.Creator.Email,
			},
			Organizer: struct {
				Email       string `json:"email"`
				DisplayName string `json:"displayName"`
				Self        bool   `json:"self"`
			}{
				Email:       item.Organizer.Email,
				DisplayName: item.Organizer.DisplayName,
				Self:        item.Organizer.Self,
			},
			Start: struct {
				DateTime string `json:"dateTime"`
				TimeZone string `json:"timeZone"`
			}{
				DateTime: item.Start.DateTime,
				TimeZone: item.Start.TimeZone,
			},
			End: struct {
				DateTime string `json:"dateTime"`
				TimeZone string `json:"timeZone"`
			}{
				DateTime: item.End.DateTime,
				TimeZone: item.End.TimeZone,
			},
			ICalUID:   item.ICalUID,
			EventType: item.EventType,
		})
	}

	return eventList
}

func CheckTimeFormat(timeStr string) error {
	if timeStr != "" {
		_, err := time.Parse("2006-01-02T15:04:05+00:00", timeStr)
		if err != nil {
			return err
		}
	}
	return nil
}
package infra

import (
	"encoding/json"
	"io"
	"log"

	"github.com/guancioul/NotionGoogleCalendarIntegration/handler"
	"github.com/guancioul/NotionGoogleCalendarIntegration/model/requestModel"
	"github.com/guancioul/NotionGoogleCalendarIntegration/model/responseModel"
	"github.com/guancioul/NotionGoogleCalendarIntegration/util"
)

func QueryNotionDatabaseService(databaseId string, requests requestModel.NotionQueryDatabaseRequest) responseModel.NotionQueryDatabaseResponse {
	// Get Authorization from config
	configHandler := util.NewConfigHandler()
	auth := configHandler.GetSecretConfig().Get("Authorization")

	// Marshal the struct to json
	requestJson, err := json.Marshal(requests)
	if err != nil {
		log.Fatalln(err)
	}

	// Send the request to Notion API
	client := handler.NewClient()
	header := map[string]string{
		"Authorization":  auth.(string),
		"Notion-Version": "2022-06-28",
		"Content-Type":   "application/json",
	}
	body := []byte(requestJson)

	response, err := client.Post("https://api.notion.com/v1/databases/"+databaseId+"/query", header, body)
	if err != nil {
		log.Fatalln(err)
	}
	defer response.Body.Close()

	// Change the response body to []byte type
	responseBody, err := io.ReadAll(response.Body)
	if err != nil {
		log.Fatalln(err)
	}
	bodyStr := string(responseBody)
	var data []byte = []byte(bodyStr)

	// Unmarshal the response body to struct
	var responseQueryNotionDatabase responseModel.NotionQueryDatabaseResponse
	json.Unmarshal(data, &responseQueryNotionDatabase)

	return responseQueryNotionDatabase
}

func CreateNotionPageService(databaseId string, requests requestModel.NotionCreateDBPageRequest) responseModel.NotionCreateDatabaseResponse {
	// Get Authorization from config
	configHandler := util.NewConfigHandler()
	auth := configHandler.GetSecretConfig().Get("Authorization")

	propertiesJson, err := json.Marshal(requests.Properties)
	if err != nil {
		log.Fatalln(err)
	}

	// Send the request to Notion API
	client := handler.NewClient()
	header := map[string]string{
		"Authorization":  auth.(string),
		"Notion-Version": "2022-06-28",
		"Content-Type":   "application/json",
	}
	bodyString := `{
			"parent": {
				"database_id": "` + databaseId + `"
			},
			"properties": ` + string(propertiesJson) + ` 
		}`
	body := []byte(bodyString)

	response, err := client.Post("https://api.notion.com/v1/pages", header, body)
	if err != nil {
		log.Fatalln(err)
	}
	defer response.Body.Close()

	// Change the response body to []byte type
	responseBody, err := io.ReadAll(response.Body)
	if err != nil {
		log.Fatalln(err)
	}
	bodyStr := string(responseBody)
	var data []byte = []byte(bodyStr)

	// Unmarshal the response body to struct
	var responseCreateNotionDatabase responseModel.NotionCreateDatabaseResponse
	json.Unmarshal(data, &responseCreateNotionDatabase)

	return responseCreateNotionDatabase
}

這邊就簡單的show一下抽出來的function,這裡面的操作在前幾天都有提到

明天會把sync的這隻api處理好,然後有時間的話就會架到aws上面


上一篇
Day 26 Notion API & Google Calendar API Integration - Google Calendar List Refactor
下一篇
Day 28 Notion API & Google Calendar API Integration - Sync Google Calendar to Notion vol.2
系列文
行事曆不再NG:Notion API&Google Calendar跨平台整合發想30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言