mirror of
https://github.com/dstotijn/go-notion.git
synced 2025-06-06 23:36:14 +02:00
263 lines
6.9 KiB
Go
263 lines
6.9 KiB
Go
package notion
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// Page is a resource on the Notion platform. Its parent is either a workspace,
|
|
// another page, or a database.
|
|
// See: https://developers.notion.com/reference/page
|
|
type Page struct {
|
|
ID string `json:"id"`
|
|
CreatedTime time.Time `json:"created_time"`
|
|
LastEditedTime time.Time `json:"last_edited_time"`
|
|
Parent PageParent `json:"parent"`
|
|
Archived bool `json:"archived"`
|
|
|
|
// Properties differ between parent type.
|
|
// See the `UnmarshalJSON` method.
|
|
Properties interface{} `json:"properties"`
|
|
}
|
|
|
|
type PageParent struct {
|
|
Type ParentType `json:"type,omitempty"`
|
|
|
|
PageID *string `json:"page_id,omitempty"`
|
|
DatabaseID *string `json:"database_id,omitempty"`
|
|
}
|
|
|
|
// PageProperties are properties of a page whose parent is a page or a workspace.
|
|
type PageProperties struct {
|
|
Title PageTitle `json:"title"`
|
|
}
|
|
|
|
type PageTitle struct {
|
|
Title []RichText `json:"title"`
|
|
}
|
|
|
|
// DatabasePageProperties are properties of a page whose parent is a database.
|
|
type DatabasePageProperties map[string]DatabasePageProperty
|
|
|
|
type DatabasePageProperty struct {
|
|
ID string `json:"id,omitempty"`
|
|
Type DatabasePropertyType `json:"type,omitempty"`
|
|
|
|
Title []RichText `json:"title,omitempty"`
|
|
RichText []RichText `json:"rich_text,omitempty"`
|
|
Number *float64 `json:"number,omitempty"`
|
|
Select *SelectOptions `json:"select,omitempty"`
|
|
MultiSelect []SelectOptions `json:"multi_select,omitempty"`
|
|
Date *Date `json:"date,omitempty"`
|
|
Formula *FormulaResult `json:"formula,omitempty"`
|
|
Relation []Relation `json:"relation,omitempty"`
|
|
Rollup *RollupResult `json:"rollup,omitempty"`
|
|
People []User `json:"people,omitempty"`
|
|
Files []File `json:"files,omitempty"`
|
|
Checkbox *bool `json:"checkbox,omitempty"`
|
|
URL *string `json:"url,omitempty"`
|
|
Email *string `json:"email,omitempty"`
|
|
PhoneNumber *string `json:"phone_number,omitempty"`
|
|
CreatedTime *time.Time `json:"created_time,omitempty"`
|
|
CreatedBy *User `json:"created_by,omitempty"`
|
|
LastEditedTime *time.Time `json:"last_edited_time,omitempty"`
|
|
LastEditedBy *User `json:"last_edited_by,omitempty"`
|
|
}
|
|
|
|
// CreatePageParams are the params used for creating a page.
|
|
type CreatePageParams struct {
|
|
ParentType ParentType
|
|
ParentID string
|
|
|
|
// Either DatabasePageProperties or Title must be not nil.
|
|
DatabasePageProperties *DatabasePageProperties
|
|
Title []RichText
|
|
|
|
// Optionally, children blocks are added to the page.
|
|
Children []Block
|
|
}
|
|
|
|
type UpdatePageParams struct {
|
|
// Either DatabasePageProperties or Title must be not nil.
|
|
DatabasePageProperties *DatabasePageProperties
|
|
Title []RichText
|
|
}
|
|
|
|
type ParentType string
|
|
|
|
const (
|
|
ParentTypeDatabase ParentType = "database_id"
|
|
ParentTypePage ParentType = "page_id"
|
|
)
|
|
|
|
// Value returns the underlying database page property value, based on its `type` field.
|
|
// When type is unknown/unmapped or doesn't have a value, `nil` is returned.
|
|
func (prop DatabasePageProperty) Value() interface{} {
|
|
switch prop.Type {
|
|
case DBPropTypeTitle:
|
|
return prop.Title
|
|
case DBPropTypeRichText:
|
|
return prop.RichText
|
|
case DBPropTypeNumber:
|
|
return prop.Number
|
|
case DBPropTypeSelect:
|
|
return prop.Select
|
|
case DBPropTypeMultiSelect:
|
|
return prop.MultiSelect
|
|
case DBPropTypeDate:
|
|
return prop.Date
|
|
case DBPropTypePeople:
|
|
return prop.People
|
|
case DBPropTypeFiles:
|
|
return prop.Files
|
|
case DBPropTypeCheckbox:
|
|
return prop.Checkbox
|
|
case DBPropTypeURL:
|
|
return prop.URL
|
|
case DBPropTypeEmail:
|
|
return prop.Email
|
|
case DBPropTypePhoneNumber:
|
|
return prop.PhoneNumber
|
|
case DBPropTypeFormula:
|
|
return prop.Formula
|
|
case DBPropTypeRelation:
|
|
return prop.Relation
|
|
case DBPropTypeRollup:
|
|
return prop.Rollup
|
|
case DBPropTypeCreatedTime:
|
|
return prop.CreatedTime
|
|
case DBPropTypeCreatedBy:
|
|
return prop.CreatedBy
|
|
case DBPropTypeLastEditedTime:
|
|
return prop.LastEditedTime
|
|
case DBPropTypeLastEditedBy:
|
|
return prop.LastEditedBy
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func (p CreatePageParams) Validate() error {
|
|
if p.ParentType == "" {
|
|
return errors.New("parent type is required")
|
|
}
|
|
if p.ParentID == "" {
|
|
return errors.New("parent ID is required")
|
|
}
|
|
if p.ParentType == ParentTypeDatabase && p.DatabasePageProperties == nil {
|
|
return errors.New("database page properties is required when parent type is database")
|
|
}
|
|
if p.ParentType == ParentTypePage && p.Title == nil {
|
|
return errors.New("title is required when parent type is page")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (p CreatePageParams) MarshalJSON() ([]byte, error) {
|
|
type CreatePageParamsDTO struct {
|
|
Parent PageParent `json:"parent"`
|
|
Properties interface{} `json:"properties"`
|
|
Children []Block `json:"children,omitempty"`
|
|
}
|
|
|
|
var parent PageParent
|
|
|
|
if p.DatabasePageProperties != nil {
|
|
parent.DatabaseID = StringPtr(p.ParentID)
|
|
} else if p.Title != nil {
|
|
parent.PageID = StringPtr(p.ParentID)
|
|
}
|
|
|
|
dto := CreatePageParamsDTO{
|
|
Parent: parent,
|
|
Children: p.Children,
|
|
}
|
|
|
|
if p.DatabasePageProperties != nil {
|
|
dto.Properties = p.DatabasePageProperties
|
|
} else if p.Title != nil {
|
|
dto.Properties = PageTitle{
|
|
Title: p.Title,
|
|
}
|
|
}
|
|
|
|
return json.Marshal(dto)
|
|
}
|
|
|
|
// UnmarshalJSON implements json.Unmarshaler.
|
|
//
|
|
// Pages get a different Properties type based on the parent of the page.
|
|
// If parent type is `workspace` or `page_id`, PageProperties is used. Else if
|
|
// parent type is `database_id`, DatabasePageProperties is used.
|
|
func (p *Page) UnmarshalJSON(b []byte) error {
|
|
type (
|
|
PageAlias Page
|
|
PageDTO struct {
|
|
PageAlias
|
|
Properties json.RawMessage `json:"properties"`
|
|
}
|
|
)
|
|
|
|
var dto PageDTO
|
|
|
|
err := json.Unmarshal(b, &dto)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
page := dto.PageAlias
|
|
|
|
switch dto.Parent.Type {
|
|
case "workspace":
|
|
fallthrough
|
|
case "page_id":
|
|
var props PageProperties
|
|
err := json.Unmarshal(dto.Properties, &props)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
page.Properties = props
|
|
case "database_id":
|
|
var props DatabasePageProperties
|
|
err := json.Unmarshal(dto.Properties, &props)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
page.Properties = props
|
|
default:
|
|
return fmt.Errorf("unknown page parent type %q", dto.Parent.Type)
|
|
}
|
|
|
|
*p = Page(page)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (p UpdatePageParams) Validate() error {
|
|
if p.DatabasePageProperties == nil && p.Title == nil {
|
|
return errors.New("either database page properties or title is required")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (p UpdatePageParams) MarshalJSON() ([]byte, error) {
|
|
type UpdatePageParamsDTO struct {
|
|
Properties interface{} `json:"properties"`
|
|
}
|
|
|
|
var dto UpdatePageParamsDTO
|
|
|
|
if p.DatabasePageProperties != nil {
|
|
dto.Properties = p.DatabasePageProperties
|
|
} else if p.Title != nil {
|
|
dto.Properties = PageTitle{
|
|
Title: p.Title,
|
|
}
|
|
}
|
|
|
|
return json.Marshal(dto)
|
|
}
|