-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
132 lines (114 loc) · 3.68 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
require('dotenv').config();
const axios = require(`axios`);
const extract = require(`extract-zip`);
const { createWriteStream } = require(`fs`);
const { rm, mkdir, unlink } = require(`fs/promises`);
const { join } = require(`path`);
// import { EventEmitter } from 'node:events';
const unofficialNotionAPI = `https://www.notion.so/api/v3`;
const { NOTION_TOKEN, NOTION_SPACE_ID, NOTION_USER_ID, NOTION_FOLDER_ID } = process.env;
const client = axios.create({
baseURL: unofficialNotionAPI,
headers: {
Cookie: `token_v2=${NOTION_TOKEN};`,
"x-notion-active-user-header": NOTION_USER_ID,
},
});
if (!NOTION_TOKEN || !NOTION_SPACE_ID || !NOTION_USER_ID) {
console.error(
`Environment variable NOTION_TOKEN, NOTION_SPACE_ID or NOTION_USER_ID is missing. Check the README.md for more information.`
);
process.exit(1);
}
const sleep = async (seconds) => {
return new Promise((resolve) => {
setTimeout(resolve, seconds * 1000);
});
};
const round = (number) => Math.round(number * 100) / 100;
const exportFromNotion = async (destination, format) => {
const task = {
eventName: `exportSpace`,
request: {
spaceId: NOTION_SPACE_ID,
// block: {
// id: NOTION_FOLDER_ID,
// spaceId: NOTION_SPACE_ID
// },
exportOptions: {
exportType: format,
timeZone: `Europe/Berlin`,
locale: `en`,
},
// recursive: true,
shouldExportComments: false
},
};
const {
data: { taskId },
} = await client.post(`enqueueTask`, { task });
console.log(`Started Export as task [${taskId}].\n`);
let exportURL;
let fileTokenCookie;
while (true) {
await sleep(2);
const {
data: { results: tasks },
headers: { 'set-cookie': getTasksRequestCookies },
} = await client.post(`getTasks`, { taskIds: [taskId] });
const task = tasks.find((t) => t.id === taskId);
if (task.error) {
console.error(`❌ Export failed with reason: ${task.error}`);
process.exit(1);
}
console.log(`Exported ${task.status.pagesExported} pages.`);
if (task.state === `success`) {
exportURL = task.status.exportURL;
fileTokenCookie = getTasksRequestCookies.find((cookie) =>
cookie.includes("file_token="),
);
console.log(`\nExport finished.`);
break;
}
}
const response = await client({
method: `GET`,
url: exportURL,
responseType: `stream`,
headers: {
Cookie: fileTokenCookie,
},
});
const size = response.headers["content-length"];
console.log(`Downloading ${round(size / 1000 / 1000)}mb...`);
const stream = response.data.pipe(createWriteStream(destination));
await new Promise((resolve, reject) => {
stream.on(`close`, resolve);
stream.on(`error`, reject);
});
};
const run = async () => {
const workspaceDir = join(process.cwd(), `workspace`);
const workspaceZip = join(process.cwd(), `workspace.zip`);
await exportFromNotion(workspaceZip, `markdown`);
await rm(workspaceDir, { recursive: true, force: true });
await mkdir(workspaceDir, { recursive: true });
await extract(workspaceZip, {
dir: workspaceDir, onEntry: async (entry, zipfile) => {
if (entry.fileName.toLowerCase().endsWith('.zip')) {
const nestedZipFile = join(workspaceDir, entry.fileName);
zipfile.openReadStream(entry, (err, readStream) => {
if (err) throw err;
const writeStream = createWriteStream(nestedZipFile);
readStream.pipe(writeStream);
writeStream.on('finish', () => {
extract(nestedZipFile, { dir: workspaceDir })
});
});
}
}
});
await unlink(workspaceZip);
console.log(`✅ Export downloaded and unzipped.`);
};
run();