1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

BookNotionを更に神アプリにしたい その1

Posted at

はじめに

BookNotionというアプリをご存知ですか?

KindleのハイライトをかんたんにNotionに保存できる読書記録アプリ(公式サイトより)

すごくざっくり説明すると、ハイライトした箇所をNotionにまとめることができるアプリです。
追加するときもメモとして自分のコメントを入れることや、タグ付けもできます。

追加したあとはNotion内でデータベースにまとめられます。
黄色く塗りつぶしているのは、実際にハイライトした内容がはいっています。
image.png

問題点

このままでも既に神アプリなんですが、個人的な問題点があります。
それは書籍単位でページにまとめられないことです。
理想としては、本Aという新規ページを作成してページ内にハイライトとコメントを全てまとめたいのです:grimacing:

ならつくればよくね?

NotionにはAPIが提供されているということで作ってみることにします。
アプリにする気はないので、とりあえず自分用にページ単位でまとめることができればOKとします。

実際にやってみた

フローとしては以下のようになると思っています。

  1. BookNotionで追加したデータベースから本のタイトルを取得する
  2. 本のタイトルに紐づくハイライトとコメントを取得する
  3. 1.で取得した本のタイトル名で新規ページを作成する
  4. 2.で取得したハイライトとコメントを、作成したページ内に追加する

ひとまずはAPIで取得したデータを実際に追加できるかどうかを試したいので、1件だけ取得・作成したいと思います。

ソースコード

import dotenv from 'dotenv';

dotenv.config();

const API_URL = 'https://api.notion.com/v1';
const API_KEY = process.env.API_KEY;
const DATABASE_ID = process.env.DATABASE_ID;
const PAGE_URL = process.env.PAGE_URL;
const HEADERS = {
  Authorization: `Bearer ${API_KEY}`,
  'Content-Type': 'application/json',
  'Notion-Version': '2022-06-28',
};

//                      BookNotionのBook Titleに紐づいた名前がはいる
const selectBookName = '武器になる哲学 人生を生き抜くための哲学・思想のキーコンセプト50';

const createNewPage = async (pageTitle: string, highlight: string, comment: string) => {
  try {
    const response = await fetch(`${API_URL}/pages`, {
      method: 'POST',
      headers: HEADERS,
      body: JSON.stringify({
        parent: {
          type: 'page_id',
          page_id: PAGE_URL,
        },
        properties: {
          title: {
            type: 'title',
            title: [
              {
                type: 'text',
                text: { content: pageTitle },
              },
            ],
          },
        },
      }),
    });
    const data = await response.json();
    console.log(`Page created: ${data.id}`);

    const blocks = [
      {
        type: 'heading_2',
        heading_2: {
          rich_text: [
            {
              type: 'text',
              text: { content: highlight },
            },
          ],
        },
      },
      {
        type: 'paragraph',
        paragraph: {
          rich_text: [
            {
              type: 'text',
              text: { content: comment },
            },
          ],
        },
      },
    ];
    await appendBlockChildren(data.id, blocks);
  } catch (error) {
    console.error(error);
  }
};
const appendBlockChildren = async (pageId: string, blocks: any[]) => {
  try {
    const response = await fetch(`${API_URL}/blocks/${pageId}/children`, {
      method: 'PATCH',
      headers: HEADERS,
      body: JSON.stringify({ children: blocks }),
    });
    const data = await response.json();
  } catch (error) {
    console.error(error);
  }
};

const getBookProperties = async (selectBookName: string): Promise<BookProperties | {}> => {
  try {
    const response = await fetch(`${API_URL}/databases/${DATABASE_ID}/query`, {
      method: 'POST',
      headers: HEADERS,
    });
    const data = await response.json();

    const filteredPages = data.results.filter((page: any) => {
      const bookTitle = page.properties['📙  Book Title'].select.name;
      return bookTitle === selectBookName;
    });

    if (filteredPages.length > 0) {
      const highlight: string = filteredPages[0].properties['📝  Highlight'].title[0].plain_text;
      const comment: string = filteredPages[0].properties['💬  Comment'].rich_text[0].plain_text;
      return { highlight, comment };
    } else {
      console.log('No pages found with the specified book title.');
      return {};
    }
  } catch (error) {
    console.error(error);
    return {};
  }
};

getBookProperties(selectBookName).then((properties: BookProperties | {}) => {
  if ('highlight' in properties && 'comment' in properties) {
    const { highlight, comment } = properties as BookProperties;
    createNewPage(selectBookName, highlight, comment);
  }
});

動かしてみた

こんな感じで追加されます。
ハイライトの内容は見出し2(## )で追加したため、大きくなっています。

image.png

次回

ハイライトとコメントを全部取得できるようにします。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?