From e20908a0c29c8a371433fcc3dc8c7dfbdd138f00 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Mon, 4 Mar 2024 18:44:25 +0800 Subject: [PATCH] add export to notion method --- .../api/src/services/integrations/notion.ts | 94 ++++++++++++++++++- .../api/src/services/integrations/pocket.ts | 4 +- .../api/src/services/integrations/readwise.ts | 2 +- 3 files changed, 93 insertions(+), 7 deletions(-) diff --git a/packages/api/src/services/integrations/notion.ts b/packages/api/src/services/integrations/notion.ts index fd46dc1bb..bcd6573e0 100644 --- a/packages/api/src/services/integrations/notion.ts +++ b/packages/api/src/services/integrations/notion.ts @@ -1,15 +1,46 @@ import axios from 'axios' +import { LibraryItem } from '../../entity/library_item' import { env } from '../../env' import { logger } from '../../utils/logger' import { IntegrationClient } from './integration' +interface NotionPage { + parent: { + database_id: string + } + cover?: { + external: { + url: string + } + } + properties: { + Name: { + title: Array<{ + text: { + content: string + } + }> + } + URL: { + url: string + } + Tags: { + multi_select: Array<{ + name: string + }> + } + } +} + export class NotionClient implements IntegrationClient { name = 'NOTION' apiUrl = 'https://api.notion.com/v1' headers = { 'Content-Type': 'application/json', Accept: 'application/json', + 'Notion-Version': '2022-06-28', } + timeout = 5000 // 5 seconds accessToken = async (code: string): Promise => { const authUrl = `${this.apiUrl}/oauth/token` @@ -31,7 +62,7 @@ export class NotionClient implements IntegrationClient { authorization: `Basic ${encoded}`, ...this.headers, }, - timeout: 5000, // 5 seconds + timeout: this.timeout, } ) return response.data.access_token @@ -45,11 +76,66 @@ export class NotionClient implements IntegrationClient { } } - async auth(state: string): Promise { + async auth(): Promise { return Promise.resolve(env.notion.authUrl) } - export = () => { - throw new Error('Method not implemented.') + private _itemToNotionPage = (item: LibraryItem): NotionPage => { + return { + parent: { + database_id: item.id, + }, + cover: item.thumbnail + ? { + external: { + url: item.thumbnail, + }, + } + : undefined, + properties: { + Name: { + title: [ + { + text: { + content: item.title, + }, + }, + ], + }, + URL: { + url: item.originalUrl, + }, + Tags: { + multi_select: + item.labels?.map((label) => { + return { + name: label.name, + } + }) || [], + }, + }, + } + } + + export = async (token: string, items: LibraryItem[]): Promise => { + const url = `${this.apiUrl}/pages` + const page = this._itemToNotionPage(items[0]) + try { + const response = await axios.post(url, page, { + headers: { + Authorization: `Bearer ${token}`, + ...this.headers, + }, + timeout: this.timeout, + }) + return response.status === 200 + } catch (error) { + if (axios.isAxiosError(error)) { + logger.error(error.response) + } else { + logger.error(error) + } + return false + } } } diff --git a/packages/api/src/services/integrations/pocket.ts b/packages/api/src/services/integrations/pocket.ts index 661d1ba0d..8f9e8ed50 100644 --- a/packages/api/src/services/integrations/pocket.ts +++ b/packages/api/src/services/integrations/pocket.ts @@ -36,8 +36,8 @@ export class PocketClient implements IntegrationClient { } } - export = async (): Promise => { - return Promise.resolve(false) + export = () => { + throw new Error('Method not implemented.') } async auth(state: string) { diff --git a/packages/api/src/services/integrations/readwise.ts b/packages/api/src/services/integrations/readwise.ts index e82597a9c..84b15a25a 100644 --- a/packages/api/src/services/integrations/readwise.ts +++ b/packages/api/src/services/integrations/readwise.ts @@ -67,7 +67,7 @@ export class ReadwiseClient implements IntegrationClient { return result } - auth(state: string): Promise { + auth = () => { throw new Error('Method not implemented.') }