JSPM

  • Created
  • Published
  • Downloads 718
  • Score
    100M100P100Q95481F
  • License MIT

A library of functions for working more easily with the Notion API

Package Exports

  • notion-helper
  • notion-helper/index.mjs

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (notion-helper) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

notion-helper

This is a little library of functions I use to work more easily with the Notion API.

It's mainly built to help you create pages and blocks without writing so many nested objects and arrays by hand.

All functions and methods have JSDoc markup to support IntelliSense.

Installation

This package is ESM-only.

Install via npm:

npm install notion-helper

Usage

Import the package:

import NotionHelper from "notion-helper";

From here, you can destructure the functions to use them directly, or just call NotionHelper.

const { makeParagraphBlocks } = NotionHelper;

const quotes = [
  "Dear frozen yogurt, you are the celery of desserts. Be ice cream, or be nothing.",
  "Give me all the bacon and eggs you have.",
  "There is no quiet anymore. There is only Doc McStuffins.",
];

const paragraphBlocks = makeParagraphBlocks(quotes);

// or...

const paragraphBlocks = NotionHelper.makeParagraphBlocks(quotes);

Notion Helper currently contains four direct functions you can use:

  • quickPages() - lets you easily create valid page objects with property values and child blocks using very simple JSON objects. This is the highest-level function in the library – you can see its documentation below.
  • makeParagraphBlocks() - takes an array of strings and returns an array of Paragraph blocks without any special formatting or links. Provides a very quick way to prep a lot of text for sending to Notion.
  • buildRichTextObj() - takes a string, options array, and URL and creates a Rich Text Object array (use flatMap() if you're inserting its output into another array). Splits strings over the character limit for you as well. Currently only works for text objects; mentions and equations aren't supported yet..
  • setIcon() - takes a string, which should be a single emoji (🌵) or an image URL and returns the correct object (emoji or external) value for an icon property.

Using quickPages()

Often you'll have an array of relatively simple data that you want to turn into Notion pages:

const tasks = [
    {
        icon: "🔨",
        task: "Build Standing Desk",
        due: "2024-09-10",
        status: "Not started",
    },
    {
        task: "Mount Overhead Lights",
        due: "2024-09-11",
        status: "Not started",
        children: [
            "Mount clamp to joist and tighten",
            "Attach arm to clamp",
            "Mount video light to arm",
            "Run power cable through ceiling panels"
        ],
    },
    { task: "Set Up Camera", due: "2024-09-11", status: "Not started" },
];

Say you want to create a page in a Tasks database for each of these, setting the relevant properties and creating a list of To-Do blocks in the page body for any that have a children array.

The Notion API requires a much more verbose page data object for each of these:
[
  {
    parent: { type: 'database_id', database_id: 'abcdefghijklmnopqrstuvwxyz' },
    icon: { type: 'emoji', emoji: '🔨' },
    properties: {
      Name: {
        title: [
          {
            type: 'text',
            text: { content: 'Build Standing Desk' },
            annotations: {}
          }
        ]
      },
      'Due Date': { date: { start: '2024-09-10', end: null } },
      Status: { status: { name: 'Not started' } }
    }
  },
  {
    parent: { type: 'database_id', database_id: 'abcdefghijklmnopqrstuvwxyz' },
    properties: {
      Name: {
        title: [
          {
            type: 'text',
            text: { content: 'Mount Overhead Lights' },
            annotations: {}
          }
        ]
      },
      'Due Date': { date: { start: '2024-09-11', end: null } },
      Status: { status: { name: 'Not started' } }
    },
    children: [
      {
        type: 'to_do',
        to_do: {
          rich_text: [
            {
              type: 'text',
              text: { content: 'Mount clamp to joist and tighten' },
              annotations: {}
            }
          ],
          checked: false,
          color: 'default',
          children: []
        }
      },
      {
        type: 'to_do',
        to_do: {
          rich_text: [
            {
              type: 'text',
              text: { content: 'Attach arm to clamp' },
              annotations: {}
            }
          ],
          checked: false,
          color: 'default',
          children: []
        }
      },
      {
        type: 'to_do',
        to_do: {
          rich_text: [
            {
              type: 'text',
              text: { content: 'Mount video light to arm' },
              annotations: {}
            }
          ],
          checked: false,
          color: 'default',
          children: []
        }
      },
      {
        type: 'to_do',
        to_do: {
          rich_text: [
            {
              type: 'text',
              text: { content: 'Run power cable through ceiling panels' },
              annotations: {}
            }
          ],
          checked: false,
          color: 'default',
          children: []
        }
      }
    ]
  },
  {
    parent: { type: 'database_id', database_id: 'abcdefghijklmnopqrstuvwxyz' },
    properties: {
      Name: {
        title: [
          {
            type: 'text',
            text: { content: 'Set Up Camera' },
            annotations: {}
          }
        ]
      },
      'Due Date': { date: { start: '2024-09-11', end: null } },
      Status: { status: { name: 'Not started' } }
    }
  }
]

Using quickPages(), you can create an array of valid page objects like the one in the toggle above.

With it, you can pass an options object with:

  • parent: A parent page/database
  • parent_type: The parent's type ("page_id" or "database_id")
  • pages: Your array of objects
  • schema: A schema describing how your object's properties map to Notion property names and types
  • childrenFn: An optional callback that will be excuted on all array elements in any object's children property, creating a children array within the Notion page object

[!TIP] You can also pass a single object, but you'll still get an array back.

The schema object should contain a property for each property in the Notion database you'd like to edit. For each, the key should map to a key present in at least one of your objects, and its value should be an array containing the matching Notion database property's name and type.

Valid property types include all those listed in the page_props section below.

[!NOTE] If the parent has the type page_id (i.e. it's a page, not a database), the only valid value will be ["title", "title"], which represent's the page's title.

Here's an example of simple usage, operating on the tasks array shown above:

const propertySchema = {
    task: ["Name", "title"],
    due: ["Due Date", "date"],
    status: ["Status", "status"],
}

const pages = quickPages({
    parent: database_id,
    parent_type: "database_id",
    pages: tasks,
    schema: propertySchema,
})

/* Create a page for each returned page object */
const responses = await Promise.all(
    pages.map((page) => notion.pages.create(page))
)

Optionally, your schema can also include custom properties that represent the icon, cover, and children. If you want to specify these, use the convention below to tell the function which properties correspond to the icon, cover, and children properties.

By default, the function will look for icon, cover, and children in your pages object, so you don't need to specify those keys in your schema if they're named that way.

const schema = [
    favicon: ["Icon", "icon"],
    bg_image: ["Cover", "cover"],
    body: ["Children", "children"]
]

By default, if you have a string or an array of strings in any object's children property, those strings will be turned into Paragraph blocks.

However, you can use the childrenFn parameter to pass a callback function. All array elements in each object's children property (if present) will be run through this callback. childrenFn should take in an array as its argument and return an array. The returned array will be used directly as the children array in the final page object.

In the example below, childrenFn is used to create a To-Do block for each children item:

const pages = quickPages({
    parent: database_id,
    parent_type: "database_id",
    pages: tasks,
    schema: propertySchema,
    childrenFn: (value) => value.map((line) => NotionHelper.block.to_do.createBlock({rtArray: NotionHelper.buildRichTextObj(line)}))
})

Note how other Notion Helper functions are used in this example callback to easily construct the To-Do blocks.

If an object's children property already contains an array of prepared Block objects, simply make it the return value of childrenFn. Otherwise, quickPages() will treat it as invalid children content and strip it out. Without a childrenFn, quickPages() will only automatically process a string or array of strings in a children property.

const pages = quickPages({
    parent: database_id,
    parent_type: "database_id",
    pages: tasks,
    schema: propertySchema,
    childrenFn: (value) => value
})

This library also provides objects with methods for quickly creating pages and blocks:

block

The block object lets you create most supported block types while writing less code. It supports these block types:

  • Bookmark
  • Bulleted List Item
  • Callout
  • Code
  • Divider
  • Embed
  • File
  • Heading 1
  • Heading 2
  • Heading 3
  • Image
  • Numbered List Item
  • Paragraph
  • PDF
  • Quote
  • Table
  • Table Row
  • Table of Contents
  • To-Do
  • Toggle
  • Video

Some block types will return a null if they are provided with invalid input. You should filter null entries out of your children array before adding it to an API call.

Each block type has a createBlock() method you can call, which takes an object containing properties specific to that block type. Most take an rtArray, which is an array of Rich Text objects you can easily create with builtRichTextObj().

Examples:

const headerText = "How to Play Guitar with Your Teeth";

const heading1 = NotionHelper.block.heading_1.createBlock({
  rtArray: buildRichTextObj(headerText),
});

page_meta

The page_meta object lets you quickly set the parent, icon, and cover for a page. Pages can be standalone or within a database.

The parent property's createMeta() method takes an object containing the parent page ID and type, while the icon and cover properties require only a string representing an externally-hosted image file (or single emoji 🤠 in the case of icon).

const page = {
  parent: NotionHelper.page_meta.parent.createMeta({
    id: parentID,
    type: "database",
  }),
  icon: NotionHelper.page_meta.icon.createMeta("🎃"),
  cover: NotionHelper.page_meta.cover.createMeta(
    "https://i.imgur.com/5vSShIw.jpeg"
  ),
};

page_props

The page_props object lets you quickly set the property values of a Notion page. Pages can be standalone or in a database, though standalone pages can only have a title property.

Each property represents a database property type. All writeable properties are supported:

  • Title
  • Rich Text
  • Checkbox
  • Date
  • Email
  • Files
  • Multi-Select
  • Number
  • People
  • Phone Number
  • Relation
  • Select
  • Status
  • URL

Each property's createProp() takes an argument as specified by the Page Properties specification of the Notion API. (E.g. Checkbox props take a boolean, Rich Text props take an array of Rich Text objects, Date props take an ISO-8601 date-time string, etc.)

const page = {
    /* parent, icon, cover */
    properties: {
        Name: NotionHelper.page_props.title.createProp(buildRichTextObj("Flylighter - Notion Web Clipper")),
        Capture Date: NotionHelper.page_props.date.createProp(new Date().toISOString())
        URL: NotionHelper.page_props.url.createProp("https://flylighter.com/")
    }
}

Learn More

If you'd like to learn the Notion API from scratch, start with my free Notion API crash course.

Questions? Ask me on Twitter!