mirror of
https://github.com/dstotijn/go-notion.git
synced 2025-06-06 23:36:14 +02:00
265 lines
8.6 KiB
Go
265 lines
8.6 KiB
Go
package notion
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"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"`
|
|
CreatedBy *BaseUser `json:"created_by,omitempty"`
|
|
LastEditedTime time.Time `json:"last_edited_time"`
|
|
LastEditedBy *BaseUser `json:"last_edited_by,omitempty"`
|
|
Parent Parent `json:"parent"`
|
|
Archived bool `json:"archived"`
|
|
URL string `json:"url"`
|
|
Icon *Icon `json:"icon,omitempty"`
|
|
Cover *Cover `json:"cover,omitempty"`
|
|
Properties PageProperties `json:"properties"`
|
|
}
|
|
|
|
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"`
|
|
Name string `json:"name,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"`
|
|
Status *SelectOptions `json:"status,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"`
|
|
}
|
|
|
|
// PageProperties represents a map of page property names to ID objects.
|
|
// This type is used whenever pages are returned, where only the `id` field
|
|
// of a page property is included.
|
|
type PageProperties map[string]PagePropertyID
|
|
|
|
type PagePropertyID struct {
|
|
ID string `json:"id"`
|
|
}
|
|
|
|
// 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
|
|
|
|
Icon *Icon
|
|
Cover *Cover
|
|
}
|
|
|
|
// UpdatePageParams is used for updating a page. At least one field should have
|
|
// a non-empty value.
|
|
type UpdatePageParams struct {
|
|
DatabasePageProperties DatabasePageProperties `json:"properties,omitempty"`
|
|
Archived *bool `json:"archived,omitempty"`
|
|
Icon *Icon `json:"icon,omitempty"`
|
|
Cover *Cover `json:"cover,omitempty"`
|
|
}
|
|
|
|
// PagePropItem is used for a *single* property object value, e.g. for a `rich_text`
|
|
// property, a single value of an array of rich text elements.
|
|
// This type is used when fetching single properties.
|
|
type PagePropItem struct {
|
|
Type DatabasePropertyType `json:"type"`
|
|
|
|
Title RichText `json:"title"`
|
|
RichText RichText `json:"rich_text"`
|
|
Number float64 `json:"number"`
|
|
Select SelectOptions `json:"select"`
|
|
MultiSelect SelectOptions `json:"multi_select"`
|
|
Date Date `json:"date"`
|
|
Formula FormulaResult `json:"formula"`
|
|
Relation Relation `json:"relation"`
|
|
Rollup RollupResult `json:"rollup"`
|
|
People User `json:"people"`
|
|
Files File `json:"files"`
|
|
Checkbox bool `json:"checkbox"`
|
|
URL string `json:"url"`
|
|
Email string `json:"email"`
|
|
PhoneNumber string `json:"phone_number"`
|
|
CreatedTime time.Time `json:"created_time"`
|
|
CreatedBy User `json:"created_by"`
|
|
LastEditedTime time.Time `json:"last_edited_time"`
|
|
LastEditedBy User `json:"last_edited_by"`
|
|
}
|
|
|
|
// PagePropResponse contains a single database page property item or a list
|
|
// of items. For rollup props with an aggregation, both a `results` array and a
|
|
// `rollup` field (inside `page_property`) is included.
|
|
// See: https://developers.notion.com/reference/retrieve-a-page-property#rollup-properties
|
|
type PagePropResponse struct {
|
|
PagePropItem
|
|
|
|
Results []PagePropItem `json:"results"`
|
|
HasMore bool `json:"has_more"`
|
|
NextCursor string `json:"next_cursor"`
|
|
PropertyItem PagePropListItem `json:"property_item"`
|
|
}
|
|
|
|
// PagePropListItem describes the property returned in a paginated list
|
|
// response (e.g. `type` is `title`, `rich_text`, `relation` or `people`).
|
|
// See: https://developers.notion.com/reference/property-item-object#paginated-property-values
|
|
type PagePropListItem struct {
|
|
ID string `json:"id"`
|
|
Type DatabasePropertyType `json:"type"`
|
|
NextURL string `json:"next_url"`
|
|
Rollup RollupResult `json:"rollup"`
|
|
}
|
|
|
|
// 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")
|
|
}
|
|
if p.Icon != nil {
|
|
if err := p.Icon.Validate(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if p.Cover != nil {
|
|
if err := p.Cover.Validate(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (p CreatePageParams) MarshalJSON() ([]byte, error) {
|
|
type CreatePageParamsDTO struct {
|
|
Parent Parent `json:"parent"`
|
|
Properties interface{} `json:"properties"`
|
|
Children []Block `json:"children,omitempty"`
|
|
Icon *Icon `json:"icon,omitempty"`
|
|
Cover *Cover `json:"cover,omitempty"`
|
|
}
|
|
|
|
var parent Parent
|
|
|
|
if p.DatabasePageProperties != nil {
|
|
parent.DatabaseID = p.ParentID
|
|
} else if p.Title != nil {
|
|
parent.PageID = p.ParentID
|
|
}
|
|
|
|
dto := CreatePageParamsDTO{
|
|
Parent: parent,
|
|
Children: p.Children,
|
|
Icon: p.Icon,
|
|
Cover: p.Cover,
|
|
}
|
|
|
|
if p.DatabasePageProperties != nil {
|
|
dto.Properties = p.DatabasePageProperties
|
|
} else if p.Title != nil {
|
|
dto.Properties = PageTitle{
|
|
Title: p.Title,
|
|
}
|
|
}
|
|
|
|
return json.Marshal(dto)
|
|
}
|
|
|
|
func (p UpdatePageParams) Validate() error {
|
|
// At least one of the params must be set.
|
|
if p.DatabasePageProperties == nil && p.Archived == nil && p.Icon == nil && p.Cover == nil {
|
|
return errors.New("at least one of database page properties, archived, icon or cover is required")
|
|
}
|
|
if p.Icon != nil {
|
|
if err := p.Icon.Validate(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|