-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.js
128 lines (110 loc) · 3.41 KB
/
main.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
require('dotenv').config();
const axios = require('axios');
const dayjs = require('dayjs');
const extract = require('extract-zip');
const { retry, forEachOf } = require('async');
const { createWriteStream, mkdirSync, rmdirSync } = require('fs');
const { join } = require('path');
const notionAPI = "https://www.notion.so/api/v3";
const notionToken = process.env.NOTION_ACCESS_TOKEN || "";
const userId = process.env.NOTION_USER_ID || "";
const spaceId = process.env.NOTION_SPACE_ID || "";
const fileDownloadToken = process.env.NOTION_DOWNLOAD_FILE_TOKEN || "";
async function sleep(seconds) {
return new Promise((resolve) => {
setTimeout(resolve, seconds * 1000);
});
}
const exportFromNotion = async (backupDir, format) => {
if (!notionToken) {
throw new Error("Notion token is empty!!!");
}
try {
let client = axios.create({
baseURL: notionAPI,
headers: {
Cookie: `token_v2=${notionToken}; notion_user_id=${userId}; file_token=${fileDownloadToken}`,
'x-notion-active-user-header': `${userId}`,
},
});
let { data: { taskId } } = await client.post('enqueueTask', {
task: {
eventName: 'exportSpace',
request: {
spaceId: spaceId,
exportOptions: {
exportType: format,
timeZone: 'America/New_York',
locale: 'en',
},
},
actor: {
table: 'notion_user',
id: userId,
},
},
});
console.warn(`Enqueued task ${taskId} (${backupDir}/${format})`);
let failCount = 0 , exportURL;
// Wait for exported files to generate
while (true) {
if (failCount >= 10) break;
await sleep(10);
let { data: { results: tasks } } = await retry(
{ times: 10, interval: 2000 },
async () => client.post('getTasks', { taskIds: [taskId] })
);
let task = tasks.find(t => t.id === taskId);
if (!task) {
failCount++;
console.warn(`No task, waiting.`);
continue;
}
if (!task.status) {
failCount++;
console.warn(`No task status, waiting. Task was:\n${JSON.stringify(task, null, 2)}`);
continue;
}
if (task.state === 'in_progress') {
console.warn(`\nWait... Export generating...: ${task.status.pagesExported} `
+ `(${backupDir}/${format})\n`);
}
if (task.state === 'failure') {
failCount++;
console.warn(`Task error: ${task.error}`);
continue;
}
if (task.state === 'success') {
exportURL = task.status.exportURL;
console.warn(`*** DONE *** | Pages exported: ${task.status.pagesExported} `
+ `(${backupDir}/${format})`);
break;
}
}
let res = await client({
method: 'GET',
url: exportURL,
responseType: 'stream'
});
const now = dayjs();
const yyyymmdd = now.format('YYYY-MM-DD');
const fileName = `${format}-${yyyymmdd}.zip`;
let stream = res.data.pipe(createWriteStream(join(process.cwd(),
`${backupDir}/${fileName}`)));
await new Promise((resolve, reject) => {
stream.on('close', resolve);
stream.on('error', reject);
});
}
catch (err) {
console.warn(err);
}
}
const main = async () => {
const backupDir = `backups`;
let cwd = process.cwd();
mkdirSync(join(cwd, backupDir), { recursive: true });
const format = "markdown";
await exportFromNotion(backupDir, format);
}
main();