dstotijn / go-notion

Go client for the Notion API.
MIT License
380 stars 39 forks source link

Color assigning for DB SelectOptions #25

Closed alexliebh closed 2 years ago

alexliebh commented 2 years ago

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 & 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

alexliebh commented 2 years ago

After proxying the Request sent out by the client, it seems that the color is indeed included but the Notion API doesn't seem to care for it. Weird.

{
    "parent": {
        "database_id": "x"
    },
    "properties": {
        "Category": {
            "select": {
                "name": "Cultural",
                "color": "orange"
            }
        },
        "City": {
            "select": {
                "name": "Brussels",
                "color": "blue"
            }
        },
        "Closed": {
            "checkbox": false
        },
        "Description": {
            "rich_text": [
                {
                    "text": {
                        "content": "À travers des expositions thématiques annuelles, le Musée Mode & Dentelle présente des pièces significatives de l’histoire de la mode tout en mettant l’accent sur la création bruxelloise et belge."
                    }
                }
            ]
        },
        "Email": {
            "type": "email",
            "email": "musea@brucity.be"
        },
        "Locality": {
            "select": {
                "name": "Bruxelles",
                "color": "blue"
            }
        },
        "Name": {
            "title": [
                {
                    "text": {
                        "content": "Musée Mode & Dentelle"
                    }
                }
            ]
        },
        "Opening Days": {
            "multi_select": [
                {
                    "name": "Mardi",
                    "color": "purple"
                },
                {
                    "name": "Mercredi",
                    "color": "purple"
                },
                {
                    "name": "Jeudi",
                    "color": "purple"
                },
                {
                    "name": "Vendredi",
                    "color": "purple"
                },
                {
                    "name": "Samedi",
                    "color": "purple"
                },
                {
                    "name": "Dimanche",
                    "color": "purple"
                }
            ]
        },
        "Opening Hours": {
            "rich_text": [
                {
                    "text": {
                        "content": "10:00-17:00"
                    }
                }
            ]
        },
        "Openings": {
            "rich_text": [
                {
                    "text": {
                        "content": "mar - dim: 10:00 - 17:00"
                    }
                }
            ]
        },
        "Phone": {
            "phone_number": "02 213 44 50"
        },
        "Train Station": {
            "select": {
                "name": "Bruxelles-Central",
                "color": "blue"
            }
        },
        "URL": {
            "url": "https://www.museumpassmusees.be/fr/offre/musee/959e91f7-94b9-4cb6-95f2-b814bbe57074/musee-mode-amp-dentelle"
        },
        "Website": {
            "type": "url",
            "url": "http://www.fashionandlacemuseum.brussels"
        }
    },
    "icon": {
        "type": "emoji",
        "emoji": "☸️"
    },
    "cover": {
        "type": "external",
        "external": {
            "url": "https://media.museumpassmusees.be/d5baa098-aebb-414f-bd55-50358def63a8?max-h=600&max-w=1500"
        }
    }
}

I will take a look at reporting it to the Notion team but I'll leave the issue open in case you have any idea to fix this?

Cheers anyway!

dstotijn commented 2 years ago

Sorry for the late reply. Thanks for the kind words! Looking that the Notion API docs, the description of the color property says:

"Not currently editable."

So I believe it's correct that you cannot set a color for a select option when creating/updating pages/blocks.

At the moment notion.SelectOptions is used for create/update request data, so I guess it's a bit confusing because you could easily think that color is a valid property when creating/updating select options. Having separate types for upserting and reading select options would clear this up, but I think it's not worth the hassle of maintaining a bunch of extra types. So closing this issue for now.