Go client for the Notion API.

go-notion

GitHub tag (latest SemVer) Go Reference GitHub Go Report Card

go-notion is a client for the Notion API, written in Go.

Features

The client supports all (non-deprecated) endpoints available in the Notion API, as of May 15, 2021:

Installation

$ go get github.com/dstotijn/go-notion

Getting started

To obtain an API key, follow Notion’s getting started guide.

Code example

First, construct a new Client:

import "github.com/dstotijn/go-notion"

(...)

client := notion.NewClient("secret-api-key")

Then, use the methods defined on Client to make requests to the API. For example:

page, err := client.FindPageByID("18d35eb5-91f1-4dcb-85b0-c340fd965015")
if err != nil {
    // Handle error...
}

👉 Check out the docs on pkg.go.dev for further reference and examples.

Status

The Notion API is currently in public beta.

⚠️ Although the API itself is versioned, this client will make breaking changes in its code until v1.0 of the module is released.

To do

  • Write tests
  • Provide examples

License

MIT License


© 2021 David Stotijn — Twitter, Email

Owner
David Stotijn
👷 Software Engineer
David Stotijn
Comments
  • fix-json-tag

    fix-json-tag

    Hi!!!

    fix #5

    Hit the api by curl command as follows

    curl -X POST https://api.notion.com/v1/pages \
             -H "Authorization: Bearer XXXX" \
             -H "Content-Type: application/json" \
             -H "Notion-Version: 2021-05-13" \
             --data '{
               "parent": { 
                   "type":"database_id",
                   "database_id":"f38a21302e234460b6e7b0682bad2428"},
                   "properties":{
                       "Name":{
                           "type":"",
                           "title":[{
                               "type":"","text":{"content":"hello world"}}
                          ]
                        }
                    } 
                }
            }'
            
    

    This happen

    {"object":"error","status":401,"code":"unauthorized","message":"API token is invalid."}
    

    so, I fix it

  • Update database entry Title

    Update database entry Title

    Hello, I'm trying to update a database entry title field (Name in my case) but I don't manage to do so. If I use Name on the properties it told me to use the Title, and using the Title does nothing (no errors). I can update other properties without issue.

    sample code:

    name := "New name"
    
    page, err := client.UpdatePage(ctx, "<pageid>", notion.UpdatePageParams{
    	Title: []notion.RichText{
    		{
    			PlainText: name,
    			Text: &notion.Text{
    				Content: product.Name,
    			},
    		},
    	},
    )
    

    I've tried several combinations, but nothing seems to being able to update the page title. I tried using "Title" as the field name (in case it was some JSON hardcoding) but that didn't work either.

    Thanks for your work on this!

  • feature: add ArchivePage

    feature: add ArchivePage

    Hi, first of all, thanks for building this interface for the Notion API! I started using it and missed the "archive pages" feature, so i implemented it.

    Cheers

  • "Failed to parse HTTP response" on database query

    I'm trying to make a simple query for a selection from the database.

    client := notion.NewClient("secret_0aXXXXXXXXXXX")
    
    res, err := client.QueryDatabase(context.TODO(), "aaaaa-bbbbb-4fc8-b220-xxxxx", &notion.DatabaseQuery{
    	Filter: notion.DatabaseQueryFilter{
    		Property: "Паркран",
    		Text: &notion.TextDatabaseQueryFilter{
    			Contains: "parkrun",
    		},
    	},
    })
    

    Unfortunately I get an error:

    notion: failed to parse HTTP response: json: cannot unmarshal number into Go struct field DatabaseQueryResponse.results of type notion.NumberMetadata

    After tweaking your code a little, I printed out the document that the library receives from the server. There is nothing private in this database, so I bring the document in full:

    response.json
    {
      "object": "list",
      "results": [
        {
          "object": "page",
          "id": "d2edfb6c-2aa2-4f7a-91f2-xxxxxxx",
          "created_time": "2021-05-24T10:45:05.833Z",
          "last_edited_time": "2021-05-24T10:45:05.833Z",
          "parent": { "type": "database_id", "database_id": "738ab074-8597-4fc8-b220-xxxxxxxxx" },
          "archived": false,
          "properties": {
            "Место среди М/Ж": { "id": "InK~", "type": "number", "number": 25 },
            "Время": {
              "id": "U^E~",
              "type": "rich_text",
              "rich_text": [
                {
                  "type": "text",
                  "text": { "content": "30:20", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "30:20",
                  "href": null
                }
              ]
            },
            "Дата": { "id": "b@g=", "type": "date", "date": { "start": "2021-04-24", "end": null } },
            "Рейтинг": {
              "id": "sJqx",
              "type": "rich_text",
              "rich_text": [
                {
                  "type": "text",
                  "text": { "content": "44.01%", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "44.01%",
                  "href": null
                }
              ]
            },
            "Место в общем зачёте": { "id": "~dWC", "type": "number", "number": 32 },
            "Паркран": {
              "id": "title",
              "type": "title",
              "title": [
                {
                  "type": "text",
                  "text": { "content": "parkrun Natashinsky", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "parkrun Natashinsky",
                  "href": null
                }
              ]
            }
          }
        },
        {
          "object": "page",
          "id": "a8d67af1-0707-4890-9c94-8efa1097b546",
          "created_time": "2021-05-24T10:45:04.432Z",
          "last_edited_time": "2021-05-24T10:45:04.432Z",
          "parent": { "type": "database_id", "database_id": "738ab074-8597-4fc8-b220-813c3dc75528" },
          "archived": false,
          "properties": {
            "Место среди М/Ж": { "id": "InK~", "type": "number", "number": 54 },
            "Время": {
              "id": "U^E~",
              "type": "rich_text",
              "rich_text": [
                {
                  "type": "text",
                  "text": { "content": "30:49", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "30:49",
                  "href": null
                }
              ]
            },
            "Дата": { "id": "b@g=", "type": "date", "date": { "start": "2021-05-22", "end": null } },
            "Рейтинг": {
              "id": "sJqx",
              "type": "rich_text",
              "rich_text": [
                {
                  "type": "text",
                  "text": { "content": "43.32%", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "43.32%",
                  "href": null
                }
              ]
            },
            "Место в общем зачёте": { "id": "~dWC", "type": "number", "number": 74 },
            "Паркран": {
              "id": "title",
              "type": "title",
              "title": [
                {
                  "type": "text",
                  "text": { "content": "parkrun Natashinsky", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "parkrun Natashinsky",
                  "href": null
                }
              ]
            }
          }
        },
        {
          "object": "page",
          "id": "a79f7eba-97df-49f9-8fe5-fd5b60e1a986",
          "created_time": "2021-05-24T10:45:04.420Z",
          "last_edited_time": "2021-05-24T10:45:04.420Z",
          "parent": { "type": "database_id", "database_id": "738ab074-8597-4fc8-b220-813c3dc75528" },
          "archived": false,
          "properties": {
            "Место среди М/Ж": { "id": "InK~", "type": "number", "number": 42 },
            "Время": {
              "id": "U^E~",
              "type": "rich_text",
              "rich_text": [
                {
                  "type": "text",
                  "text": { "content": "30:27", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "30:27",
                  "href": null
                }
              ]
            },
            "Дата": { "id": "b@g=", "type": "date", "date": { "start": "2021-05-08", "end": null } },
            "Рейтинг": {
              "id": "sJqx",
              "type": "rich_text",
              "rich_text": [
                {
                  "type": "text",
                  "text": { "content": "43.84%", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "43.84%",
                  "href": null
                }
              ]
            },
            "Место в общем зачёте": { "id": "~dWC", "type": "number", "number": 60 },
            "Паркран": {
              "id": "title",
              "type": "title",
              "title": [
                {
                  "type": "text",
                  "text": { "content": "parkrun Natashinsky", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "parkrun Natashinsky",
                  "href": null
                }
              ]
            }
          }
        },
        {
          "object": "page",
          "id": "e32c597e-5959-4d14-8d73-a45762bc0fa0",
          "created_time": "2021-05-24T10:45:04.403Z",
          "last_edited_time": "2021-05-24T10:45:04.403Z",
          "parent": { "type": "database_id", "database_id": "738ab074-8597-4fc8-b220-813c3dc75528" },
          "archived": false,
          "properties": {
            "Место среди М/Ж": { "id": "InK~", "type": "number", "number": 46 },
            "Время": {
              "id": "U^E~",
              "type": "rich_text",
              "rich_text": [
                {
                  "type": "text",
                  "text": { "content": "30:03", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "30:03",
                  "href": null
                }
              ]
            },
            "Дата": { "id": "b@g=", "type": "date", "date": { "start": "2021-05-01", "end": null } },
            "Рейтинг": {
              "id": "sJqx",
              "type": "rich_text",
              "rich_text": [
                {
                  "type": "text",
                  "text": { "content": "44.43%", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "44.43%",
                  "href": null
                }
              ]
            },
            "Место в общем зачёте": { "id": "~dWC", "type": "number", "number": 58 },
            "Паркран": {
              "id": "title",
              "type": "title",
              "title": [
                {
                  "type": "text",
                  "text": { "content": "parkrun Natashinsky", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "parkrun Natashinsky",
                  "href": null
                }
              ]
            }
          }
        },
        {
          "object": "page",
          "id": "ac686d42-05bf-4c4d-b1fc-ae7ce0992d79",
          "created_time": "2021-05-24T10:45:04.388Z",
          "last_edited_time": "2021-05-24T10:45:04.388Z",
          "parent": { "type": "database_id", "database_id": "738ab074-8597-4fc8-b220-813c3dc75528" },
          "archived": false,
          "properties": {
            "Место среди М/Ж": { "id": "InK~", "type": "number", "number": 54 },
            "Время": {
              "id": "U^E~",
              "type": "rich_text",
              "rich_text": [
                {
                  "type": "text",
                  "text": { "content": "31:43", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "31:43",
                  "href": null
                }
              ]
            },
            "Дата": { "id": "b@g=", "type": "date", "date": { "start": "2021-04-17", "end": null } },
            "Рейтинг": {
              "id": "sJqx",
              "type": "rich_text",
              "rich_text": [
                {
                  "type": "text",
                  "text": { "content": "41.83%", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "41.83%",
                  "href": null
                }
              ]
            },
            "Место в общем зачёте": { "id": "~dWC", "type": "number", "number": 73 },
            "Паркран": {
              "id": "title",
              "type": "title",
              "title": [
                {
                  "type": "text",
                  "text": { "content": "parkrun Natashinsky", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "parkrun Natashinsky",
                  "href": null
                }
              ]
            }
          }
        },
        {
          "object": "page",
          "id": "df95b4d1-2a51-4ace-8fcb-a886aa2afb74",
          "created_time": "2021-05-24T10:45:04.373Z",
          "last_edited_time": "2021-05-24T10:45:04.373Z",
          "parent": { "type": "database_id", "database_id": "738ab074-8597-4fc8-b220-813c3dc75528" },
          "archived": false,
          "properties": {
            "Место среди М/Ж": { "id": "InK~", "type": "number", "number": 70 },
            "Время": {
              "id": "U^E~",
              "type": "rich_text",
              "rich_text": [
                {
                  "type": "text",
                  "text": { "content": "32:15", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "32:15",
                  "href": null
                }
              ]
            },
            "Дата": { "id": "b@g=", "type": "date", "date": { "start": "2021-04-03", "end": null } },
            "Рейтинг": {
              "id": "sJqx",
              "type": "rich_text",
              "rich_text": [
                {
                  "type": "text",
                  "text": { "content": "41.14%", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "41.14%",
                  "href": null
                }
              ]
            },
            "Место в общем зачёте": { "id": "~dWC", "type": "number", "number": 99 },
            "Паркран": {
              "id": "title",
              "type": "title",
              "title": [
                {
                  "type": "text",
                  "text": { "content": "parkrun Natashinsky", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "parkrun Natashinsky",
                  "href": null
                }
              ]
            }
          }
        },
        {
          "object": "page",
          "id": "b3cb19fc-1e72-4ac5-a74f-197cbc150fa7",
          "created_time": "2021-05-24T10:45:04.362Z",
          "last_edited_time": "2021-05-24T10:45:04.362Z",
          "parent": { "type": "database_id", "database_id": "738ab074-8597-4fc8-b220-813c3dc75528" },
          "archived": false,
          "properties": {
            "Место среди М/Ж": { "id": "InK~", "type": "number", "number": 59 },
            "Время": {
              "id": "U^E~",
              "type": "rich_text",
              "rich_text": [
                {
                  "type": "text",
                  "text": { "content": "30:29", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "30:29",
                  "href": null
                }
              ]
            },
            "Дата": { "id": "b@g=", "type": "date", "date": { "start": "2021-04-10", "end": null } },
            "Рейтинг": {
              "id": "sJqx",
              "type": "rich_text",
              "rich_text": [
                {
                  "type": "text",
                  "text": { "content": "43.52%", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "43.52%",
                  "href": null
                }
              ]
            },
            "Место в общем зачёте": { "id": "~dWC", "type": "number", "number": 81 },
            "Паркран": {
              "id": "title",
              "type": "title",
              "title": [
                {
                  "type": "text",
                  "text": { "content": "parkrun Natashinsky", "link": null },
                  "annotations": {
                    "bold": false,
                    "italic": false,
                    "strikethrough": false,
                    "underline": false,
                    "code": false,
                    "color": "default"
                  },
                  "plain_text": "parkrun Natashinsky",
                  "href": null
                }
              ]
            }
          }
        }
      ],
      "next_cursor": null,
      "has_more": false
    }
    
  • `CreatePage` function always return 400 error

    `CreatePage` function always return 400 error

    First of all ,thanks for creating the notino-sdk for go.

    when the following code execute always return 400 error.

    go version go1.15.6 darwin/amd64

    func getClient(apiKey string) *notion.Client {
    	return notion.NewClient(apiKey)
    }
    
    func createPage(c echo.Context) error {
    	notionApi := os.Getenv("NOTION_API")
    	client    := getClient(notionApi)
    	ctx       := context.Background()
    	parentId  := "{page_id}"
    
    	titleText := &notion.Text{
    		Content: "this is a title of the created page",
    	}
    	title := []notion.RichText{
    		{
    			Type: notion.RichTextTypeText,
    			Text: titleText,
    		},
    	}
    	params := notion.CreatePageParams{
    		ParentType: notion.ParentTypePage,
    		ParentID:   parentId,
    		Title:      title,
    	}
    
    	page, err := client.CreatePage(ctx, params)
    	if err != nil {
    		fmt.Printf("%s",err)
    	}
            fmt.Println(page)
    	return nil
    }
    

    The following error code will be returned when createPage function is executed.

    notion: failed to create page: body failed validation. Fix one: body.parent.type should be not present, instead was `"database_id"`. body.parent.page_id should be defined, instead was `undefined`. (code: validation_error, status: 400)
    

    I think the structure is correct, so I'm thinking there's probably something wrong with the code.

    Thank you .

  • Encountering Error Code 500 on Database Query

    Encountering Error Code 500 on Database Query

    When the following line executes, it returns back stating an error with code 500 occurs.

    response, err := client.QueryDatabase(context.Background(), id, query)

    I'm not particularly sure where the issue is arising, so any help resolving is appreciated!

  • Impossible to create an empty DatabaseQueryFilter to fetch all rows from a database

    Impossible to create an empty DatabaseQueryFilter to fetch all rows from a database

    Description

    Impossible to create a DatabaseQuery with an empty DatabseQueryFilter. Fields that do not have empty values (such as embedded structs) cannot be omitted. Source

    To Reproduce

    Populate your environment variables with valid values for NOTION_SECRET_API_KEY and NOTION_DATABASE_ID and run the following code.

    package main
    
    import (
    	"context"
    	"fmt"
    	"os"
    
    	"github.com/dstotijn/go-notion"
    )
    
    func main() {
    	client := notion.NewClient(os.Getenv("NOTION_SECRET_API_KEY"))
    	rows, err := client.QueryDatabase(context.Background(), os.Getenv("NOTION_DATABASE_ID"), &notion.DatabaseQuery{
    		PageSize: 10,
    	})
    	fmt.Println("======= ERROR ======")
    	fmt.Println(err)
    	fmt.Println("======= ROWS ======")
    	fmt.Println(rows)
    }
    
    

    Given the following table Screen Shot 2021-05-24 at 10 10 24 PM I go the following error Screen Shot 2021-05-24 at 10 11 24 PM

  • Returns APIError error instead of std err object

    Returns APIError error instead of std err object

    Allows the following:

    err := notion.Search(...)
    
    notionErr, ok := err.(*APIError)
    if ok && notionErr.Code == "rate_limited" {
    	// retry
    }
    

    Please don't forget to create a new release after you merge ;)

  • Color assigning for DB SelectOptions

    Color assigning for DB SelectOptions

    I thoroughly enjoy using your client, it makes a lot of sense when you get the hang of it. Unfortunately, I have been struggling with something that doesn't seem to stem from my code (feel free to contradict using the code provided below). When creating a new Page in a Database, I add a few Select properties with SelectOptions while filling the Color and Name fields. The API doesn't seem to receive the Colorinformation though and the Options appear a different color every time in the Notion interface. This leads to the inability to add any more Pages due to the inconsistent colors.

    I scoured the Notion API Interface and the docs of this API but I didn't seem to find any note about this.

    In this specific example, City, Locality, Category, Opening Days, and Train Station are always random colors and I cannot seem to be able to set them.

    package main
    
    import (
    	"context"
    	"fmt"
    	"html"
    
    	"github.com/dstotijn/go-notion"
    )
    
    func CreateMuseumPage(mus Museum, db_id string, client notion.Client) (notion.Page, error) {
    	specifics, err := ParseSpecifics(mus)
    	city := ParseCity(mus.AddressLocality)
    	categ := ParseCategory(mus.Themes)
    	if err != nil {
    		return notion.Page{}, err
    	}
    	params := notion.CreatePageParams{
    		ParentType: "database_id",
    		ParentID:   db_id,
    		DatabasePageProperties: &notion.DatabasePageProperties{
    			"Name": notion.DatabasePageProperty{
    				Title: IntoRichTextArray(mus.Name),
    			},
    			"Description": notion.DatabasePageProperty{
    				RichText: IntoRichTextArray(mus.ShortDescription),
    			},
    			"URL": notion.DatabasePageProperty{
    				URL: &mus.DetailURL,
    			},
    			"Locality": notion.DatabasePageProperty{
    				Select: &notion.SelectOptions{
    					Name:  mus.AddressLocality,
    					Color: city.Color(),
    				},
    			},
    			"Category": notion.DatabasePageProperty{
    				Select: &notion.SelectOptions{
    					Name:  categ.String(),
    					Color: notion.ColorOrange,
    				},
    			},
    			"City": notion.DatabasePageProperty{
    				Select: &notion.SelectOptions{
    					Name:  city.String(),
    					Color: city.Color(),
    				},
    			},
    			"Closed": notion.DatabasePageProperty{
    				Checkbox: &mus.TemporaryClosed,
    			},
    			"Openings": notion.DatabasePageProperty{
    				RichText: IntoRichTextArray(specifics.opening),
    			},
    			"Phone": notion.DatabasePageProperty{
    				PhoneNumber: &specifics.phone,
    			},
    			"Email": notion.DatabasePageProperty{
    				Type:  notion.DBPropTypeEmail,
    				Email: &specifics.email,
    			},
    			"Website": notion.DatabasePageProperty{
    				Type: notion.DBPropTypeURL,
    				URL:  &specifics.website,
    			},
    			"Train Station": notion.DatabasePageProperty{
    				Select: &notion.SelectOptions{
    					Name:  specifics.station,
    					Color: city.Color(),
    				},
    			},
    			"Opening Hours": notion.DatabasePageProperty{
    				RichText: IntoRichTextArray(specifics.openingHours),
    			},
    			"Opening Days": notion.DatabasePageProperty{
    				MultiSelect: CreateDayOptions(specifics.openingDays),
    			},
    		},
    		Icon: &notion.Icon{
    			Type:  notion.IconTypeEmoji,
    			Emoji: categ.Emoji(),
    		},
    		Cover: &notion.Cover{
    			Type: notion.FileTypeExternal,
    			External: &notion.FileExternal{
    				URL: mus.CoverPhoto.ResizableURL + "?max-h=600&max-w=1500",
    			},
    		},
    	}
    	fmt.Print("[NOTION] Creating page \"" + mus.Name + "\" in the Musea database...")
    	page, err := client.CreatePage(context.Background(), params)
    	if err != nil {
    		return notion.Page{}, err
    	}
    	fmt.Println("Done")
    	return page, nil
    }
    
    func CreateDayOptions(days []Day) []notion.SelectOptions {
    	var select_options []notion.SelectOptions
    	for _, day := range DaysToString(days) {
    		select_options = append(select_options, notion.SelectOptions{
    			Name:  day,
    			Color: notion.ColorPurple,
    		})
    	}
    	return select_options
    }
    
    func DaysToString(vs []Day) []string {
    	vsm := make([]string, len(vs))
    	for i, v := range vs {
    		vsm[i] = v.LongString()
    	}
    	return vsm
    }
    
    func IntoRichText(base string) notion.RichText {
    	t := &notion.Text{
    		Content: html.UnescapeString(base),
    	}
    	rt := notion.RichText{
    		Text: t,
    	}
    	return rt
    }
    
    func IntoRichTextArray(base string) []notion.RichText {
    	return []notion.RichText{IntoRichText(base)}
    }
    
    type City int64
    
    const (
    	Brussels City = iota
    	Gent
    	Mechelen
    	Antwerp
    	NotImpl
    )
    
    func (me City) String() string {
    	return []string{"Brussels", "Gent", "Mechelen", "Antwerp", ""}[me]
    }
    
    func (me City) Color() notion.Color {
    	return []notion.Color{notion.ColorBlue, notion.ColorPurple, notion.ColorBrown, notion.ColorOrange}[me]
    }
    

    The resulting error doesn't really matter but I'll stick it in here in case you can learn more from it than I can :^)

    [NOTION] Creating page "Musée Mode &amp; Dentelle" in the Musea database...Done
    [NOTION] Creating page "Musée de la Banque nationale de Belgique" in the Musea database...notion: failed to create page: Select option color doesn't match existing for 68ad963d-18a2-49b4-a6a9-96fe36552c33. Select option color doesn't match existing for b1f3eb78-f05c-493d-8843-2735ddd4300a. Select option color doesn't match existing for 385e8aaa-a523-4e99-9da9-7d2031ba6ab2. Select option color doesn't match existing for e6154c30-e6ac-4436-beb8-aa3c9acd0184. (code: validation_error, status: 400)
    

    If you have any quick fixes for this, it would be absolutely amazing. Thank you in advance

  • Retrieve File

    Retrieve File

    Notion added the file url and an expiry time to the files object: https://developers.notion.com/reference/file-object

    Are you planning to add this in the future?

    For the beginning, in my opinion, it would be enough to add the two fields to the File struct and maybe add later the functionality of actually downloading the file.

  • Support retrieve a block

    Support retrieve a block

    Hi. Thank you for creating good repository 👍 This is helpful for me. 🙏

    I wanted to use Retrieve a block endpoint, So I implemented it!

    https://developers.notion.com/reference/retrieve-a-block

    Would you please merge it when you have time?

    Thank you in advance. 🙇🙇🙇🙇🙇

  • Excessive entry of People User Type in DatabasePageProperty struct issue

    Excessive entry of People User Type in DatabasePageProperty struct issue

    In the CreatePage function, when data is entered in the People type of the Type database, due to excessive DatabasePageProperty->People User struct item body.properties.People.people[0].type should be not present, instead was "". body.properties.People.people[0].name should be not present, instead was "". body.properties.People.people[0].avatar_url should be not present, instead was "". body.properties.People.people[0].person should be not present or an object, instead was null. body.properties.People.people[0].bot should be not present or an object, instead was null. (code: validation_error, status: 400) error occurs. However, It can be solved by adding omitempty to each json item of User struct.

  • Consider typing interface{} fields?

    Consider typing interface{} fields?

    First of all, thanks for the work you're putting into this!

    There are couple of places in the Go API where the type of a field is only known at runtime (eg. Page.Properties), so the field is typed as interface{} in Go. One approach that's used eg. by the protobuf runtime is to use an interface with a "dummy" method that uniquely identifies the implementors, which helps both IDEs/language servers to do autocompletion and the compiler to ensure that the code is correct.

    A simple example

    type Page struct {
       Properties IsPageProperties
    }
    
    type IsPageProperties interface { isPageProperties() }
    
    type PageProperties struct { /* ... */ }
    
    func (PageProperties) isPageProperties() {}
    
    type DatabasePageProperties struct {  /* ... */  }
    
    func (DatabasePageProperties) isPageProperties() {}
    

    let me know if you think this approach makes sense, and I can try to send a PR.

Godaddy-domains-client-go - Godaddy domains api Client golang - Write automaticly from swagger codegen

Go API client for swagger Overview This API client was generated by the swagger-codegen project. By using the swagger-spec from a remote server, you c

Jan 9, 2022
Tailscale-client-go - A client implementation for the Tailscale HTTP API

tailscale-client-go A client implementation for the Tailscale HTTP API Example p

Sep 8, 2022
An API Client package for Studyplus for School SYNC API

Studyplus for School SYNC API Client This project is currently alpha, possibility having breaking changes. studyplus_for_school_sync_go is a API clien

Aug 2, 2021
Go API Client for Metasploit RPC API

go-msf-rpc Golang based RPC client to communicate with Metasploit. Based on code initially developed by Wyatt Dahlenburg repo. Extended to include oth

Nov 18, 2022
iceportal-api is a Golang client implementation to interact with the REST API of iceportal.de when connected to the WiFi-Network offered in German ICE Trains.
iceportal-api is a Golang client implementation to interact with the REST API of iceportal.de when connected to the WiFi-Network offered in German ICE Trains.

iceportal-api is a Golang client implementation to interact with the REST API of iceportal.de when connected to the WiFi-Network offered in German ICE Trains.

Aug 20, 2022
Prisma Client Go is an auto-generated and fully type-safe database client

Prisma Client Go Typesafe database access for Go Quickstart • Website • Docs • API reference • Blog • Slack • Twitter Prisma Client Go is an auto-gene

Jan 9, 2023
The Dual-Stack Dynamic DNS client, the world's first dynamic DNS client built for IPv6.

dsddns DsDDNS is the Dual-Stack Dynamic DNS client. A dynamic DNS client keeps your DNS records in sync with the IP addresses associated with your hom

Sep 27, 2022
Go Substrate RPC Client (GSRPC)Go Substrate RPC Client (GSRPC)

Go Substrate RPC Client (GSRPC) Substrate RPC client in Go. It provides APIs and types around Polkadot and any Substrate-based chain RPC calls. This c

Nov 11, 2021
Server and client implementation of the grpc go libraries to perform unary, client streaming, server streaming and full duplex RPCs from gRPC go introduction

Description This is an implementation of a gRPC client and server that provides route guidance from gRPC Basics: Go tutorial. It demonstrates how to u

Nov 24, 2021
Comunicación de envios de archivos entres cliente-servidor, client-client.

Client - Server - Client Estes es un proyecto simple de comunicacion de envios de archivos del cliente al servidor y viceversamente, y de cliente a cl

Jul 16, 2022
Go PowerDNS 4.x API Client

PowerDNS 4.x API bindings for Golang This community project provides bindings for the currently latest version of PowerDNS Authoritative Server. Featu

Dec 12, 2022
Golang client for querying SecurityTrails API data
Golang client for querying SecurityTrails API data

haktrails haktrails is a Golang client for querying SecurityTrails API data, sponsored by SecurityTrails. SecurityTrails $50 Bug Bounty Hunter Plan Sa

Jan 4, 2023
Go/Golang client library to interact with the Stein API

go-stein This Go / Golang client helps you interact with the Stein API. Stein is a suite of programs to help you turn any Google Sheet to a database.

Aug 23, 2022
Go client for the Foreign exchange rates and currency conversion API 💰

fixer Go client for Fixer.io (Foreign exchange rates and currency conversion API) You need to register for a free access key if using the default Fixe

Nov 14, 2022
Go client library for accessing the Football Data API

football-data-sdk football-data-sdk is a Go client library for accessing the Football Data API. Successful queries return native Go structs. Services

Oct 13, 2022
Teraswitch Go API Client

GoTSW The official Teraswitch Go client. Install go get -u github.com/teraswitch/gotsw Usage import "github.com/teraswitch/gotsw" Authentication packa

Apr 1, 2022
Client for the OpenWeather API, written in Go

Weather This is a Go project template, intended for students at the Bitfield Institute of Technology—but everyone's welcome to try it if you're intere

Nov 9, 2021
viagh.NewHTTPClient returns a *http.Client that makes API requests via the gh command.

viagh viagh.NewHTTPClient returns a *http.Client that makes API requests via the gh command. Why viagh? When writing a GitHub CLI extension, the exten

Dec 24, 2021
Autify's web API client for Golang

autify-go This is a Go wrapper for working with Autify's Web API. This project tries to connect the Web API Endpoint easily by using this library. Ins

Nov 9, 2021