|
@@ -0,0 +1,110 @@
|
|
|
+import { isFullPage, Client as NotionClient } from "@notionhq/client"
|
|
|
+import { Currencies, RatesResp } from "./OpenExchangeRates"
|
|
|
+import {
|
|
|
+ PageObjectResponse,
|
|
|
+ QueryDatabaseResponse,
|
|
|
+} from "@notionhq/client/build/src/api-endpoints"
|
|
|
+
|
|
|
+interface Options {
|
|
|
+ notionKey: string
|
|
|
+ databaseId: string
|
|
|
+}
|
|
|
+
|
|
|
+export default class NotionData {
|
|
|
+ #notionKey: string
|
|
|
+ #databaseId: string
|
|
|
+
|
|
|
+ public constructor(options: Options) {
|
|
|
+ this.#notionKey = options.notionKey
|
|
|
+ this.#databaseId = options.databaseId
|
|
|
+ }
|
|
|
+
|
|
|
+ private async queryDatabasePages(
|
|
|
+ notion: NotionClient,
|
|
|
+ dbId: string
|
|
|
+ ): Promise<Array<PageObjectResponse>> {
|
|
|
+ let query: QueryDatabaseResponse
|
|
|
+ let startCursor: string | null = null
|
|
|
+ let fullResults: Array<PageObjectResponse> = []
|
|
|
+ do {
|
|
|
+ query = await notion.databases.query({
|
|
|
+ database_id: dbId,
|
|
|
+ page_size: 100,
|
|
|
+ start_cursor: startCursor ?? undefined,
|
|
|
+ })
|
|
|
+
|
|
|
+ const queryResults = query.results.filter(page => isFullPage(page))
|
|
|
+ startCursor = query.next_cursor
|
|
|
+
|
|
|
+ fullResults = [...fullResults, ...queryResults]
|
|
|
+ } while (query.next_cursor !== null)
|
|
|
+ return fullResults
|
|
|
+ }
|
|
|
+
|
|
|
+ public async syncCurrencies(currencies: Currencies) {
|
|
|
+ const notion = new NotionClient({ auth: this.#notionKey })
|
|
|
+ const pages = await this.queryDatabasePages(notion, this.#databaseId)
|
|
|
+ const existCurrencies = pages
|
|
|
+ .map(page => page.properties["Code"])
|
|
|
+ .filter(prop => prop?.type == "title")
|
|
|
+ .map(prop => prop.title[0]?.plain_text)
|
|
|
+ console.log("Exist Currencies", existCurrencies, existCurrencies.length)
|
|
|
+
|
|
|
+ for (const currency in currencies) {
|
|
|
+ if (existCurrencies.includes(currency)) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ await notion.pages.create({
|
|
|
+ parent: {
|
|
|
+ database_id: this.#databaseId,
|
|
|
+ },
|
|
|
+ properties: {
|
|
|
+ Code: {
|
|
|
+ type: "title",
|
|
|
+ title: [
|
|
|
+ {
|
|
|
+ text: {
|
|
|
+ content: currency,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ Rate: {
|
|
|
+ type: "number",
|
|
|
+ number: 1,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public async updateRates(ratesResp: RatesResp) {
|
|
|
+ const notion = new NotionClient({ auth: this.#notionKey })
|
|
|
+ const ratesMap = ratesResp.rates
|
|
|
+ const pages = await this.queryDatabasePages(notion, this.#databaseId)
|
|
|
+
|
|
|
+ for (const page of pages) {
|
|
|
+ let currencyCodeProp = page.properties["Code"]
|
|
|
+ let currencyCode = undefined
|
|
|
+ if (currencyCodeProp!.type === "title") {
|
|
|
+ currencyCode = currencyCodeProp.title[0]!.plain_text
|
|
|
+ } else {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!(currencyCode! in ratesMap)) {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ await notion.pages.update({
|
|
|
+ page_id: page.id,
|
|
|
+ properties: {
|
|
|
+ Rate: {
|
|
|
+ number: ratesMap[currencyCode] as number,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|