From 46ba0c74afe5c7acbc3ff0cfdeb7dab44df11a13 Mon Sep 17 00:00:00 2001 From: Theodorus Clarence Date: Tue, 18 Jan 2022 12:06:23 +0700 Subject: [PATCH] feat: add increment link count --- src/lib/notion.ts | 39 +++++++++++++++++++++++++++++++++++---- src/pages/_middleware.ts | 5 +++-- src/pages/testing.tsx | 34 ++++++++++++++++++++++++++++++++++ src/types/notion.ts | 2 +- 4 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 src/pages/testing.tsx diff --git a/src/lib/notion.ts b/src/lib/notion.ts index fd61a81..63bb97b 100644 --- a/src/lib/notion.ts +++ b/src/lib/notion.ts @@ -8,6 +8,13 @@ const NOTION_INTEGRATION_SECRET = const notion = new Client({ auth: NOTION_INTEGRATION_SECRET }); +export type Url = { + pageId: string; + slug: string; + link?: string; + count: number; +}; + /** * Get long URL by slug */ @@ -25,11 +32,35 @@ export const getUrlBySlug = async (slug: string) => { }); const results = response.results[0] as unknown as LinkResult; - const url = { - slug: results?.properties.slug.title[0].plain_text, - link: results?.properties.link.rich_text[0].plain_text, - count: Number(results?.properties.count.rich_text[0].plain_text), + + const url: Url = { + pageId: results?.id, + slug: results?.properties.slug.title[0]?.plain_text, + link: results?.properties.link.rich_text[0]?.plain_text, + count: Number(results?.properties.count.rich_text[0]?.plain_text ?? 0), }; return url; }; + +/** + * Increment count column by 1 + */ +export const incrementLinkCount = async (url: Url) => { + if (!NOTION_LINK_DATABASE_ID) { + throw new Error('NEXT_PUBLIC_NOTION_LINK_DATABASE_ID env is not defined'); + } + + if (!url.pageId) { + throw new Error('URL data is not found'); + } + + await notion.pages.update({ + page_id: url.pageId, + properties: { + count: { + rich_text: [{ text: { content: String(url.count + 1) } }], + }, + }, + }); +}; diff --git a/src/pages/_middleware.ts b/src/pages/_middleware.ts index 938305c..5aace85 100644 --- a/src/pages/_middleware.ts +++ b/src/pages/_middleware.ts @@ -1,11 +1,11 @@ import { NextRequest, NextResponse } from 'next/server'; -import { getUrlBySlug } from '@/lib/notion'; +import { getUrlBySlug, incrementLinkCount } from '@/lib/notion'; export default async function middleware(req: NextRequest) { const path = req.nextUrl.pathname.split('/')[1]; - const whitelist = ['favicons', 'fonts', 'images', 'svg', '']; + const whitelist = ['favicons', 'fonts', 'images', 'svg', '', 'testing']; if (whitelist.includes(path)) { return; } @@ -13,6 +13,7 @@ export default async function middleware(req: NextRequest) { const url = await getUrlBySlug(path); if (url.link) { + await incrementLinkCount(url); return NextResponse.redirect(url.link); } } diff --git a/src/pages/testing.tsx b/src/pages/testing.tsx new file mode 100644 index 0000000..07ffbed --- /dev/null +++ b/src/pages/testing.tsx @@ -0,0 +1,34 @@ +import { InferGetStaticPropsType } from 'next'; +import * as React from 'react'; + +import { getUrlBySlug, incrementLinkCount } from '@/lib/notion'; + +import Layout from '@/components/layout/Layout'; +import Seo from '@/components/Seo'; + +export default function TestingPage({ + link, +}: InferGetStaticPropsType) { + return ( + + + +
+
+
+
{JSON.stringify(link, null, 2)}
+
+
+
+
+ ); +} + +export const getStaticProps = async () => { + const link = await getUrlBySlug('clarence'); + await incrementLinkCount(link); + + return { + props: { link }, + }; +}; diff --git a/src/types/notion.ts b/src/types/notion.ts index d714ba2..63936ab 100644 --- a/src/types/notion.ts +++ b/src/types/notion.ts @@ -18,7 +18,7 @@ interface TitleColumn { interface TextColumn { id: string; type: string; - rich_text: [RichText]; + rich_text: [RichText | undefined]; } interface RichText {