sync items and highlights to user created database in notion

This commit is contained in:
Hongbo Wu
2024-04-03 22:25:19 +08:00
parent f794cf707a
commit 491611b05f
2 changed files with 100 additions and 90 deletions

View File

@ -40,6 +40,7 @@ import {
saveIntegration,
updateIntegration,
} from '../../services/integrations'
import { NotionClient } from '../../services/integrations/notion'
import { analytics } from '../../utils/analytics'
import {
deleteTask,
@ -57,15 +58,14 @@ export const setIntegrationResolver = authorized<
...input,
user: { id: uid },
id: input.id || undefined,
type: input.type || IntegrationType.Export,
type: input.type || undefined,
syncedAt: input.syncedAt ? new Date(input.syncedAt) : undefined,
importItemState:
input.type === IntegrationType.Import
? input.importItemState || ImportItemState.Unarchived // default to unarchived
: undefined,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
settings: input.settings,
}
if (input.id) {
// Update
const existingIntegration = await findIntegration({ id: input.id }, uid)
@ -96,6 +96,19 @@ export const setIntegrationResolver = authorized<
if (integration.name.toLowerCase() === 'readwise') {
// create a task to export all the items for readwise temporarily
await enqueueExportToIntegration(integration.id, uid)
} else if (integration.name.toLowerCase() === 'notion') {
const settings = integration.settings as { parentDatabaseId?: string }
if (settings.parentDatabaseId) {
// update notion database properties
const notion = new NotionClient(integration.token, integration)
try {
await notion.updateDatabase(settings.parentDatabaseId)
} catch (error) {
return {
errorCodes: [SetIntegrationErrorCode.BadRequest],
}
}
}
}
analytics.capture({

View File

@ -1,6 +1,5 @@
import { Client } from '@notionhq/client'
import axios from 'axios'
import { updateIntegration } from '.'
import { Integration } from '../../entity/integration'
import { LibraryItem } from '../../entity/library_item'
import { env } from '../../env'
@ -111,7 +110,7 @@ type Property = 'highlights'
interface Settings {
parentPageId: string
parentDatabaseId: string
properties: Property[]
properties?: Property[]
}
export class NotionClient implements IntegrationClient {
@ -244,7 +243,7 @@ export class NotionClient implements IntegrationClient {
: undefined,
},
children:
settings.properties.includes('highlights') && item.highlights
settings.properties?.includes('highlights') && item.highlights
? item.highlights
.filter(
(highlight) => !lastSync || highlight.updatedAt > lastSync // only new highlights
@ -315,103 +314,101 @@ export class NotionClient implements IntegrationClient {
return false
}
const pageId = settings.parentPageId
if (!pageId) {
logger.error('Notion parent page id not found')
return false
}
let databaseId = settings.parentDatabaseId
const databaseId = settings.parentDatabaseId
if (!databaseId) {
// create a database for the items
const database = await this.client.databases.create({
parent: {
page_id: pageId,
},
title: [
{
text: {
content: 'Library',
},
},
],
description: [
{
text: {
content: 'Library of saved items from Omnivore',
},
},
],
properties: {
Title: {
title: {},
},
Author: {
rich_text: {},
},
'Original URL': {
url: {},
},
'Omnivore URL': {
url: {},
},
'Saved At': {
date: {},
},
'Last Updated': {
date: {},
},
Tags: {
multi_select: {},
},
},
})
// save the database id
databaseId = database.id
settings.parentDatabaseId = databaseId
await updateIntegration(
this.integrationData.id,
{
settings,
},
this.integrationData.user.id
)
logger.error('Notion database id not found')
return false
}
await Promise.all(
items.map(async (item) => {
const notionPage = this.itemToNotionPage(
item,
settings,
this.integrationData?.syncedAt
)
const url = notionPage.properties['Omnivore URL'].url
try {
const notionPage = this.itemToNotionPage(
item,
settings,
this.integrationData?.syncedAt
)
const url = notionPage.properties['Omnivore URL'].url
const existingPage = await this.findPage(url, databaseId)
if (existingPage) {
// update the page
await this.client.pages.update({
page_id: existingPage.id,
properties: notionPage.properties,
})
// append the children incrementally
if (notionPage.children && notionPage.children.length > 0) {
await this.client.blocks.children.append({
block_id: existingPage.id,
children: notionPage.children,
const existingPage = await this.findPage(url, databaseId)
if (existingPage) {
// update the page
await this.client.pages.update({
page_id: existingPage.id,
properties: notionPage.properties,
})
// append the children incrementally
if (notionPage.children && notionPage.children.length > 0) {
await this.client.blocks.children.append({
block_id: existingPage.id,
children: notionPage.children,
})
}
return
}
return
// create the page
return this.createPage(notionPage)
} catch (error) {
logger.error(error)
return false
}
// create the page
return this.createPage(notionPage)
})
)
return true
}
private findDatabase = async (databaseId: string) => {
return this.client.databases.retrieve({
database_id: databaseId,
})
}
updateDatabase = async (databaseId: string) => {
const database = await this.findDatabase(databaseId)
await this.client.databases.update({
database_id: database.id,
title: [
{
text: {
content: 'Library',
},
},
],
description: [
{
text: {
content: 'Library of saved items from Omnivore',
},
},
],
properties: {
Title: {
title: {},
},
Author: {
rich_text: {},
},
'Original URL': {
url: {},
},
'Omnivore URL': {
url: {},
},
'Saved At': {
date: {},
},
'Last Updated': {
date: {},
},
Tags: {
multi_select: {},
},
},
})
}
}