From e32f7422cdced88e7cb877d73375670a841a8ac0 Mon Sep 17 00:00:00 2001 From: David Stotijn Date: Sat, 15 May 2021 18:06:11 +0200 Subject: [PATCH] Add "update page properties" endpoint support --- client.go | 37 +++++++++++++++++++++++++++++++++++++ database.go | 34 +++++++++++++++++----------------- page.go | 45 +++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 95 insertions(+), 21 deletions(-) diff --git a/client.go b/client.go index bb722b5..157d3a8 100644 --- a/client.go +++ b/client.go @@ -186,3 +186,40 @@ func (c *Client) CreatePage(ctx context.Context, params CreatePageParams) (page return page, nil } + +// UpdatePageProps updates page property values for a page. +// See: https://developers.notion.com/reference/patch-page +func (c *Client) UpdatePageProps(ctx context.Context, pageID string, params UpdatePageParams) (page Page, err error) { + if err := params.Validate(); err != nil { + return Page{}, fmt.Errorf("notion: invalid page params: %w", err) + } + + body := &bytes.Buffer{} + + err = json.NewEncoder(body).Encode(params) + if err != nil { + return Page{}, fmt.Errorf("notion: failed to encode body params to JSON: %w", err) + } + + req, err := c.newRequest(ctx, http.MethodPatch, "/pages/"+pageID, body) + if err != nil { + return Page{}, fmt.Errorf("notion: invalid request: %w", err) + } + + res, err := c.httpClient.Do(req) + if err != nil { + return Page{}, fmt.Errorf("notion: failed to make HTTP request: %w", err) + } + defer res.Body.Close() + + if res.StatusCode != http.StatusOK { + return Page{}, fmt.Errorf("notion: failed to update page properties: %w", parseErrorResponse(res)) + } + + err = json.NewDecoder(res.Body).Decode(&page) + if err != nil { + return Page{}, fmt.Errorf("notion: failed to parse HTTP response: %w", err) + } + + return page, nil +} diff --git a/database.go b/database.go index ce01264..683ec86 100644 --- a/database.go +++ b/database.go @@ -29,35 +29,35 @@ type ( Expression string `json:"expression"` } RelationMetadata struct { - DatabaseID string `json:"database_id"` - SyncedPropName *string `json:"synced_property_name"` - SyncedPropID *string `json:"synced_property_id"` + DatabaseID string `json:"database_id,omitempty"` + SyncedPropName *string `json:"synced_property_name,omitempty"` + SyncedPropID *string `json:"synced_property_id,omitempty"` } RollupMetadata struct { - RelationPropName string `json:"relation_property_name"` - RelationPropID string `json:"relation_property_id"` - RollupPropName string `json:"rollup_property_name"` - RollupPropID string `json:"rollup_property_id"` - Function string `json:"function"` + RelationPropName string `json:"relation_property_name,omitempty"` + RelationPropID string `json:"relation_property_id,omitempty"` + RollupPropName string `json:"rollup_property_name,omitempty"` + RollupPropID string `json:"rollup_property_id,omitempty"` + Function string `json:"function,omitempty"` } ) type SelectOptions struct { - ID string `json:"id"` - Name string `json:"name"` - Color string `json:"color"` + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Color Color `json:"color,omitempty"` } type DatabaseProperty struct { ID string `json:"id"` Type DatabasePropertyType `json:"type"` - Number *NumberMetadata `json:"number"` - Select *SelectMetadata `json:"select"` - MultiSelect *SelectMetadata `json:"multi_select"` - Formula *FormulaMetadata `json:"formula"` - Relation *RelationMetadata `json:"relation"` - Rollup *RollupMetadata `json:"rollup"` + Number *NumberMetadata `json:"number,omitempty"` + Select *SelectMetadata `json:"select,omitempty"` + MultiSelect *SelectMetadata `json:"multi_select,omitempty"` + Formula *FormulaMetadata `json:"formula,omitempty"` + Relation *RelationMetadata `json:"relation,omitempty"` + Rollup *RollupMetadata `json:"rollup,omitempty"` } // DatabaseQuery is used for quering a database. diff --git a/page.go b/page.go index ffa05af..7468857 100644 --- a/page.go +++ b/page.go @@ -42,10 +42,16 @@ type PageTitle struct { type DatabasePageProperties map[string]DatabasePageProperty type DatabasePageProperty struct { - DatabaseProperty - RichText []RichText `json:"rich_text"` - Select *SelectOptions `json:"select"` - MultiSelect []SelectOptions `json:"multi_select"` + ID string `json:"id,omitempty"` + Type DatabasePropertyType `json:"type"` + + RichText []RichText `json:"rich_text,omitempty"` + Number *NumberMetadata `json:"number,omitempty"` + Select *SelectOptions `json:"select,omitempty"` + MultiSelect []SelectOptions `json:"multi_select,omitempty"` + Formula *FormulaMetadata `json:"formula,omitempty"` + Relation *RelationMetadata `json:"relation,omitempty"` + Rollup *RollupMetadata `json:"rollup,omitempty"` } // CreatePageParams are the params used for creating a page. @@ -61,6 +67,12 @@ type CreatePageParams struct { Children []Block } +type UpdatePageParams struct { + // Either DatabasePageProperties or Title must be not nil. + DatabasePageProperties *DatabasePageProperties + Title []RichText +} + type ParentType string const ( @@ -166,3 +178,28 @@ func (p *Page) UnmarshalJSON(b []byte) error { 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) +}