mirror of
https://github.com/jxpeng98/obsidian-to-NotionNext
synced 2026-07-29 16:35:57 +08:00
Compare commits
97 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0f5d2d51b | ||
|
|
a68a3920ad | ||
|
|
76d3fc9872 | ||
|
|
e3fb50b205 | ||
|
|
5411b0bac6 | ||
|
|
f974d6dc66 | ||
|
|
de110334e6 | ||
|
|
d8c8e78625 | ||
|
|
feab049033 | ||
|
|
04d73fdccc | ||
|
|
f4ab15c0d5 | ||
|
|
0bd4427f7a | ||
|
|
221cf62fcc | ||
|
|
7a2610c4b9 | ||
|
|
f9f30df7ea | ||
|
|
1d22f2e741 | ||
|
|
935ecacd2b | ||
|
|
6724399628 | ||
|
|
8fd6f7c701 | ||
|
|
f3e3ccdeb1 | ||
|
|
c65cb6a4df | ||
|
|
7c3028dd63 | ||
|
|
d2a40694e3 | ||
|
|
9f7298a880 | ||
|
|
b8860beb85 | ||
|
|
5e8c8f6f63 | ||
|
|
1887ad8f3d | ||
|
|
517426ea7a | ||
|
|
b6d5ff0093 | ||
|
|
41ebff9067 | ||
|
|
96b83b6da0 | ||
|
|
63ded7d50e | ||
|
|
8ef9a007e3 | ||
|
|
2d57952c38 | ||
|
|
e3a74d61cc | ||
|
|
47e902a6ee | ||
|
|
098110d9ba | ||
|
|
82629c122f | ||
|
|
7be8f1c799 | ||
|
|
df58b7acb6 | ||
|
|
0fedf4e83f | ||
|
|
444ccfcd0f | ||
|
|
05a8b789d9 | ||
|
|
d845dc7945 | ||
|
|
26a326bb0d | ||
|
|
539a2d1731 | ||
|
|
3eb9b0305a | ||
|
|
a6df90dc56 | ||
|
|
46e5477509 | ||
|
|
2364a6c756 | ||
|
|
21133862ff | ||
|
|
68a0796e9b | ||
|
|
058d45e834 | ||
|
|
fdc0b3e756 | ||
|
|
27d88a9b94 | ||
|
|
089dca83bb | ||
|
|
fc0954540a | ||
|
|
f3fe8e7835 | ||
|
|
f60bc598a8 | ||
|
|
0752c5bbd9 | ||
|
|
22f12063e4 | ||
|
|
e2defbd248 | ||
|
|
0b7d5b3435 | ||
|
|
2a4e03e319 | ||
|
|
c0d9f41555 | ||
|
|
bc65eb2781 | ||
|
|
22d2f79612 | ||
|
|
c62482d83b | ||
|
|
bf512fe2a3 | ||
|
|
ae7a9ac6cf | ||
|
|
595935ffae | ||
|
|
cf3129b90b | ||
|
|
6d5ece76b6 | ||
|
|
021584dac6 | ||
|
|
e6fc5e522b | ||
|
|
e6099a94d5 | ||
|
|
04b8ba65de | ||
|
|
43a7165983 | ||
|
|
3740680bdd | ||
|
|
5ac25c3de9 | ||
|
|
8bc84b8d61 | ||
|
|
7aae1b23e9 | ||
|
|
511a3e2289 | ||
|
|
22bf322127 | ||
|
|
4497d9cd7f | ||
|
|
d4aeaaa0f9 | ||
|
|
bf6ef7af0c | ||
|
|
27c8e0f610 | ||
|
|
c9a5c72c6c | ||
|
|
7bc0b43d4f | ||
|
|
d5f908ed34 | ||
|
|
f87e024e77 | ||
|
|
e667bec7e0 | ||
|
|
845cb7bf66 | ||
|
|
7d096e1cfb | ||
|
|
f3346c455e | ||
|
|
208fb40f72 |
26
.github/workflows/CI.yml
vendored
Normal file
26
.github/workflows/CI.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "*"
|
||||||
|
|
||||||
|
env:
|
||||||
|
PLUGIN_NAME: share-to-notionnext
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Use Node.js
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
id: build
|
||||||
|
run: |
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
30
.github/workflows/release.yml
vendored
30
.github/workflows/release.yml
vendored
@@ -6,7 +6,7 @@ on:
|
|||||||
- "*"
|
- "*"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
PLUGIN_NAME: obsidian-to-notion # Change this to match the id of your plugin.
|
PLUGIN_NAME: share-to-notionnext # Change this to match the id of your plugin.
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -34,7 +34,7 @@ jobs:
|
|||||||
id: create_release
|
id: create_release
|
||||||
uses: actions/create-release@v1
|
uses: actions/create-release@v1
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
|
||||||
VERSION: ${{ github.ref }}
|
VERSION: ${{ github.ref }}
|
||||||
with:
|
with:
|
||||||
tag_name: ${{ github.ref }}
|
tag_name: ${{ github.ref }}
|
||||||
@@ -46,7 +46,7 @@ jobs:
|
|||||||
id: upload-zip
|
id: upload-zip
|
||||||
uses: actions/upload-release-asset@v1
|
uses: actions/upload-release-asset@v1
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
|
||||||
with:
|
with:
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
asset_path: ./${{ env.PLUGIN_NAME }}.zip
|
asset_path: ./${{ env.PLUGIN_NAME }}.zip
|
||||||
@@ -57,7 +57,7 @@ jobs:
|
|||||||
id: upload-main
|
id: upload-main
|
||||||
uses: actions/upload-release-asset@v1
|
uses: actions/upload-release-asset@v1
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
|
||||||
with:
|
with:
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
asset_path: ./main.js
|
asset_path: ./main.js
|
||||||
@@ -68,20 +68,20 @@ jobs:
|
|||||||
id: upload-manifest
|
id: upload-manifest
|
||||||
uses: actions/upload-release-asset@v1
|
uses: actions/upload-release-asset@v1
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
|
||||||
with:
|
with:
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
asset_path: ./manifest.json
|
asset_path: ./manifest.json
|
||||||
asset_name: manifest.json
|
asset_name: manifest.json
|
||||||
asset_content_type: application/json
|
asset_content_type: application/json
|
||||||
|
|
||||||
- name: Upload styles.css
|
# - name: Upload styles.css
|
||||||
id: upload-css
|
# id: upload-css
|
||||||
uses: actions/upload-release-asset@v1
|
# uses: actions/upload-release-asset@v1
|
||||||
env:
|
# env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
# GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
|
||||||
with:
|
# with:
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
# upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
asset_path: ./styles.css
|
# asset_path: ./styles.css
|
||||||
asset_name: styles.css
|
# asset_name: styles.css
|
||||||
asset_content_type: text/css
|
# asset_content_type: text/css
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -10,7 +10,7 @@ node_modules
|
|||||||
|
|
||||||
# Don't include the compiled main.js file in the repo.
|
# Don't include the compiled main.js file in the repo.
|
||||||
# They should be uploaded to GitHub releases instead.
|
# They should be uploaded to GitHub releases instead.
|
||||||
# main.js
|
main.js
|
||||||
|
|
||||||
# Exclude sourcemaps
|
# Exclude sourcemaps
|
||||||
*.map
|
*.map
|
||||||
@@ -20,3 +20,4 @@ data.json
|
|||||||
|
|
||||||
# Exclude macOS Finder (System Explorer) View States
|
# Exclude macOS Finder (System Explorer) View States
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.history
|
||||||
23
Message.ts
Normal file
23
Message.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
export const NoticeMsg: {[key: string]:any} = {
|
||||||
|
"en": {
|
||||||
|
"notion-logo": "Share to NotionNext",
|
||||||
|
"sync-success": "Sync to NotionNext success: \n",
|
||||||
|
"sync-fail": "Sync to NotionNext fail: \n",
|
||||||
|
"open-notion": "Please open the file that needs to be synchronized",
|
||||||
|
"config-secrets-notion-api": "Please set up the notion API in the settings tab.",
|
||||||
|
"config-secrets-database-id": "Please set up the database id in the settings tab.",
|
||||||
|
"set-tags-fail": "Set tags fail,please check the frontmatter of the file or close the tag switch in the settings tab.",
|
||||||
|
},
|
||||||
|
"zh": {
|
||||||
|
"notion-logo": "分享到NotionNext",
|
||||||
|
"sync-success": "同步到NotionNext成功:\n",
|
||||||
|
"sync-fail": "同步到NotionNext失败: \n",
|
||||||
|
"open-file": "请打开需要同步的文件",
|
||||||
|
"set-tags-fail": "设置标签失败,请检查文件的frontmatter,或者在插件设置中关闭设置tags开关",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const NoticeMConfig = (lang:any) :any => {
|
||||||
|
return NoticeMsg[lang]
|
||||||
|
}
|
||||||
179
README-zh.md
Normal file
179
README-zh.md
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
# Obsidian share to NotionNext
|
||||||
|
感谢[原作者](https://github.com/EasyChris/obsidian-to-notion)开发出了这么好用的插件,能够将obsidian同步到notion。 但是原仓库只能同步Name和Tags信息,如果像我一样通过[NotionNext](https://github.com/tangly1024/NotionNext)来搭建自己的网页,就有一些局限性。每次导入之后都需要进行大量的修改。
|
||||||
|
|
||||||
|
所以我在[原作者](https://github.com/EasyChris/obsidian-to-notion)的基础之上,增加了匹配[NotionNext](https://github.com/tangly1024/NotionNext)模板的功能。这样可以直接在Obsidian编辑,整理好之后一键发布。
|
||||||
|
|
||||||
|
## 使用方式
|
||||||
|
### 注意事项
|
||||||
|
本插件现在暂时只能用于匹配[NotionNext](https://github.com/tangly1024/NotionNext)。如果你不是使用这个模板,你只会无限返回`error 400`.
|
||||||
|
|
||||||
|
所以没有NotionNext需求的,请使用原作者的[Obsidian-to-notion](https://github.com/EasyChris/obsidian-to-notion)
|
||||||
|
|
||||||
|
### 准备安装
|
||||||
|
在安装插件之前,你必须配置好了以下内容:
|
||||||
|
|
||||||
|
1. 你的NotionNext数据库。
|
||||||
|
2. 根据原作者的readme.md,配置好了Notion API,并且已经和你的NotionNext仓库关联。
|
||||||
|
3. NotionNext Database ID
|
||||||
|
4. 你的NotionNext数据库有如下内容:
|
||||||
|
- type
|
||||||
|
- title
|
||||||
|
- slug
|
||||||
|
- category
|
||||||
|
- tags
|
||||||
|
- date
|
||||||
|
- status
|
||||||
|
- summary
|
||||||
|
- password
|
||||||
|
- icon
|
||||||
|
|
||||||
|
**如果你是直接复制的NotionNext的模板,这些内容应该已经有了。我在原作者的基础之上对本插件的内容进行了更改,所以你只需要保证你的数据库有如上内容,并且所有的字母都是小写!!!**
|
||||||
|
|
||||||
|
|
||||||
|
**⚠️⚠️⚠️:表头全部小写!!!顺序无所谓!**
|
||||||
|
|
||||||
|
### 安装插件
|
||||||
|
1. 关闭Obsidian
|
||||||
|
2. 从Release下载插件文件,解压到你的obsidian插件目录下。
|
||||||
|
3. 重新打开Obsidian,进入设置,启用插件。
|
||||||
|
4. 在设置中,找到Obsidian to NotionNext,填入你的NotionNext Database ID 和 API token。
|
||||||
|
|
||||||
|
### 使用插件
|
||||||
|
在仓库中我上传了一个模板,你可以直接复制到你的模板文件夹中。然后使用Obsidian的模板功能一键生成新笔记。
|
||||||
|
|
||||||
|
如果你不想使用模板,你也可以直接在Obsidian中创建一个新的文件,然后复制下边的内容。然后保存。
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
type: Post # Post or Page, the default is Post
|
||||||
|
slug: test # slug for url, the default is
|
||||||
|
stats: Draft # Draft, Invisible, Published
|
||||||
|
category: test
|
||||||
|
summary: this is a summary for test post
|
||||||
|
icon: fa-solid fa-camera # you can ignore this
|
||||||
|
password: "1234" # if you donot want to set password, you can delete this line
|
||||||
|
tags:
|
||||||
|
- test # tags for post
|
||||||
|
- web # add more tags if you want
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
Contents Below
|
||||||
|
|
||||||
|
```
|
||||||
|
模板使用如下:
|
||||||
|

|
||||||
|
|
||||||
|
**插件预览如下**
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**以下为原README.md**
|
||||||
|
|
||||||
|
非常感谢原作者的开发,我只是在原作者的基础之上进行了修改,增加了一些功能。如果你觉得这个插件对你有帮助,可以给[原作者](https://github.com/EasyChris/obsidian-to-notion)一个star。
|
||||||
|
|
||||||
|
# Obsidian to Notion
|
||||||
|
[](https://github.com/Easychris/obsidian-to-notion/actions/workflows/CI.yml)
|
||||||
|
[](https://github.com/Easychris/obsidian-to-notion/actions/workflows/release.yml)
|
||||||
|
[](https://raw.githubusercontent.com/EasyChris/obsidian-to-notion/master/LICENSE)
|
||||||
|
[](https://GitHub.com/Easychris/obsidian-to-notion/releases/)
|
||||||
|
[](https://github.com/Easychris/obsidian-to-notion/releases)
|
||||||
|
|
||||||
|
Obsidian share to Notion [English](README.md)
|
||||||
|
|
||||||
|
将obsidian文件一键分享到Notion,并在obsidian中添加Notion分享链接
|
||||||
|
|
||||||
|
如果能对你有所帮助,欢迎给一个star支持。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# 使用方式
|
||||||
|
## 安装插件
|
||||||
|
|
||||||
|
### 市场下载
|
||||||
|
插件市场搜索 noiton 即可下载
|
||||||
|
|
||||||
|

|
||||||
|
### BRAT
|
||||||
|
插件中中心搜索 BRAT
|
||||||
|
添加 `EasyChris/obsidian-to-notion` 到 BRAT 插件安装列表中
|
||||||
|
返回插件中心启用即可
|
||||||
|
### 手动安装
|
||||||
|
```
|
||||||
|
cd YOUR_OBSIDIAN_FOLDER/.obsidian/plugins/
|
||||||
|
git clone https://github.com/EasyChris/obsidian-to-notion.git
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 申请 Notion API
|
||||||
|
官方参考文档:[https://developers.notion.com/docs](https://developers.notion.com/docs)
|
||||||
|
### 第 1 步:创建integration。
|
||||||
|
转到 [https://www.notion.com/my-integrations](https://www.notion.com/my-integrations)
|
||||||
|
创建完成之后,复制`secrets toekn`
|
||||||
|

|
||||||
|
|
||||||
|
### 第2步:与你的集成共享一个数据库
|
||||||
|
新建一个的page(权限为公开)
|
||||||
|
在page中新建一个数据库 -> 需要`full page database`
|
||||||
|

|
||||||
|
|
||||||
|
将`integration`添加到你的新建的数据库中
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### 注意
|
||||||
|
|
||||||
|
数据库的第一个自定义名称必须是 "Name",否则同步会失败。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 第三步:复制database ID
|
||||||
|
|
||||||
|
```
|
||||||
|
https://www.notion.so/myworkspace/a8aec43384f447ed84390e8e42c2e089?v=...
|
||||||
|
|--------- Database ID --------|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 打开插件配置
|
||||||
|
将得到的 `NOTION_API_KEY` 和 `DATABASE_ID`填入配置当中
|
||||||
|

|
||||||
|
|
||||||
|
## 上传文件内容到notion
|
||||||
|
点击上传notion的按钮
|
||||||
|

|
||||||
|
上传成功之后会自动生成一个分享链接
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## 页面 Banner 链接[可选]
|
||||||
|
默认可以不填写
|
||||||
|
横幅URL必须是图像URL,例如:https://i.imgur.com/xxx.jpg
|
||||||
|
|
||||||
|
## Notion ID [可选]
|
||||||
|
Notion ID是你想分享文件的页面ID。
|
||||||
|
如果你不写它,notion将分享到默认的链接,如:https://www.notion.so/myworkspace/a8aec43384f447ed84390,访问这个页面将重定向到你的网站页面。
|
||||||
|
如果你写了Notion ID,它将分享到页面链接如:https://your_user_name.notion.site/myworkspace/a8aec43384f447ed84390。不需要重定向网址。
|
||||||
|
|
||||||
|
## 同步图片
|
||||||
|
|
||||||
|
使用 [Obsidian Image Auto Upload Plugin](https://github.com/renmu123/obsidian-image-auto-upload-plugin) 插件,配置你自己的 cos 或者 oss,将图片存储到你自己的云存储,然后在 obsidian 中使用图片链接即可。该插件会自动帮你上传图片,并替换成链接。
|
||||||
|
|
||||||
|
# 请我喝杯咖啡
|
||||||
|
|
||||||
|
[顿顿饭](https://dun.mianbaoduo.com/@easy)
|
||||||
|
|
||||||
|
# 感谢
|
||||||
|
[开发流程 | Obsidian 插件开发文档](https://luhaifeng666.github.io/obsidian-plugin-docs-zh/zh/getting-started/development-workflow.html)
|
||||||
|
|
||||||
|
[GitHub - devbean/obsidian-wordpress: An obsidian plugin for publishing docs to WordPress.](https://github.com/devbean/obsidian-wordpress)
|
||||||
|
|
||||||
|
[GitHub - obsidianmd/obsidian-api](https://github.com/obsidianmd/obsidian-api)
|
||||||
|
|
||||||
|
[GitHub - zhaohongxuan/obsidian-weread-plugin: Obsidian Weread Plugin is an plugin to sync Weread(微信读书) hightlights and annotations into your Obsidian Vault.](https://github.com/zhaohongxuan/obsidian-weread-plugin)
|
||||||
252
README.md
252
README.md
@@ -1,40 +1,146 @@
|
|||||||
Obsidian share to Notion
|
# Obsidian to NotionNext
|
||||||
|
[中文文档](README-zh.md)
|
||||||
|
|
||||||
将obsidian文件一键分享到Notion,并在obsidian中添加Notion分享链接
|
Thanks to the [original author](https://github.com/EasyChris/obsidian-to-notion) for developing such a useful plugin that can synchronize Obsidian to Notion. However, the original repository can only sync Name and Tags information. For those like me who use [NotionNext](https://github.com/tangly1024/NotionNext) to set up their website, this presents some limitations. Every time I import, I need to make a lot of modifications.
|
||||||
|
|
||||||
|
Thus, based on the [original author's work](https://github.com/EasyChris/obsidian-to-notion), I've added a feature to match the [NotionNext](https://github.com/tangly1024/NotionNext) template. This way, you can edit directly in Obsidian and publish with a single click after organizing.
|
||||||
|
|
||||||
|
## How to Use
|
||||||
|
### Precautions
|
||||||
|
For now, this plugin is exclusively for [NotionNext](https://github.com/tangly1024/NotionNext). If you're not using this template, you'll keep receiving `error 400`.
|
||||||
|
|
||||||
|
For those without a NotionNext requirement, please use the original [Obsidian-to-notion](https://github.com/EasyChris/obsidian-to-notion).
|
||||||
|
|
||||||
|
### Pre-Installation Steps
|
||||||
|
Before installing the plugin, you must have set up the following:
|
||||||
|
1. Your NotionNext database.
|
||||||
|
2. According to the original author's readme.md, set up the Notion API, and it should already be associated with your NotionNext repository.
|
||||||
|
3. NotionNext Database ID
|
||||||
|
4. Your NotionNext database should have the following contents:
|
||||||
|
- type
|
||||||
|
- title
|
||||||
|
- slug
|
||||||
|
- category
|
||||||
|
- tags
|
||||||
|
- date
|
||||||
|
- status
|
||||||
|
- summary
|
||||||
|
- password
|
||||||
|
- icon
|
||||||
|
|
||||||
|
**If you've directly copied the NotionNext template, these contents should already exist. I've made changes to this plugin based on the original author's work. All you need to ensure is that your database has the above content, and every letter is in lowercase!!!**
|
||||||
|
|
||||||
|
**⚠️⚠️⚠️: All headers are in lowercase!!! The order doesn't matter!**
|
||||||
|
|
||||||
|
### Plugin Installation
|
||||||
|
1. Close Obsidian.
|
||||||
|
2. Download the plugin file from Release and unzip it into your Obsidian plugin directory.
|
||||||
|
3. Re-open Obsidian, go to settings, and enable the plugin.
|
||||||
|
4. In the settings, find Obsidian to NotionNext, and enter your NotionNext Database ID and API token.
|
||||||
|
|
||||||
|
### How to Use
|
||||||
|
### Using the Plugin
|
||||||
|
In the repository, I have uploaded a template which you can directly copy into your template folder. After that, use Obsidian's template feature to create a new note with one click.
|
||||||
|
|
||||||
|
If you don't want to use the template, you can also directly create a new file in Obsidian and then copy the content below. Then save it.
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
type: Post # Post or Page, the default is Post
|
||||||
|
slug: test # slug for url, the default is
|
||||||
|
stats: Draft # Draft, Invisible, Published
|
||||||
|
category: test
|
||||||
|
summary: this is a summary for test post
|
||||||
|
icon: fa-solid fa-camera # you can ignore this
|
||||||
|
password: "1234" # if you donot want to set password, you can delete this line
|
||||||
|
tags:
|
||||||
|
- test # tags for post
|
||||||
|
- web # add more tags if you want
|
||||||
|
---
|
||||||
|
|
||||||
|
Contents Below
|
||||||
|
```
|
||||||
|
Usage of the template is as follows:
|
||||||
|

|
||||||
|
|
||||||
|
**Plugin preview is shown below**
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Original README.md**
|
||||||
|
|
||||||
|
Many Thanks for the original author's work. I've only made some changes to the original author's work. If you find this plugin useful, please give the [original author](https://github.com/EasyChris/obsidian-to-notion) a star.
|
||||||
|
|
||||||
|
# Obsidian to Notion
|
||||||
|
[](https://github.com/Easychris/obsidian-to-notion/actions/workflows/CI.yml)
|
||||||
|
[](https://github.com/Easychris/obsidian-to-notion/actions/workflows/release.yml)
|
||||||
|
[](https://raw.githubusercontent.com/EasyChris/obsidian-to-notion/master/LICENSE)
|
||||||
|
[](https://GitHub.com/Easychris/obsidian-to-notion/releases/)
|
||||||
|
[](https://github.com/Easychris/obsidian-to-notion/releases)
|
||||||
|
|
||||||
|
|
||||||
|
Share of obsidian to Notion [中文文档](README-zh.md)
|
||||||
|
|
||||||
|
Sharing files from Obsidian to Notion with a single click, and Obsidian will automatically add the Notion share link
|
||||||
|
|
||||||
|
You are welcome to offer it a star if it can benefit you.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
# 使用方式
|
# TODO
|
||||||
## 安装插件
|
### [TODO Board](https://github.com/users/EasyChris/projects/3/views/1)
|
||||||
|
- [x] support for custom page banner
|
||||||
|
- [x] update the exsit page
|
||||||
|
- [x] support for mult language
|
||||||
|
- [x] support for auto copy the share link to clipboard
|
||||||
|
- [x] support for mobile
|
||||||
|
- [x] support tags thank for [@jannikbuscha](https://github.com/jannikbuscha)
|
||||||
|
- [ ] transfer the bi-link format like [[]] into the format that Notion supports.
|
||||||
|
|
||||||
|
|
||||||
|
# How to use
|
||||||
|
## Install the plugin
|
||||||
|
|
||||||
|
### Marketplace download
|
||||||
|
Open obsidian setting -> Add plugin -> Search -> notion
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
### BRAT
|
### BRAT
|
||||||
插件中中心搜索 BRAT
|
Enter `BRAT` into the plugin market center to find it.
|
||||||
添加 `EasyChris/obsidian-to-notion` 到 BRAT 插件安装列表中
|
Add `EasyChris/obsidian-to-notion` to the list of BRAT plugins that have been installed.
|
||||||
返回插件中心启用即可
|
Return to the plugin center and turn it on.
|
||||||
### 手动安装
|
### Manual installation
|
||||||
```
|
```
|
||||||
cd YOUR_OBSIDIAN_FOLDER/.obsidian/plugins/
|
cd YOUR_OBSIDIAN_FOLDER/.obsidian/plugins/
|
||||||
git clone https://github.com/EasyChris/obsidian-to-notion.git
|
git clone https://github.com/EasyChris/obsidian-to-notion.git
|
||||||
```
|
```
|
||||||
### 市场下载
|
|
||||||
因为暂时还未上架,所以请通过BRAT安装
|
|
||||||
|
|
||||||
## 申请 Notion API
|
|
||||||
官方参考文档:[https://developers.notion.com/docs](https://developers.notion.com/docs)
|
## Apply Notion API
|
||||||
### 第 1 步:创建integration。
|
Official reference documentation: [https://developers.notion.com/docs](https://developers.notion.com/docs)
|
||||||
转到 [https://www.notion.com/my-integrations](https://www.notion.com/my-integrations)
|
### Step 1: Create integration.
|
||||||
创建完成之后,复制`secrets toekn`
|
Go to [https://www.notion.com/my-integrations](https://www.notion.com/my-integrations)
|
||||||
|
Once created, copy `secrets toekn`
|
||||||

|

|
||||||
|
|
||||||
### 第2步:与你的集成共享一个数据库
|
#### Note:
|
||||||
新建一个的page(权限为公开)
|
database first custom name must be "Name", otherwise sync to notion will be failed
|
||||||
在page中新建一个数据库 -> 需要`full page database`
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Step 2: Share a database with your integration
|
||||||
|
Create a new page (with public permissions)
|
||||||
|
Create a new database in the page -> you need `full page database`
|
||||||

|

|
||||||
|
|
||||||
将`integration`添加到你的新建的数据库中
|
Add `integration` to your new database
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### 第三步:复制database ID
|
### Step 3: Copy the database ID
|
||||||
|
|
||||||
```
|
```
|
||||||
https://www.notion.so/myworkspace/a8aec43384f447ed84390e8e42c2e089?v=...
|
https://www.notion.so/myworkspace/a8aec43384f447ed84390e8e42c2e089?v=...
|
||||||
@@ -44,26 +150,110 @@ https://www.notion.so/myworkspace/a8aec43384f447ed84390e8e42c2e089?v=...
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 打开插件配置
|
## Open the plugin configuration
|
||||||
将得到的 `NOTION_API_KEY` 和 `DATABASE_ID`填入配置当中
|
Fill the configuration with the `NOTION_API_KEY` and `DATABASE_ID` you got
|
||||||

|

|
||||||
|
|
||||||
## 上传文件内容到notion
|
## Upload file content to notion
|
||||||
点击上传notion的按钮
|
Click the upload notion button
|
||||||

|

|
||||||
上传成功之后会自动生成一个分享链接
|
A share link will be automatically generated after successful upload
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
# 请我喝杯咖啡
|
## Banner URL [option]
|
||||||
|
Banner url must be a image url like: https://i.imgur.com/xxx.jpg
|
||||||
|
If you don't want to use banner, leave it blank
|
||||||
|
|
||||||
[顿顿饭](https://dun.mianbaoduo.com/@easy)
|
|
||||||
|
|
||||||
# 感谢
|
## Convert Tags [option]
|
||||||
[开发流程 | Obsidian 插件开发文档](https://luhaifeng666.github.io/obsidian-plugin-docs-zh/zh/getting-started/development-workflow.html)
|
Transfer the Obsidian tags to the Notion table.
|
||||||
|
It requires the column with the name 'Tags'.
|
||||||
|

|
||||||
|
|
||||||
|
Add tags to your notion page
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
* open plugin convert tags
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
* add tags in the head
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
tags: [tag1,tag2]
|
||||||
|
---
|
||||||
|
|
||||||
|
this is test tags
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
tags:
|
||||||
|
- tag4
|
||||||
|
---
|
||||||
|
|
||||||
|
this is test tags
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Thanks for [@jannikbuscha](https://github.com/jannikbuscha) contribution
|
||||||
|
|
||||||
|
|
||||||
|
## Notion ID [option]
|
||||||
|
Notion ID is the your notion site ID that you want to share the file to.
|
||||||
|
if you don't write it, notion will share to the default link like:
|
||||||
|
https://www.notion.so/myworkspace/a8aec43384f447ed84390
|
||||||
|
that visit this page need to redirect to your site url
|
||||||
|
if you write the Notion ID, it will share to the page link like:
|
||||||
|
https://your_user_name.notion.site/myworkspace/a8aec43384f447ed84390.
|
||||||
|
The visiter don't need to redirect url.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Sync image to Notion
|
||||||
|
|
||||||
|
To sync images to your oss or cos bucket, use the [Obsidian Image Auto Upload Plugin](https://github.com/renmu123/obsidian-image-auto-upload-plugin).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Development
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/EasyChris/obsidian-to-notion.git
|
||||||
|
yarn install
|
||||||
|
yarn dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Release
|
||||||
|
|
||||||
|
```
|
||||||
|
node update-version.js
|
||||||
|
./release.sh
|
||||||
|
```
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Thanks
|
||||||
|
[Development Process | Obsidian Plugin Development Documentation](https://luhaifeng666.github.io/obsidian-plugin-docs-zh/zh/getting-started/development-workflow.html)
|
||||||
|
|
||||||
[GitHub - devbean/obsidian-wordpress: An obsidian plugin for publishing docs to WordPress.](https://github.com/devbean/obsidian-wordpress)
|
[GitHub - devbean/obsidian-wordpress: An obsidian plugin for publishing docs to WordPress.](https://github.com/devbean/obsidian-wordpress)
|
||||||
|
|
||||||
[GitHub - obsidianmd/obsidian-api](https://github.com/obsidianmd/obsidian-api)
|
[GitHub - obsidianmd/obsidian-api](https://github.com/obsidianmd/obsidian-api)
|
||||||
|
|
||||||
[GitHub - zhaohongxuan/obsidian-weread-plugin: Obsidian Weread Plugin is an plugin to sync Weread(微信读书) hightlights and annotations into your Obsidian Vault.](https://github.com/zhaohongxuan/obsidian-weread-plugin)
|
[GitHub - Easychris/obsidian-to-notion: Obsidian Weread Plugin is an plugin to sync Weread(微信读书) hightlights and annotations into your Obsidian Vault.](https://github.dev/zhaohongxuan/obsidian-weread-plugin)
|
||||||
|
|
||||||
|
[GitHub - Quorafind/Obsidian-Memos: A quick capture plugin for Obsidian, all data from your notes.](https://github.com/Quorafind/Obsidian-Memos)
|
||||||
|
|
||||||
|
[https://github.com/jannikbuscha/obsidian-to-notion](https://github.com/jannikbuscha)
|
||||||
|
|
||||||
|
# License
|
||||||
|
GNU GPLv3
|
||||||
|
|||||||
155
Upload2Notion.ts
155
Upload2Notion.ts
@@ -1,11 +1,9 @@
|
|||||||
import { requestUrl } from "obsidian";
|
import { Notice, requestUrl,TFile,normalizePath, App } from "obsidian";
|
||||||
import { Client } from "@notionhq/client";
|
import { Client } from "@notionhq/client";
|
||||||
import { markdownToBlocks, } from "@tryfabric/martian";
|
import { markdownToBlocks, } from "@tryfabric/martian";
|
||||||
import * as fs from "fs";
|
|
||||||
import * as yamlFrontMatter from "yaml-front-matter";
|
import * as yamlFrontMatter from "yaml-front-matter";
|
||||||
import * as yaml from "yaml"
|
import * as yaml from "yaml"
|
||||||
import MyPlugin from "main";
|
import MyPlugin from "main";
|
||||||
|
|
||||||
export class Upload2Notion {
|
export class Upload2Notion {
|
||||||
app: MyPlugin;
|
app: MyPlugin;
|
||||||
notion: Client;
|
notion: Client;
|
||||||
@@ -13,24 +11,119 @@ export class Upload2Notion {
|
|||||||
constructor(app: MyPlugin) {
|
constructor(app: MyPlugin) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
}
|
||||||
async createPage(title:string, childArr: any) {
|
|
||||||
const bodyString = {
|
async deletePage(notionID:string){
|
||||||
|
const response = await requestUrl({
|
||||||
|
url: `https://api.notion.com/v1/blocks/${notionID}`,
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': 'Bearer ' + this.app.settings.notionAPI,
|
||||||
|
'Notion-Version': '2022-06-28',
|
||||||
|
},
|
||||||
|
body: ''
|
||||||
|
})
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 因为需要解析notion的block进行对比,非常的麻烦,
|
||||||
|
// 暂时就直接删除,新建一个page
|
||||||
|
async updatePage(notionID:string, title:string, allowTags:boolean, tags:string[], type:string, slug:string, stats:string, category:string, summary:string, paword:string, favicon:string, datetime:string, childArr:any) {
|
||||||
|
await this.deletePage(notionID)
|
||||||
|
const res = await this.createPage(title, allowTags, tags, type, slug, stats, category, summary, paword, favicon, datetime, childArr)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
async createPage(title:string, allowTags:boolean, tags:string[], type:string, slug:string, stats:string, category:string, summary:string, pawrod:string, favicon:string, datetime:string, childArr: any) {
|
||||||
|
const bodyString:any = {
|
||||||
parent: {
|
parent: {
|
||||||
database_id: this.app.settings.databaseID
|
database_id: this.app.settings.databaseID
|
||||||
},
|
},
|
||||||
properties: {
|
properties: {
|
||||||
Name: {
|
title: {
|
||||||
title: [
|
title: [
|
||||||
{
|
{
|
||||||
text: {
|
text: {
|
||||||
content: title,
|
content: title
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
tags: {
|
||||||
|
multi_select: allowTags && tags !== undefined ? tags.map(tag => {
|
||||||
|
return {"name": tag}
|
||||||
|
}) : [],
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
select: {
|
||||||
|
name: type || 'Post'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
slug: {
|
||||||
|
rich_text: [
|
||||||
|
{
|
||||||
|
text: {
|
||||||
|
content: slug || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
select: {
|
||||||
|
name: stats || 'Draft'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category: {
|
||||||
|
select: {
|
||||||
|
name: category || 'Obsidian'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
summary: {
|
||||||
|
rich_text: [
|
||||||
|
{
|
||||||
|
text: {
|
||||||
|
content: summary || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
rich_text: [
|
||||||
|
{
|
||||||
|
text: {
|
||||||
|
content: pawrod || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
rich_text: [
|
||||||
|
{
|
||||||
|
text: {
|
||||||
|
content: favicon || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
date: {
|
||||||
|
date: {
|
||||||
|
start: datetime || new Date().toISOString()
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
children: childArr,
|
children: childArr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.app.settings.bannerUrl) {
|
||||||
|
bodyString.cover = {
|
||||||
|
type: "external",
|
||||||
|
external: {
|
||||||
|
url: this.app.settings.bannerUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
const response = await requestUrl({
|
const response = await requestUrl({
|
||||||
url: `https://api.notion.com/v1/pages`,
|
url: `https://api.notion.com/v1/pages`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -38,28 +131,53 @@ export class Upload2Notion {
|
|||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
// 'User-Agent': 'obsidian.md',
|
// 'User-Agent': 'obsidian.md',
|
||||||
'Authorization': 'Bearer ' + this.app.settings.notionAPI,
|
'Authorization': 'Bearer ' + this.app.settings.notionAPI,
|
||||||
'Notion-Version': '2021-08-16',
|
'Notion-Version': '2022-06-28',
|
||||||
},
|
},
|
||||||
body: JSON.stringify(bodyString),
|
body: JSON.stringify(bodyString),
|
||||||
})
|
})
|
||||||
return response;
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
new Notice(`network error ${error}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async syncMarkdownToNotion(title:string, markdown: string, fullPath:string): Promise<any> {
|
async syncMarkdownToNotion(title:string, allowTags:boolean, tags:string[], type:string, slug:string, stats:string, category:string, summary:string, paword:string, favicon:string, datetime:string, markdown: string, nowFile: TFile, app:App, settings:any): Promise<any> {
|
||||||
|
let res:any
|
||||||
const yamlObj:any = yamlFrontMatter.loadFront(markdown);
|
const yamlObj:any = yamlFrontMatter.loadFront(markdown);
|
||||||
const __content = yamlObj.__content
|
const __content = yamlObj.__content
|
||||||
const file2md = markdownToBlocks(__content);
|
const file2Block = markdownToBlocks(__content);
|
||||||
const res = await this.createPage(title, file2md);
|
const frontmasster =await app.metadataCache.getFileCache(nowFile)?.frontmatter
|
||||||
|
const notionID = frontmasster ? frontmasster.notionID : null
|
||||||
|
|
||||||
|
if(notionID){
|
||||||
|
res = await this.updatePage(notionID, title, allowTags, tags, type, slug, stats, category, summary, paword, favicon, datetime, file2Block);
|
||||||
|
} else {
|
||||||
|
res = await this.createPage(title, allowTags, tags, type, slug, stats, category, summary, paword, favicon, datetime, file2Block);
|
||||||
|
}
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
this.updateYamlInfo(markdown, fullPath, res)
|
await this.updateYamlInfo(markdown, nowFile, res, app, settings)
|
||||||
|
} else {
|
||||||
|
new Notice(`${res.text}`)
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateYamlInfo(yamlContent: string, fullPath: string, res: any) {
|
async updateYamlInfo(yamlContent: string, nowFile: TFile, res: any,app:App, settings:any) {
|
||||||
const yamlObj:any = yamlFrontMatter.loadFront(yamlContent);
|
const yamlObj:any = yamlFrontMatter.loadFront(yamlContent);
|
||||||
const {url} = res.json
|
let {url, id} = res.json
|
||||||
|
// replace www to notionID
|
||||||
|
const {notionID} = settings;
|
||||||
|
if(notionID!=="") {
|
||||||
|
// replace url str "www" to notionID
|
||||||
|
url = url.replace("www.notion.so", `${notionID}.notion.site`)
|
||||||
|
}
|
||||||
yamlObj.link = url;
|
yamlObj.link = url;
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(url)
|
||||||
|
} catch (error) {
|
||||||
|
new Notice(`复制链接失败,请手动复制${error}`)
|
||||||
|
}
|
||||||
|
yamlObj.notionID = id;
|
||||||
const __content = yamlObj.__content;
|
const __content = yamlObj.__content;
|
||||||
delete yamlObj.__content
|
delete yamlObj.__content
|
||||||
const yamlhead = yaml.stringify(yamlObj)
|
const yamlhead = yaml.stringify(yamlObj)
|
||||||
@@ -68,9 +186,10 @@ export class Upload2Notion {
|
|||||||
// if __content have start \n remove it
|
// if __content have start \n remove it
|
||||||
const __content_remove_n = __content.replace(/^\n/, '')
|
const __content_remove_n = __content.replace(/^\n/, '')
|
||||||
const content = '---\n' +yamlhead_remove_n +'\n---\n' + __content_remove_n;
|
const content = '---\n' +yamlhead_remove_n +'\n---\n' + __content_remove_n;
|
||||||
|
try {
|
||||||
//write content fo file
|
await nowFile.vault.modify(nowFile, content)
|
||||||
fs.writeFileSync(fullPath, content);
|
} catch (error) {
|
||||||
return res
|
new Notice(`write file error ${error}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
doc/10.png
Normal file
BIN
doc/10.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
7
icon.ts
7
icon.ts
@@ -2,11 +2,8 @@ import { addIcon } from 'obsidian';
|
|||||||
|
|
||||||
const icons: Record<string, string> = {
|
const icons: Record<string, string> = {
|
||||||
'notion-logo': `
|
'notion-logo': `
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px" viewBox="0 0 100 100" version="1.1">
|
<!-- License: Apache. Made by lawnchairlauncher: https://github.com/lawnchairlauncher/lawnicons -->
|
||||||
<g id="surface1">
|
<svg width="100px" height="100px" viewBox="0 0 192 192" xmlns="http://www.w3.org/2000/svg" fill="none"><path fill="#000000" fill-rule="evenodd" d="m138.462 21.522 27.784 19.588.044.033.275.201c1.713 1.256 3.349 2.455 4.452 3.83 1.411 1.76 1.884 3.644 1.884 5.877v104.706c0 3.587-.635 7.178-3.058 9.934-2.451 2.789-6.145 4.067-10.732 4.394l-.018.001-98.629 5.971-.021.001c-3.242.154-6.094.035-8.669-.907-2.688-.984-4.719-2.727-6.604-5.129l-.01-.012-19.979-25.979-.012-.017c-3.81-5.086-5.723-9.348-5.723-14.509V34.509c0-3.12.688-6.394 2.745-9.033 2.124-2.727 5.356-4.328 9.503-4.686l.058-.005 84.854-4.344c5.192-.445 8.938-.576 12.286.185 3.459.787 6.208 2.452 9.57 4.896ZM56.43 157.336h.002v3.3c0 1.904.47 2.337.613 2.452.296.235 1.203.652 3.642.518l97.449-5.371c1.928-.106 2.256-.649 2.348-.801l.005-.008c.29-.476.486-1.407.486-3.357V60.001c0-1.635-.334-2.218-.421-2.327l-.005-.007-.002-.003-.006-.002a.117.117 0 0 1-.012-.004c-.053-.019-.263-.078-.724-.037l-.057.005-101.622 5.668c-.624.056-.973.163-1.152.242-.142.062-.173.104-.181.116l-.002.002c-.066.085-.36.586-.36 2.321v91.361Zm9.085-106.705 87.074-4.506-21.028-15.375-.039-.031c-1.259-.98-2.507-1.854-4.12-2.46-1.588-.597-3.695-.993-6.669-.734l-.05.005-87.009 4.898h-.01a6.453 6.453 0 0 0-.893.116L49.934 48.56c2.037 1.646 3.109 2.146 4.337 2.367 1.538.277 3.52.167 7.722-.115l3.522-.237v.056Zm-34.231-3.586v83.893c0 .538.175 1.061.498 1.49l13.174 17.464V61.224a2.47 2.47 0 0 0-.877-1.889l-.08-.068-12.715-12.222Zm109.871 35.062c.451 2.04 0 4.082-2.041 4.315l-3.393.673v49.881c-2.947 1.586-5.66 2.492-7.927 2.492-3.622 0-4.528-1.134-7.239-4.53l-.003-.003L98.36 100.02v33.78l7.02 1.59s0 4.082-5.664 4.082l-15.615.906c-.455-.91 0-3.176 1.582-3.627l4.078-1.131V90.955l-5.66-.459c-.454-2.04.677-4.987 3.85-5.216l16.754-1.128 23.09 35.367V88.231l-5.885-.677c-.455-2.499 1.356-4.315 3.618-4.536l15.627-.91v-.001Z" clip-rule="evenodd"/></svg>
|
||||||
<path style=" stroke:none;fill-rule:evenodd;fill:currentColor;fill-opacity:1;" d="M 18.738281 17.796875 C 21.832031 20.308594 22.996094 20.117188 28.804688 19.730469 L 83.582031 16.441406 C 84.746094 16.441406 83.78125 15.28125 83.390625 15.089844 L 74.292969 8.511719 C 72.550781 7.160156 70.230469 5.609375 65.777344 5.996094 L 12.734375 9.867188 C 10.800781 10.058594 10.414062 11.023438 11.183594 11.800781 Z M 22.027344 30.5625 L 22.027344 88.199219 C 22.027344 91.296875 23.574219 92.457031 27.058594 92.265625 L 87.261719 88.78125 C 90.746094 88.589844 91.136719 86.457031 91.136719 83.941406 L 91.136719 26.691406 C 91.136719 24.179688 90.167969 22.824219 88.035156 23.019531 L 25.125 26.691406 C 22.800781 26.886719 22.027344 28.046875 22.027344 30.5625 Z M 81.460938 33.652344 C 81.84375 35.398438 81.460938 37.136719 79.714844 37.332031 L 76.8125 37.910156 L 76.8125 80.460938 C 74.292969 81.816406 71.972656 82.589844 70.035156 82.589844 C 66.9375 82.589844 66.164062 81.621094 63.839844 78.722656 L 44.867188 48.9375 L 44.867188 77.753906 L 50.871094 79.109375 C 50.871094 79.109375 50.871094 82.589844 46.027344 82.589844 L 32.675781 83.363281 C 32.285156 82.589844 32.675781 80.65625 34.027344 80.269531 L 37.511719 79.304688 L 37.511719 41.199219 L 32.675781 40.8125 C 32.285156 39.070312 33.253906 36.558594 35.964844 36.363281 L 50.292969 35.398438 L 70.035156 65.570312 L 70.035156 38.878906 L 65.003906 38.300781 C 64.617188 36.171875 66.164062 34.625 68.097656 34.433594 Z M 8.28125 4.644531 L 63.453125 0.582031 C 70.230469 0 71.972656 0.390625 76.230469 3.484375 L 93.84375 15.859375 C 96.75 17.988281 97.71875 18.570312 97.71875 20.890625 L 97.71875 88.78125 C 97.71875 93.035156 96.167969 95.550781 90.75 95.9375 L 26.675781 99.804688 C 22.609375 100 20.671875 99.421875 18.542969 96.710938 L 5.574219 79.882812 C 3.25 76.785156 2.28125 74.46875 2.28125 71.757812 L 2.28125 11.410156 C 2.28125 7.933594 3.832031 5.03125 8.28125 4.644531 Z M 8.28125 4.644531 "/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
`
|
`
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
183
main.ts
183
main.ts
@@ -1,8 +1,5 @@
|
|||||||
import { timingSafeEqual } from "crypto";
|
|
||||||
import {
|
import {
|
||||||
App,
|
App,
|
||||||
EditableFileView,
|
|
||||||
requestUrl,
|
|
||||||
Editor,
|
Editor,
|
||||||
MarkdownView,
|
MarkdownView,
|
||||||
Modal,
|
Modal,
|
||||||
@@ -12,50 +9,56 @@ import {
|
|||||||
Setting,
|
Setting,
|
||||||
normalizePath
|
normalizePath
|
||||||
} from "obsidian";
|
} from "obsidian";
|
||||||
import { join } from "path";
|
|
||||||
import * as fs from "fs";
|
|
||||||
import {addIcons} from 'icon';
|
import {addIcons} from 'icon';
|
||||||
import { Upload2Notion } from "Upload2Notion";
|
import { Upload2Notion } from "Upload2Notion";
|
||||||
|
import {NoticeMConfig} from "Message";
|
||||||
|
import { CLIENT_RENEG_LIMIT } from "tls";
|
||||||
|
|
||||||
|
|
||||||
// Remember to rename these classes and interfaces!
|
// Remember to rename these classes and interfaces!
|
||||||
|
|
||||||
interface MyPluginSettings {
|
interface PluginSettings {
|
||||||
notionAPI: string;
|
notionAPI: string;
|
||||||
databaseID: string;
|
databaseID: string;
|
||||||
|
bannerUrl: string;
|
||||||
|
notionID: string;
|
||||||
proxy: string;
|
proxy: string;
|
||||||
|
allowTags: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_SETTINGS: MyPluginSettings = {
|
const langConfig = NoticeMConfig( window.localStorage.getItem('language') || 'en')
|
||||||
|
|
||||||
|
const DEFAULT_SETTINGS: PluginSettings = {
|
||||||
notionAPI: "",
|
notionAPI: "",
|
||||||
databaseID: "",
|
databaseID: "",
|
||||||
|
bannerUrl: "",
|
||||||
|
notionID: "",
|
||||||
proxy: "",
|
proxy: "",
|
||||||
|
allowTags: false
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class MyPlugin extends Plugin {
|
export default class ObsidianSyncNotionPlugin extends Plugin {
|
||||||
settings: MyPluginSettings;
|
settings: PluginSettings;
|
||||||
|
|
||||||
async onload() {
|
async onload() {
|
||||||
await this.loadSettings();
|
await this.loadSettings();
|
||||||
addIcons();
|
addIcons();
|
||||||
// This creates an icon in the left ribbon.
|
// This creates an icon in the left ribbon.
|
||||||
const ribbonIconEl = this.addRibbonIcon(
|
const ribbonIconEl = this.addRibbonIcon(
|
||||||
"notion-logo",
|
"notion-logo",
|
||||||
"Share to notion",
|
"Share to NotionNext",
|
||||||
async (evt: MouseEvent) => {
|
async (evt: MouseEvent) => {
|
||||||
// Called when the user clicks the icon.
|
// Called when the user clicks the icon.
|
||||||
this.upload();
|
this.upload();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
// Perform additional things with the ribbon
|
|
||||||
ribbonIconEl.addClass("my-plugin-ribbon-class");
|
|
||||||
|
|
||||||
// This adds a status bar item to the bottom of the app. Does not work on mobile apps.
|
// This adds a status bar item to the bottom of the app. Does not work on mobile apps.
|
||||||
const statusBarItemEl = this.addStatusBarItem();
|
const statusBarItemEl = this.addStatusBarItem();
|
||||||
// statusBarItemEl.setText("share to notion");
|
// statusBarItemEl.setText("share to notion");
|
||||||
|
|
||||||
this.addCommand({
|
this.addCommand({
|
||||||
id: "share-to-notion",
|
id: "share-to-notionnext",
|
||||||
name: "share to notion",
|
name: "share to notionnext",
|
||||||
editorCallback: async (editor: Editor, view: MarkdownView) => {
|
editorCallback: async (editor: Editor, view: MarkdownView) => {
|
||||||
this.upload()
|
this.upload()
|
||||||
},
|
},
|
||||||
@@ -70,44 +73,73 @@ export default class MyPlugin extends Plugin {
|
|||||||
onunload() {}
|
onunload() {}
|
||||||
|
|
||||||
async upload(){
|
async upload(){
|
||||||
const { notionAPI, databaseID } = this.settings;
|
const { notionAPI, databaseID, allowTags } = this.settings;
|
||||||
if (notionAPI === "" || databaseID === "") {
|
if (notionAPI === "" || databaseID === "") {
|
||||||
new Notice(
|
new Notice(
|
||||||
"Please set up the notion API and database ID in the settings tab."
|
"Please set up the notion API and database ID in the settings tab."
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { nowFile, fileData,fullPath } =
|
const { markDownData, nowFile, tags, type, slug, stats, category, summary, paword, favicon, datetime } =await this.getNowFileMarkdownContent(this.app);
|
||||||
await this.getNowFileMarkdwonContent(this.app);
|
|
||||||
|
if (markDownData) {
|
||||||
const { basename } = nowFile;
|
const { basename } = nowFile;
|
||||||
if (fileData) {
|
|
||||||
const upload = new Upload2Notion(this);
|
const upload = new Upload2Notion(this);
|
||||||
const res = await upload.syncMarkdownToNotion(basename,fileData, fullPath)
|
const res = await upload.syncMarkdownToNotion(basename, allowTags, tags, type, slug, stats, category, summary, paword, favicon, datetime, markDownData, nowFile, this.app, this.settings)
|
||||||
console.log(res)
|
|
||||||
if(res.status === 200){
|
if(res.status === 200){
|
||||||
new Notice(`${basename} 同步成功`)
|
new Notice(`${langConfig["sync-success"]}${basename}`)
|
||||||
}else {
|
}else {
|
||||||
new Notice(`${basename} 同步失败`)
|
new Notice(`${langConfig["sync-fail"]}${basename}`, 5000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getNowFileMarkdwonContent(app: App) {
|
async getNowFileMarkdownContent(app: App) {
|
||||||
const nowFile = app.workspace.getActiveFile();
|
const nowFile = app.workspace.getActiveFile();
|
||||||
|
const { allowTags } = this.settings;
|
||||||
|
let tags = []
|
||||||
|
let type = ''
|
||||||
|
let slug = ''
|
||||||
|
let stats = ''
|
||||||
|
let category = ''
|
||||||
|
let summary = ''
|
||||||
|
let paword = ''
|
||||||
|
let favicon = ''
|
||||||
|
let datetime = ''
|
||||||
|
|
||||||
|
const FileCache = app.metadataCache.getFileCache(nowFile)
|
||||||
|
try {
|
||||||
|
if(allowTags) {
|
||||||
|
tags = FileCache.frontmatter.tags;
|
||||||
|
type = FileCache.frontmatter.type;
|
||||||
|
slug = FileCache.frontmatter.slug;
|
||||||
|
stats = FileCache.frontmatter.stats;
|
||||||
|
category = FileCache.frontmatter.category;
|
||||||
|
summary = FileCache.frontmatter.summary;
|
||||||
|
paword = FileCache.frontmatter.password;
|
||||||
|
favicon = FileCache.frontmatter.icon;
|
||||||
|
datetime = FileCache.frontmatter.date;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
new Notice(langConfig["set-tags-fail"]);
|
||||||
|
}
|
||||||
if (nowFile) {
|
if (nowFile) {
|
||||||
const filePath: string = nowFile.path;
|
const markDownData = await nowFile.vault.read(nowFile);
|
||||||
// @ts-ignore
|
|
||||||
const basePath: string = nowFile.vault.adapter.basePath;
|
|
||||||
const fullPath = normalizePath(join(basePath, filePath));
|
|
||||||
console.log("fullpath", fullPath);
|
|
||||||
const fileData = fs.readFileSync(fullPath, "utf8");
|
|
||||||
return {
|
return {
|
||||||
fileData,
|
markDownData,
|
||||||
nowFile,
|
nowFile,
|
||||||
fullPath,
|
tags,
|
||||||
|
type,
|
||||||
|
slug,
|
||||||
|
stats,
|
||||||
|
category,
|
||||||
|
summary,
|
||||||
|
paword,
|
||||||
|
favicon,
|
||||||
|
datetime,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
new Notice("请打开需要同步的文件");
|
new Notice(langConfig["open-file"]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,26 +157,10 @@ export default class MyPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SampleModal extends Modal {
|
|
||||||
constructor(app: App) {
|
|
||||||
super(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
onOpen() {
|
|
||||||
const { contentEl } = this;
|
|
||||||
contentEl.setText("Woah!");
|
|
||||||
}
|
|
||||||
|
|
||||||
onClose() {
|
|
||||||
const { contentEl } = this;
|
|
||||||
contentEl.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SampleSettingTab extends PluginSettingTab {
|
class SampleSettingTab extends PluginSettingTab {
|
||||||
plugin: MyPlugin;
|
plugin: ObsidianSyncNotionPlugin;
|
||||||
|
|
||||||
constructor(app: App, plugin: MyPlugin) {
|
constructor(app: App, plugin: ObsidianSyncNotionPlugin) {
|
||||||
super(app, plugin);
|
super(app, plugin);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
@@ -155,35 +171,82 @@ class SampleSettingTab extends PluginSettingTab {
|
|||||||
containerEl.empty();
|
containerEl.empty();
|
||||||
|
|
||||||
containerEl.createEl("h2", {
|
containerEl.createEl("h2", {
|
||||||
text: "Settings for obsidian to notion plugin.",
|
text: "Settings for obsidian to NotionNext plugin.",
|
||||||
});
|
});
|
||||||
|
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName("Notion API Token")
|
.setName("Notion API Token")
|
||||||
.setDesc("It's a secret")
|
.setDesc("It's a secret")
|
||||||
.addText((text) =>
|
.addText((text) =>{
|
||||||
text
|
let t = text
|
||||||
.setPlaceholder("Enter your Notion API Token")
|
.setPlaceholder("Enter your Notion API Token")
|
||||||
.setValue(this.plugin.settings.notionAPI)
|
.setValue(this.plugin.settings.notionAPI)
|
||||||
.onChange(async (value) => {
|
.onChange(async (value) => {
|
||||||
console.log("Secret: " + value);
|
|
||||||
this.plugin.settings.notionAPI = value;
|
this.plugin.settings.notionAPI = value;
|
||||||
await this.plugin.saveSettings();
|
await this.plugin.saveSettings();
|
||||||
})
|
})
|
||||||
);
|
// t.inputEl.type = 'password'
|
||||||
|
return t
|
||||||
|
});
|
||||||
|
|
||||||
new Setting(containerEl)
|
|
||||||
|
const notionDatabaseID = new Setting(containerEl)
|
||||||
.setName("Database ID")
|
.setName("Database ID")
|
||||||
.setDesc("It's a secret")
|
.setDesc("It's a secret")
|
||||||
.addText((text) =>
|
.addText((text) => {
|
||||||
text
|
let t = text
|
||||||
.setPlaceholder("Enter your Database ID")
|
.setPlaceholder("Enter your Database ID")
|
||||||
.setValue(this.plugin.settings.databaseID)
|
.setValue(this.plugin.settings.databaseID)
|
||||||
.onChange(async (value) => {
|
.onChange(async (value) => {
|
||||||
console.log("Secret: " + value);
|
|
||||||
this.plugin.settings.databaseID = value;
|
this.plugin.settings.databaseID = value;
|
||||||
await this.plugin.saveSettings();
|
await this.plugin.saveSettings();
|
||||||
})
|
})
|
||||||
|
// t.inputEl.type = 'password'
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
// notionDatabaseID.controlEl.querySelector('input').type='password'
|
||||||
|
|
||||||
|
new Setting(containerEl)
|
||||||
|
.setName("Banner url(optional)")
|
||||||
|
.setDesc("page banner url(optional), default is empty, if you want to show a banner, please enter the url(like:https://raw.githubusercontent.com/EasyChris/obsidian-to-notion/ae7a9ac6cf427f3ca338a409ce6967ced9506f12/doc/2.png)")
|
||||||
|
.addText((text) =>
|
||||||
|
text
|
||||||
|
.setPlaceholder("Enter banner pic url: ")
|
||||||
|
.setValue(this.plugin.settings.bannerUrl)
|
||||||
|
.onChange(async (value) => {
|
||||||
|
this.plugin.settings.bannerUrl = value;
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
new Setting(containerEl)
|
||||||
|
.setName("Notion ID(optional)")
|
||||||
|
.setDesc("Your notion ID(optional),share link likes:https://username.notion.site/,your notion id is [username]")
|
||||||
|
.addText((text) =>
|
||||||
|
text
|
||||||
|
.setPlaceholder("Enter notion ID(options) ")
|
||||||
|
.setValue(this.plugin.settings.notionID)
|
||||||
|
.onChange(async (value) => {
|
||||||
|
this.plugin.settings.notionID = value;
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
new Setting(containerEl)
|
||||||
|
.setName("Convert tags(optional)")
|
||||||
|
.setDesc("Transfer the Obsidian tags to the Notion table. It requires the column with the name 'Tags'")
|
||||||
|
.addToggle((toggle) =>
|
||||||
|
toggle
|
||||||
|
.setValue(this.plugin.settings.allowTags)
|
||||||
|
.onChange(async (value) => {
|
||||||
|
this.plugin.settings.allowTags = value;
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"id": "obsidian-to-notion",
|
"id": "share-to-notionnext",
|
||||||
"name": "Obsidian shared to Notion",
|
"name": "Share to NotionNext",
|
||||||
"version": "0.3.4",
|
"version": "0.0.4",
|
||||||
"minAppVersion": "0.0.1",
|
"minAppVersion": "0.0.1",
|
||||||
"description": "This is a plugin for Obsidian. This plugin share obsidian md file to notion with notion api",
|
"description": "This is a plugin for Obsidian. This plugin shares obsidian md file to notion with notion api for NotionNext web deploy.",
|
||||||
"author": "Easychris",
|
"author": "jxpeng98",
|
||||||
"authorUrl": "https://github.com/EasyChris/obsidian-to-notion",
|
"authorUrl": "https://github.com/jxpeng98/obsidian-to-NotionNext",
|
||||||
"isDesktopOnly": false
|
"isDesktopOnly": false
|
||||||
}
|
}
|
||||||
15
obsidian template.md
Normal file
15
obsidian template.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
type: Post // Post or Page
|
||||||
|
slug: test // slug for url
|
||||||
|
stats: Draft // Draft, Invisible, Published
|
||||||
|
category: test
|
||||||
|
summary: this is a summary for test post
|
||||||
|
icon: fa-solid fa-camera // you can ignore this
|
||||||
|
password: "1234" // if you donot want to set password, you can delete this line
|
||||||
|
tags:
|
||||||
|
- test // tags for post
|
||||||
|
- web // add more tags if you want
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
Contents Below
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "obsidian-to-notion",
|
"name": "share-to-notionnext",
|
||||||
"version": "0.3.4",
|
"version": "0.0.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "This is a plugin for Obsidian. This plugin share obsidian md file to notion with notion api",
|
"description": "This is a plugin for Obsidian. This plugin share obsidian md file to notion with notion api for NotionNext web deploy.",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "node esbuild.config.mjs",
|
"dev": "node esbuild.config.mjs",
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tryfabric/martian": "^1.2.0",
|
"@tryfabric/martian": "^1.2.0",
|
||||||
"https-proxy-agent": "^5.0.1",
|
"https-proxy-agent": "^5.0.1",
|
||||||
"yaml": "^2.1.0",
|
"yaml": "^2.2.2",
|
||||||
"yaml-front-matter": "^4.1.1"
|
"yaml-front-matter": "^4.1.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
node update-version.js $1
|
node update-version.js $1
|
||||||
|
git add .
|
||||||
|
git commit -m "Update version to $1"
|
||||||
git tag -a $1 -m $1
|
git tag -a $1 -m $1
|
||||||
git push origin $1
|
git push origin $1
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
/* Sets all the text color to red! */
|
|
||||||
/* body {
|
|
||||||
color: red;
|
|
||||||
} */
|
|
||||||
|
|||||||
Reference in New Issue
Block a user