diff --git a/database/migrations.go b/database/migrations.go index d4ebb55d..e7f806cd 100644 --- a/database/migrations.go +++ b/database/migrations.go @@ -707,4 +707,13 @@ var migrations = []func(tx *sql.Tx) error{ _, err = tx.Exec(sql) return err }, + func(tx *sql.Tx) (err error) { + sql := ` + ALTER TABLE integrations ADD COLUMN notion_enabled bool default 'f'; + ALTER TABLE integrations ADD COLUMN notion_token text default ''; + ALTER TABLE integrations ADD COLUMN notion_page_id text default ''; + ` + _, err = tx.Exec(sql) + return err + }, } diff --git a/http/client/client.go b/http/client/client.go index 6e7c2282..46388998 100644 --- a/http/client/client.go +++ b/http/client/client.go @@ -44,9 +44,9 @@ type Client struct { requestPassword string requestUserAgent string requestCookie string - - useProxy bool - doNotFollowRedirects bool + customHeaders map[string]string + useProxy bool + doNotFollowRedirects bool ClientTimeout int ClientMaxBodySize int64 @@ -111,6 +111,12 @@ func (c *Client) WithAuthorization(authorization string) *Client { return c } +// WithCustomHeaders defines custom HTTP headers. +func (c *Client) WithCustomHeaders(customHeaders map[string]string) *Client { + c.customHeaders = customHeaders + return c +} + // WithCacheHeaders defines caching headers. func (c *Client) WithCacheHeaders(etagHeader, lastModifiedHeader string) *Client { c.requestEtagHeader = etagHeader @@ -183,6 +189,22 @@ func (c *Client) PostJSON(data interface{}) (*Response, error) { return c.executeRequest(request) } +// PatchJSON performs a Patch HTTP request with a JSON payload. +func (c *Client) PatchJSON(data interface{}) (*Response, error) { + b, err := json.Marshal(data) + if err != nil { + return nil, err + } + + request, err := c.buildRequest(http.MethodPatch, bytes.NewReader(b)) + if err != nil { + return nil, err + } + + request.Header.Add("Content-Type", "application/json") + return c.executeRequest(request) +} + func (c *Client) executeRequest(request *http.Request) (*Response, error) { defer timer.ExecutionTime(time.Now(), fmt.Sprintf("[HttpClient] inputURL=%s", c.inputURL)) @@ -337,6 +359,10 @@ func (c *Client) buildHeaders() http.Header { headers.Add("Cookie", c.requestCookie) } + for key, value := range c.customHeaders { + headers.Add(key, value) + } + headers.Add("Connection", "close") return headers } diff --git a/integration/integration.go b/integration/integration.go index 52a4b8af..96f02305 100644 --- a/integration/integration.go +++ b/integration/integration.go @@ -9,6 +9,7 @@ import ( "miniflux.app/integration/instapaper" "miniflux.app/integration/linkding" "miniflux.app/integration/matrixbot" + "miniflux.app/integration/notion" "miniflux.app/integration/nunuxkeeper" "miniflux.app/integration/pinboard" "miniflux.app/integration/pocket" @@ -62,6 +63,18 @@ func SendEntry(entry *model.Entry, integration *model.Integration) { } } + if integration.NotionEnabled { + logger.Debug("[Integration] Sending Entry #%d %q for User #%d to Notion", entry.ID, entry.URL, integration.UserID) + + client := notion.NewClient( + integration.NotionToken, + integration.NotionPageID, + ) + if err := client.AddEntry(entry.URL, entry.Title); err != nil { + logger.Error("[Integration] UserID #%d: %v", integration.UserID, err) + } + } + if integration.NunuxKeeperEnabled { logger.Debug("[Integration] Sending Entry #%d %q for User #%d to NunuxKeeper", entry.ID, entry.URL, integration.UserID) diff --git a/integration/notion/notion.go b/integration/notion/notion.go new file mode 100644 index 00000000..16f29dc3 --- /dev/null +++ b/integration/notion/notion.go @@ -0,0 +1,54 @@ +// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package notion + +import ( + "fmt" + + "miniflux.app/http/client" +) + +// Client represents a Notion client. +type Client struct { + token string + pageID string +} + +// NewClient returns a new Notion client. +func NewClient(token, pageID string) *Client { + return &Client{token, pageID} +} + +func (c *Client) AddEntry(entryURL string, entryTitle string) error { + if c.token == "" || c.pageID == "" { + return fmt.Errorf("notion: missing credentials") + } + clt := client.New("https://api.notion.com/v1/blocks/" + c.pageID + "/children") + block := &Data{ + Children: []Block{ + { + Object: "block", + Type: "bookmark", + Bookmark: Bookmark{ + Caption: []interface{}{}, + URL: entryURL, + }, + }, + }, + } + clt.WithAuthorization("Bearer " + c.token) + customHeaders := map[string]string{ + "Notion-Version": "2022-06-28", + } + clt.WithCustomHeaders(customHeaders) + response, error := clt.PatchJSON(block) + if error != nil { + return fmt.Errorf("notion: unable to patch entry: %v", error) + } + + if response.HasServerFailure() { + return fmt.Errorf("notion: request failed, status=%d", response.StatusCode) + } + return nil +} diff --git a/integration/notion/wrapper.go b/integration/notion/wrapper.go new file mode 100644 index 00000000..d37633c0 --- /dev/null +++ b/integration/notion/wrapper.go @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package notion + +type Data struct { + Children []Block `json:"children"` +} + +type Block struct { + Object string `json:"object"` + Type string `json:"type"` + Bookmark Bookmark `json:"bookmark"` +} + +type Bookmark struct { + Caption []interface{} `json:"caption"` // Assuming the "caption" field can have different types + URL string `json:"url"` +} diff --git a/locale/translations/de_DE.json b/locale/translations/de_DE.json index 5a001d4e..0ef14f91 100644 --- a/locale/translations/de_DE.json +++ b/locale/translations/de_DE.json @@ -351,6 +351,9 @@ "form.integration.wallabag_client_secret": "Wallabag Client-Secret", "form.integration.wallabag_username": "Wallabag Benutzername", "form.integration.wallabag_password": "Wallabag Passwort", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "Artikel in Nunux Keeper speichern", "form.integration.nunux_keeper_endpoint": "Nunux Keeper API-Endpunkt", "form.integration.nunux_keeper_api_key": "Nunux Keeper API-Schlüssel", diff --git a/locale/translations/el_EL.json b/locale/translations/el_EL.json index acfca611..6527fed3 100644 --- a/locale/translations/el_EL.json +++ b/locale/translations/el_EL.json @@ -351,6 +351,9 @@ "form.integration.wallabag_client_secret": "Wallabag Μυστικό Πελάτη", "form.integration.wallabag_username": "Όνομα Χρήστη Wallabag", "form.integration.wallabag_password": "Wallabag Κωδικός Πρόσβασης", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "Αποθήκευση άρθρων στο Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Τελικό σημείο Nunux Keeper API", "form.integration.nunux_keeper_api_key": "Κλειδί API Nunux Keeper", diff --git a/locale/translations/en_US.json b/locale/translations/en_US.json index 0d5e0350..d278bfdb 100644 --- a/locale/translations/en_US.json +++ b/locale/translations/en_US.json @@ -351,6 +351,9 @@ "form.integration.wallabag_client_secret": "Wallabag Client Secret", "form.integration.wallabag_username": "Wallabag Username", "form.integration.wallabag_password": "Wallabag Password", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "Save entries to Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Nunux Keeper API Endpoint", "form.integration.nunux_keeper_api_key": "Nunux Keeper API key", diff --git a/locale/translations/es_ES.json b/locale/translations/es_ES.json index d1b9fcc5..e69e56d4 100644 --- a/locale/translations/es_ES.json +++ b/locale/translations/es_ES.json @@ -351,6 +351,9 @@ "form.integration.wallabag_client_secret": "Secreto de cliente de Wallabag", "form.integration.wallabag_username": "Nombre de usuario de Wallabag", "form.integration.wallabag_password": "Contraseña de Wallabag", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "Enviar artículos a Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Acceso API de Nunux Keeper", "form.integration.nunux_keeper_api_key": "Clave de API de Nunux Keeper", diff --git a/locale/translations/fi_FI.json b/locale/translations/fi_FI.json index 554fe014..16b6bb39 100644 --- a/locale/translations/fi_FI.json +++ b/locale/translations/fi_FI.json @@ -351,6 +351,9 @@ "form.integration.wallabag_client_secret": "Wallabag Client Secret", "form.integration.wallabag_username": "Wallabag-käyttäjätunnus", "form.integration.wallabag_password": "Wallabag-salasana", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "Tallenna artikkelit Nunux Keeperiin", "form.integration.nunux_keeper_endpoint": "Nunux Keeper API-päätepiste", "form.integration.nunux_keeper_api_key": "Nunux Keeper API-avain", diff --git a/locale/translations/fr_FR.json b/locale/translations/fr_FR.json index 13b5481b..c1e6975d 100644 --- a/locale/translations/fr_FR.json +++ b/locale/translations/fr_FR.json @@ -351,6 +351,9 @@ "form.integration.wallabag_client_secret": "Clé secrète du client Wallabag", "form.integration.wallabag_username": "Nom d'utilisateur de Wallabag", "form.integration.wallabag_password": "Mot de passe de Wallabag", + "form.integration.notion_activate": "Sauvegarder les articles vers Notion", + "form.integration.notion_page_id": "l'identifiant de la page Notion", + "form.integration.notion_token": "Jeton d'accès de l'API de Notion", "form.integration.nunux_keeper_activate": "Sauvegarder les articles vers Nunux Keeper", "form.integration.nunux_keeper_endpoint": "URL de l'API de Nunux Keeper", "form.integration.nunux_keeper_api_key": "Clé d'API de Nunux Keeper", diff --git a/locale/translations/hi_IN.json b/locale/translations/hi_IN.json index dbe6107d..7e0b2f54 100644 --- a/locale/translations/hi_IN.json +++ b/locale/translations/hi_IN.json @@ -351,6 +351,9 @@ "form.integration.wallabag_client_secret": "वालाबैग क्लाइंट सीक्रेट", "form.integration.wallabag_username": "वालाबैग उपयोगकर्ता नाम", "form.integration.wallabag_password": "वालाबैग पासवर्ड", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "विषय-वस्तु को ननक्स कीपर में सहेजें", "form.integration.nunux_keeper_endpoint": "ननक्स कीपर एपीआई समापन बिंदु", "form.integration.nunux_keeper_api_key": "ननक्स कीपर एपीआई कुंजी", diff --git a/locale/translations/id_ID.json b/locale/translations/id_ID.json index 3fa277fb..4e4a8a39 100644 --- a/locale/translations/id_ID.json +++ b/locale/translations/id_ID.json @@ -348,6 +348,9 @@ "form.integration.wallabag_client_secret": "Rahasia Klien Wallabag", "form.integration.wallabag_username": "Nama Pengguna Wallabag", "form.integration.wallabag_password": "Kata Sandi Wallabag", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "Simpan artikel ke Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Titik URL API Nunux Keeper", "form.integration.nunux_keeper_api_key": "Kunci API Nunux Keeper", diff --git a/locale/translations/it_IT.json b/locale/translations/it_IT.json index 31876b79..d30b7f66 100644 --- a/locale/translations/it_IT.json +++ b/locale/translations/it_IT.json @@ -351,6 +351,9 @@ "form.integration.wallabag_client_secret": "Client secret dell'account Wallabag", "form.integration.wallabag_username": "Nome utente dell'account Wallabag", "form.integration.wallabag_password": "Password dell'account Wallabag", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "Salva gli articoli su Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Endpoint dell'API di Nunux Keeper", "form.integration.nunux_keeper_api_key": "API key dell'account Nunux Keeper", diff --git a/locale/translations/ja_JP.json b/locale/translations/ja_JP.json index 4d4ba130..782d6e2d 100644 --- a/locale/translations/ja_JP.json +++ b/locale/translations/ja_JP.json @@ -351,6 +351,9 @@ "form.integration.wallabag_client_secret": "Wallabag の Client Secret", "form.integration.wallabag_username": "Wallabag のユーザー名", "form.integration.wallabag_password": "Wallabag のパスワード", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "Nunux Keeper に記事を保存する", "form.integration.nunux_keeper_endpoint": "Nunux Keeper の API Endpoint", "form.integration.nunux_keeper_api_key": "Nunux Keeper の API key", diff --git a/locale/translations/nl_NL.json b/locale/translations/nl_NL.json index 102d1359..3fb32dbe 100644 --- a/locale/translations/nl_NL.json +++ b/locale/translations/nl_NL.json @@ -351,6 +351,9 @@ "form.integration.wallabag_client_secret": "Wallabag Client-Secret", "form.integration.wallabag_username": "Wallabag gebruikersnaam", "form.integration.wallabag_password": "Wallabag wachtwoord", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "Opslaan naar Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Nunux Keeper URL", "form.integration.nunux_keeper_api_key": "Nunux Keeper API-sleutel", diff --git a/locale/translations/pl_PL.json b/locale/translations/pl_PL.json index d22775bf..6f32532e 100644 --- a/locale/translations/pl_PL.json +++ b/locale/translations/pl_PL.json @@ -353,6 +353,9 @@ "form.integration.wallabag_client_secret": "Wallabag Client Secret", "form.integration.wallabag_username": "Login do Wallabag", "form.integration.wallabag_password": "Hasło do Wallabag", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "Zapisz artykuly do Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Nunux Keeper URL", "form.integration.nunux_keeper_api_key": "Nunux Keeper API key", diff --git a/locale/translations/pt_BR.json b/locale/translations/pt_BR.json index ac8b2059..f5ee949d 100644 --- a/locale/translations/pt_BR.json +++ b/locale/translations/pt_BR.json @@ -351,6 +351,9 @@ "form.integration.wallabag_client_secret": "Segredo do cliente (Client Secret) do Wallabag", "form.integration.wallabag_username": "Nome de usuário do Wallabag", "form.integration.wallabag_password": "Senha do Wallabag", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "Salvar itens no Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Endpoint de API do Nunux Keeper", "form.integration.nunux_keeper_api_key": "Chave de API do Nunux Keeper", diff --git a/locale/translations/ru_RU.json b/locale/translations/ru_RU.json index 7df14c03..82eb0481 100644 --- a/locale/translations/ru_RU.json +++ b/locale/translations/ru_RU.json @@ -353,6 +353,9 @@ "form.integration.wallabag_client_secret": "Wallabag Client Secret", "form.integration.wallabag_username": "Имя пользователя Wallabag", "form.integration.wallabag_password": "Пароль Wallabag", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "Сохранять статьи в Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Конечная точка Nunux Keeper API", "form.integration.nunux_keeper_api_key": "API-ключ Nunux Keeper", diff --git a/locale/translations/tr_TR.json b/locale/translations/tr_TR.json index 78cbdbe9..641efcb4 100644 --- a/locale/translations/tr_TR.json +++ b/locale/translations/tr_TR.json @@ -351,6 +351,9 @@ "form.integration.wallabag_client_secret": "Wallabag Client Secret", "form.integration.wallabag_username": "Wallabag Kullanıcı Adı", "form.integration.wallabag_password": "Wallabag Parolası", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "Makaleleri Nunux Keeper'a kaydet", "form.integration.nunux_keeper_endpoint": "Nunux Keeper API Uç Noktası", "form.integration.nunux_keeper_api_key": "Nunux Keeper API anahtarı", diff --git a/locale/translations/uk_UA.json b/locale/translations/uk_UA.json index 4e06b6e5..42be13f7 100644 --- a/locale/translations/uk_UA.json +++ b/locale/translations/uk_UA.json @@ -350,6 +350,9 @@ "form.integration.wallabag_client_secret": "Wallabag Client Secret", "form.integration.wallabag_username": "Ім’я користувача Wallabag", "form.integration.wallabag_password": "Пароль Wallabag", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "Зберігати статті до Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Nunux Keeper API Endpoint", "form.integration.nunux_keeper_api_key": "Ключ API Nunux Keeper", diff --git a/locale/translations/zh_CN.json b/locale/translations/zh_CN.json index e333885e..e96e964a 100644 --- a/locale/translations/zh_CN.json +++ b/locale/translations/zh_CN.json @@ -349,6 +349,9 @@ "form.integration.wallabag_client_secret": "Wallabag 客户端 Secret", "form.integration.wallabag_username": "Wallabag 用户名", "form.integration.wallabag_password": "Wallabag 密码", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "保存文章到 Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Nunux Keeper API 端点", "form.integration.nunux_keeper_api_key": "Nunux Keeper API 密钥", diff --git a/locale/translations/zh_TW.json b/locale/translations/zh_TW.json index 1ef1e2b1..0330664e 100644 --- a/locale/translations/zh_TW.json +++ b/locale/translations/zh_TW.json @@ -351,6 +351,9 @@ "form.integration.wallabag_client_secret": "Wallabag 客戶端 Secret", "form.integration.wallabag_username": "Wallabag 使用者名稱", "form.integration.wallabag_password": "Wallabag 密碼", + "form.integration.notion_activate": "Save entries to Notion", + "form.integration.notion_page_id": "Notion Page ID", + "form.integration.notion_token": "Notion Secret Token", "form.integration.nunux_keeper_activate": "儲存文章到 Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Nunux Keeper API 端點", "form.integration.nunux_keeper_api_key": "Nunux Keeper API 金鑰", diff --git a/model/integration.go b/model/integration.go index 138af747..50abd7fc 100644 --- a/model/integration.go +++ b/model/integration.go @@ -29,6 +29,9 @@ type Integration struct { NunuxKeeperEnabled bool NunuxKeeperURL string NunuxKeeperAPIKey string + NotionEnabled bool + NotionToken string + NotionPageID string EspialEnabled bool EspialURL string EspialAPIKey string diff --git a/storage/integration.go b/storage/integration.go index 98dd271c..f65aff6e 100644 --- a/storage/integration.go +++ b/storage/integration.go @@ -130,6 +130,9 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) { wallabag_client_secret, wallabag_username, wallabag_password, + notion_enabled, + notion_token, + notion_page_id, nunux_keeper_enabled, nunux_keeper_url, nunux_keeper_api_key, @@ -181,6 +184,9 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) { &integration.WallabagClientSecret, &integration.WallabagUsername, &integration.WallabagPassword, + &integration.NotionEnabled, + &integration.NotionToken, + &integration.NotionPageID, &integration.NunuxKeeperEnabled, &integration.NunuxKeeperURL, &integration.NunuxKeeperAPIKey, @@ -269,7 +275,10 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error { matrix_bot_user=$40, matrix_bot_password=$41, matrix_bot_url=$42, - matrix_bot_chat_id=$43 + matrix_bot_chat_id=$43, + notion_enabled=$45, + notion_token=$46, + notion_page_id=$47 WHERE user_id=$44 ` @@ -318,6 +327,9 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error { integration.MatrixBotPassword, integration.MatrixBotURL, integration.MatrixBotChatID, + integration.NotionEnabled, + integration.NotionToken, + integration.NotionPageID, integration.UserID, ) } else { @@ -367,7 +379,10 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error { matrix_bot_user=$40, matrix_bot_password=$41, matrix_bot_url=$42, - matrix_bot_chat_id=$43 + matrix_bot_chat_id=$43, + notion_enabled=$45, + notion_token=$46, + notion_page_id=$47 WHERE user_id=$44 ` @@ -417,6 +432,9 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error { integration.MatrixBotURL, integration.MatrixBotChatID, integration.UserID, + integration.NotionEnabled, + integration.NotionToken, + integration.NotionPageID, ) } @@ -437,7 +455,7 @@ func (s *Storage) HasSaveEntry(userID int64) (result bool) { WHERE user_id=$1 AND - (pinboard_enabled='t' OR instapaper_enabled='t' OR wallabag_enabled='t' OR nunux_keeper_enabled='t' OR espial_enabled='t' OR pocket_enabled='t' OR linkding_enabled='t') + (pinboard_enabled='t' OR instapaper_enabled='t' OR wallabag_enabled='t' OR notion_enabled='t' OR nunux_keeper_enabled='t' OR espial_enabled='t' OR pocket_enabled='t' OR linkding_enabled='t') ` if err := s.db.QueryRow(query, userID).Scan(&result); err != nil { result = false diff --git a/template/templates/views/integrations.html b/template/templates/views/integrations.html index a89e16c0..afc47bef 100644 --- a/template/templates/views/integrations.html +++ b/template/templates/views/integrations.html @@ -142,7 +142,22 @@ +

Notion

+
+ + + + + + + +
+ +
+

Nunux Keeper