Electron+Vue3 MAC 版日历开发记录(11)——Notion事件获取

1,781 阅读3分钟

这是我参与更文挑战的第11天,活动详情查看: 更文挑战

关于 Notion 的使用,估计大家都不陌生,最近他们专门为 Developer 开放了 API,具体看developers.notion.com/

本项目在开发的时候,也想过如果结合开源,让其他伙伴也用起来,那事件的数据放在哪合适,因为本身事件包含的字段和结构相对复杂,总不能用 Vuex state 去关联。同时,也不想着把大家的数据放到我的服务器数据库中,相对开源项目,大家还是想着独立性更高。

所以,基于以上的思考,再结合之前用过一段时间的 Notion,发现可以以全新的 Notion API,尝试将数据同步到自己的 Notion 中。

使用 Notion API

1. 创建 integration.

  • Go to www.notion.com/my-integrat….
  • Click the "+ New integration" button.
  • Give your integration a name - I chose "Vacation Planner".
  • Select the workspace where you want to install this integration.
  • Click "Submit" to create the integration.
  • Copy the "Internal Integration Token" on the next page and save it somewhere secure, e.g. a password manager.

点下一步会生成一个:Internal Integration Token,这里需要注意的是你的 integrations 是不是公开的。

创建好的个人 Integration 查看链接:www.notion.so/my-integrat…

2. Share a database with your integration

在我们的 workspace 创建一个用于存储事件数据的数据库: /table,然后再点 share 把数据库分享给我们创建的 integration

同时,需要拿到此 table 的 32 位 ID,后面需要用到。

Step 3: 创建数据并获取

根据 FullCalendar 提供的事件 Demo 和字段,我们直接在 Notion table 上模拟几条事件数据:

我们使用 Postman 模拟获取数据:

  curl -X POST 'https://api.notion.com/v1/databases/577b3228cd1*******87d601/query' \
  -H 'Authorization: Bearer secret_OeWua2be357D**********' \
  -H 'Notion-Version: 2021-05-13' \
  -H "Content-Type: application/json"

可以看出,我们拿到的 json 中的 result 已经拿到了这三条数据了。

再打开看每一条数据结构:

{
    "object": "page",
    "id": "72ba9-9b57-4859-9ab3-d7eaf",
    "created_time": "2021-06-11T03:31:41.534Z",
    "last_edited_time": "2021-06-11T14:31:00.000Z",
    "parent": {
        "type": "database_id",
        "database_id": "5778-cd15-4117-8243-0fe601"
    },
    "archived": false,
    "properties": {
        "title": {
            "id": "Whai",
            "type": "rich_text",
            "rich_text": [
                {
                    "type": "text",
                    "text": {
                        "content": "使用 Notion API 存储数据",
                        "link": null
                    },
                    "annotations": {
                        "bold": false,
                        "italic": false,
                        "strikethrough": false,
                        "underline": false,
                        "code": false,
                        "color": "default"
                    },
                    "plain_text": "使用 Notion API 存储数据",
                    "href": null
                }
            ]
        },
        "event_id": {
            "id": "jv^r",
            "type": "number",
            "number": 2
        },
        "end": {
            "id": "p:bR",
            "type": "date",
            "date": {
                "start": "2021-06-12",
                "end": null
            }
        },
        "start": {
            "id": "wh^E",
            "type": "date",
            "date": {
                "start": "2021-06-12",
                "end": null
            }
        },
        "id": {
            "id": "title",
            "type": "title",
            "title": [
                {
                    "type": "text",
                    "text": {
                        "content": "2",
                        "link": null
                    },
                    "annotations": {
                        "bold": false,
                        "italic": false,
                        "strikethrough": false,
                        "underline": false,
                        "code": false,
                        "color": "default"
                    },
                    "plain_text": "2",
                    "href": null
                }
            ]
        }
    }
}

具体根据每个属性的 type 获取对应的值。

4. 代码实现

具体实现,我们看 EventService.ts:

'use strict';
import axios from 'axios';
import wrapper from 'axios-cache-plugin';
export default class EventService {
  async getEvents() {
    const http = wrapper(axios, {
      maxCacheSize: 15,
      ttl: 60000, //ms
    });
    http.__addFilter(/weatherdata/);

    const headers = {
      'Notion-Version': '2021-05-13',
      'Authorization': 'Bearer '+ import.meta.env.VITE_NOTION_KEY
    };

    const res = await http({
      url: import.meta.env.VITE_NOTION_DATABASE_API + import.meta.env.VITE_NOTION_DATABASE_ID + '/query',
      method: 'post',
      headers: headers,
    });

    return this.list2Events(res.data.results);
  }

  // {"id": 5,"title": "Conference","start": "2021-04-11","end": "2021-04-13"},
  list2Events(results: []) {
    const events = results.map((element) => {
      return {
        'id': element.properties.event_id.number,
        'title': element.properties.title.rich_text[0].plain_text,
        'start': element.properties.start.date.start,
        'end': element.properties.end?.date.start,
      }
    });

    return events;
  }
}

以上代码没对异常情况做处理,基本通过正常逻辑将 Notion 数据转为 Event 数据。

显示

有了数据以后,就可以在页面上呈现了,看过之前代码的伙伴肯定不陌生了:

// FullcalendarSub.vue
<template>
  <Fullcalendar
    ref="fullcalendar"
    :events="events"
    :options="calendarOptions"
  />
</template>

...

import EventService from '../../../services/EventService';

...

setup() {
    onMounted(() => {
      eventService.value.getEvents().then((data) => (events.value = data));
    });
    
    const events = ref([]);
    const eventService = ref(new EventService());
    return {
      events,
      eventService,
    };
},

结果显示如下:

小结

今天主要代码功能是:同步 Notion database 数据到日历上呈现。

明天我们继续在客户端创建 Event,并保存到 Notion 上。

所有用到的 Internal Integration Tokendatabase_id 等数据都保存到 .env 里。

未完待续!

这个项目的所有记录基本放进专栏里了,欢迎查看: Electron+Vue3 MAC 版日历开发记录 最近有伙伴问代码链接:代码已同步到 github 上了:github.com/fanly/fanly…