Git Product home page Git Product logo

notion-backup's Introduction

notion-backup

This is a very simple tool to export a workspace from Notion, designed to work as part of a GitHub workflow.

It reads NOTION_TOKEN and NOTION_SPACE_ID from the environment, and outputs the export to both html and markdown directories in the current working directory, as well as to html.zip and markdown.zip.

Obtaining tokens

Automatically downloading backups from Notion requires two unique authentication tokens and your individual space ID which must be obtained for the script to work.

  1. Log into your Notion account in your browser of choice if you haven't done so already.
  2. Open a new tab in your browser and open the development tools. This is usually easiest done by right-click and selecting Inspect Element (Chrome, Edge, Safari) or Inspect (Firefox). Switch to the Network tab.
  3. Open https://notion.so/f/. You must use this specific subdirectory to obtain the right cookies.
  4. Insert getSpaces into the search filter of the Network tab. This should give you one result. Click on it.
  5. In the Preview tab, look for the key space. There you should find a list of all the workspaces you have access to. Unless you're part of shared workspaces there should only be one.
  6. Copy the UUID of the workspace you want to backup (e.g. 6e560115-7a65-4f65-bb04-1825b43748f1). This is your NOTION_SPACE_ID.
  7. Switch to the Application (Chrome, Edge) or Storage (Firefox, Safari) tab on the top.
  8. In the left sidebar, select Cookies -> https://www.notion.so (Chrome, Edge, Firefox) or Cookies – https://www.notion.so (Safari).
  9. Copy the value of token_v2 as your NOTION_TOKEN and the value of file_token as your NOTION_FILE_TOKEN.
  10. Set the three environment variables as secrets for actions in your GitHub repository.

NOTE: if you log out of your account or your session expires naturally, the NOTION_TOKEN and NOTION_FILE_TOKEN will get invalidated and the backup will fail. In this case you need to obtain new tokens by repeating this process. There is currently no practical way to automize this until Notion decide to add a backup endpoint to their official API, at which point this script will be able to use a proper authentication token.

Setup

This assumes you are looking to set this up to back up Notion to GitHub.

  1. Obtain the required values for the environment variables as explained above.
  2. Create a repo for your backup. You probably want it private.
  3. Set the NOTION_TOKEN, NOTION_FILE_TOKEN and NOTION_SPACE_ID environment variables as secrets in your GitHub repo.
  4. Give Actions write access to your repository: Settings > Actions > General > Workflow permissions > choose Read and write permissions
  5. Install the following under .github/workflows/whatever.yml in your repo.
  6. Configure the frequency by changing the cron value. You can use Crontab.guru.
  7. Push and control your backup workflow from the Actions tab of your repository Github page.
name: "Notion backup"

on:
  push:
    branches:
      - master
  schedule:
    -   cron: "0 */4 * * *"

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

jobs:
  backup:
    runs-on: ubuntu-latest
    name: Backup
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v3

      - uses: actions/setup-node@v2
        with:
          node-version: '18'

      - name: Delete previous backup
        run: rm -rf markdown html *.zip

      - name: Setup dependencies
        run: npm install -g notion-backup

      - name: Run backup
        run: notion-backup
        env:
          NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }}
          NOTION_FILE_TOKEN: ${{ secrets.NOTION_FILE_TOKEN }}
          NOTION_SPACE_ID: ${{ secrets.NOTION_SPACE_ID }}
          NODE_OPTIONS: "--max-http-header-size 15000"

      - name: Delete zips
        run: |
          rm -f *.zip
          rm -f markdown/*-Part*.zip
          rm -f html/*-Part*.zip

      - name: Commit changes
        run: |
          git config user.name github-actions
          git config user.email [email protected]
          git add .
          git commit -m "Automated snapshot"
          git push

LFS Support

You won't be able to backup files exceeding a size of 100MB unless you enable Git LFS. Add a file named .gitattributes at the root of your repository and add the following. If you want to support other file types, just add a new line for that file type.

*.zip filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text

notion-backup's People

Contributors

darobin avatar hbhargava7 avatar ngdio avatar oktomus avatar thilo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

notion-backup's Issues

notion-backups Fork and Parallel Release

Hiya!

Just leaving an issue here to let you know that I released a fork of this package with additional functionality on npm.

I wrote it for myself since I was looking for a way to do Notion backups for multiple users and multiple workspaces, but unfortunately, it is API breaking for this package, that's why I released a package in parallel to this package instead of sending a PR. I've credited you and also listed you as a contributor in that package, I hope that's ok?

You can see how I've credited this package and yourself in the repo and npm package page.

Have a nice day! 🌟
CH3EERS!

PS: I managed to pick up some node.js and learning about the npm ecosystem from this project, so I am very grateful.

Backup fails with "Request failed with status code 403" error

Backup no longer works, even after updating actions to the latest version as per README. I've updated the token multiple times but it doesn't change anything. I have however noticed the token appears different now than what I was used to, with v02%3Auser_token_or_cookies%3A as a suffix before the usual token. I've tried to leave out the suffix or to change the %3A into colons but this hasn't fixed the issue either.

Actions log
2023-03-22T19:19:01.6218450Z Requested labels: ubuntu-latest
2023-03-22T19:19:01.6218489Z Job defined at: ngdio/notion-backup/.github/workflows/notion-backup.yaml@refs/heads/master
2023-03-22T19:19:01.6218519Z Waiting for a runner to pick up this job...
2023-03-22T19:19:02.2002817Z Job is waiting for a hosted runner to come online.
2023-03-22T19:19:07.4057762Z Job is about to start running on the hosted runner: GitHub Actions 2 (hosted)
2023-03-22T19:19:10.2115296Z Current runner version: '2.303.0'
2023-03-22T19:19:10.2150575Z ##[group]Operating System
2023-03-22T19:19:10.2151340Z Ubuntu
2023-03-22T19:19:10.2151714Z 22.04.2
2023-03-22T19:19:10.2152076Z LTS
2023-03-22T19:19:10.2153386Z ##[endgroup]
2023-03-22T19:19:10.2153836Z ##[group]Runner Image
2023-03-22T19:19:10.2154265Z Image: ubuntu-22.04
2023-03-22T19:19:10.2154683Z Version: 20230313.1
2023-03-22T19:19:10.2155359Z Included Software: https://github.com/actions/runner-images/blob/ubuntu22/20230313.1/images/linux/Ubuntu2204-Readme.md
2023-03-22T19:19:10.2156226Z Image Release: https://github.com/actions/runner-images/releases/tag/ubuntu22%2F20230313.1
2023-03-22T19:19:10.2156800Z ##[endgroup]
2023-03-22T19:19:10.2157265Z ##[group]Runner Image Provisioner
2023-03-22T19:19:10.2157663Z 2.0.127.1
2023-03-22T19:19:10.2158104Z ##[endgroup]
2023-03-22T19:19:10.2159368Z ##[group]GITHUB_TOKEN Permissions
2023-03-22T19:19:10.2160268Z Actions: write
2023-03-22T19:19:10.2160686Z Checks: write
2023-03-22T19:19:10.2162136Z Contents: write
2023-03-22T19:19:10.2162690Z Deployments: write
2023-03-22T19:19:10.2164210Z Discussions: write
2023-03-22T19:19:10.2164787Z Issues: write
2023-03-22T19:19:10.2165216Z Metadata: read
2023-03-22T19:19:10.2165630Z Packages: write
2023-03-22T19:19:10.2165989Z Pages: write
2023-03-22T19:19:10.2166504Z PullRequests: write
2023-03-22T19:19:10.2166970Z RepositoryProjects: write
2023-03-22T19:19:10.2167476Z SecurityEvents: write
2023-03-22T19:19:10.2167905Z Statuses: write
2023-03-22T19:19:10.2168330Z ##[endgroup]
2023-03-22T19:19:10.2173349Z Secret source: Actions
2023-03-22T19:19:10.2174062Z Prepare workflow directory
2023-03-22T19:19:10.3311412Z Prepare all required actions
2023-03-22T19:19:10.3602902Z Getting action download info
2023-03-22T19:19:10.6312608Z Download action repository 'actions/checkout@v3' (SHA:24cb9080177205b6e8c946b17badbe402adc938f)
2023-03-22T19:19:11.0564343Z Download action repository 'actions/setup-node@v2' (SHA:1f8c6b94b26d0feae1e387ca63ccbdc44d27b561)
2023-03-22T19:19:11.6432400Z Complete job name: Backup
2023-03-22T19:19:11.8013014Z ##[group]Run actions/checkout@v3
2023-03-22T19:19:11.8013583Z with:
2023-03-22T19:19:11.8014209Z   repository: ngdio/notion-backup
2023-03-22T19:19:11.8014998Z   token: ***
2023-03-22T19:19:11.8015382Z   ssh-strict: true
2023-03-22T19:19:11.8015721Z   persist-credentials: true
2023-03-22T19:19:11.8016190Z   clean: true
2023-03-22T19:19:11.8016549Z   fetch-depth: 1
2023-03-22T19:19:11.8016934Z   lfs: false
2023-03-22T19:19:11.8017282Z   submodules: false
2023-03-22T19:19:11.8017664Z   set-safe-directory: true
2023-03-22T19:19:11.8018130Z ##[endgroup]
2023-03-22T19:19:12.2892156Z Syncing repository: ngdio/notion-backup
2023-03-22T19:19:12.2894744Z ##[group]Getting Git version info
2023-03-22T19:19:12.2895523Z Working directory is '/home/runner/work/notion-backup/notion-backup'
2023-03-22T19:19:12.2902262Z [command]/usr/bin/git version
2023-03-22T19:19:12.3184281Z git version 2.39.2
2023-03-22T19:19:12.3186487Z ##[endgroup]
2023-03-22T19:19:12.3206117Z Temporarily overriding HOME='/home/runner/work/_temp/7ebbc482-821a-4829-a3b1-107e2d7f40b1' before making global git config changes
2023-03-22T19:19:12.3207520Z Adding repository directory to the temporary git global config as a safe directory
2023-03-22T19:19:12.3208342Z [command]/usr/bin/git config --global --add safe.directory /home/runner/work/notion-backup/notion-backup
2023-03-22T19:19:12.3227036Z Deleting the contents of '/home/runner/work/notion-backup/notion-backup'
2023-03-22T19:19:12.3234668Z ##[group]Initializing the repository
2023-03-22T19:19:12.3238936Z [command]/usr/bin/git init /home/runner/work/notion-backup/notion-backup
2023-03-22T19:19:12.3362790Z hint: Using 'master' as the name for the initial branch. This default branch name
2023-03-22T19:19:12.3373015Z hint: is subject to change. To configure the initial branch name to use in all
2023-03-22T19:19:12.3384091Z hint: of your new repositories, which will suppress this warning, call:
2023-03-22T19:19:12.3385093Z hint: 
2023-03-22T19:19:12.3387026Z hint: 	git config --global init.defaultBranch <name>
2023-03-22T19:19:12.3387988Z hint: 
2023-03-22T19:19:12.3389161Z hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
2023-03-22T19:19:12.3390197Z hint: 'development'. The just-created branch can be renamed via this command:
2023-03-22T19:19:12.3391204Z hint: 
2023-03-22T19:19:12.3392060Z hint: 	git branch -m <name>
2023-03-22T19:19:12.3393398Z Initialized empty Git repository in /home/runner/work/notion-backup/notion-backup/.git/
2023-03-22T19:19:12.3398443Z [command]/usr/bin/git remote add origin https://github.com/ngdio/notion-backup
2023-03-22T19:19:12.3488198Z ##[endgroup]
2023-03-22T19:19:12.3488938Z ##[group]Disabling automatic garbage collection
2023-03-22T19:19:12.3490054Z [command]/usr/bin/git config --local gc.auto 0
2023-03-22T19:19:12.3592373Z ##[endgroup]
2023-03-22T19:19:12.3593290Z ##[group]Setting up auth
2023-03-22T19:19:12.3594125Z [command]/usr/bin/git config --local --name-only --get-regexp core\.sshCommand
2023-03-22T19:19:12.3930457Z [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :"
2023-03-22T19:19:12.4268723Z [command]/usr/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader
2023-03-22T19:19:12.4308051Z [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :"
2023-03-22T19:19:12.4646975Z [command]/usr/bin/git config --local http.https://github.com/.extraheader AUTHORIZATION: basic ***
2023-03-22T19:19:12.4726764Z ##[endgroup]
2023-03-22T19:19:12.4727833Z ##[group]Fetching the repository
2023-03-22T19:19:12.4739691Z [command]/usr/bin/git -c protocol.version=2 fetch --no-tags --prune --progress --no-recurse-submodules --depth=1 origin +efd735ecb67e6e8ecd66a1751895fee1bf31e05e:refs/remotes/origin/master
2023-03-22T19:19:12.7414455Z remote: Enumerating objects: 9, done.        
2023-03-22T19:19:12.7422713Z remote: Counting objects:  11% (1/9)        
2023-03-22T19:19:12.7424613Z remote: Counting objects:  22% (2/9)        
2023-03-22T19:19:12.7427912Z remote: Counting objects:  33% (3/9)        
2023-03-22T19:19:12.7428639Z remote: Counting objects:  44% (4/9)        
2023-03-22T19:19:12.7429479Z remote: Counting objects:  55% (5/9)        
2023-03-22T19:19:12.7430095Z remote: Counting objects:  66% (6/9)        
2023-03-22T19:19:12.7430905Z remote: Counting objects:  77% (7/9)        
2023-03-22T19:19:12.7431535Z remote: Counting objects:  88% (8/9)        
2023-03-22T19:19:12.7432720Z remote: Counting objects: 100% (9/9)        
2023-03-22T19:19:12.7433402Z remote: Counting objects: 100% (9/9), done.        
2023-03-22T19:19:12.7438212Z remote: Compressing objects:  16% (1/6)        
2023-03-22T19:19:12.7438990Z remote: Compressing objects:  33% (2/6)        
2023-03-22T19:19:12.7439968Z remote: Compressing objects:  50% (3/6)        
2023-03-22T19:19:12.7440624Z remote: Compressing objects:  66% (4/6)        
2023-03-22T19:19:12.7441790Z remote: Compressing objects:  83% (5/6)        
2023-03-22T19:19:12.7442427Z remote: Compressing objects: 100% (6/6)        
2023-03-22T19:19:12.7443274Z remote: Compressing objects: 100% (6/6), done.        
2023-03-22T19:19:13.1761279Z remote: Total 9 (delta 1), reused 8 (delta 1), pack-reused 0        
2023-03-22T19:19:13.5454347Z From https://github.com/ngdio/notion-backup
2023-03-22T19:19:13.5455874Z  * [new ref]         efd735ecb67e6e8ecd66a1751895fee1bf31e05e -> origin/master
2023-03-22T19:19:13.5498631Z ##[endgroup]
2023-03-22T19:19:13.5521536Z ##[group]Determining the checkout info
2023-03-22T19:19:13.5522542Z ##[endgroup]
2023-03-22T19:19:13.5524153Z ##[group]Checking out the ref
2023-03-22T19:19:13.5525107Z [command]/usr/bin/git checkout --progress --force -B master refs/remotes/origin/master
2023-03-22T19:19:13.5978456Z Reset branch 'master'
2023-03-22T19:19:13.5979623Z branch 'master' set up to track 'origin/master'.
2023-03-22T19:19:13.5986659Z ##[endgroup]
2023-03-22T19:19:13.6038269Z [command]/usr/bin/git log -1 --format='%H'
2023-03-22T19:19:13.6083993Z 'efd735ecb67e6e8ecd66a1751895fee1bf31e05e'
2023-03-22T19:19:13.6513256Z ##[group]Run actions/setup-node@v2
2023-03-22T19:19:13.6513576Z with:
2023-03-22T19:19:13.6513818Z   node-version: 18
2023-03-22T19:19:13.6514080Z   always-auth: false
2023-03-22T19:19:13.6514504Z   check-latest: false
2023-03-22T19:19:13.6515141Z   token: ***
2023-03-22T19:19:13.6515382Z ##[endgroup]
2023-03-22T19:19:14.1018858Z Found in cache @ /opt/hostedtoolcache/node/18.15.0/x64
2023-03-22T19:19:14.1192456Z ##[group]Run rm -rf markdown html *.zip
2023-03-22T19:19:14.1192843Z �[36;1mrm -rf markdown html *.zip�[0m
2023-03-22T19:19:14.1265871Z shell: /usr/bin/bash -e {0}
2023-03-22T19:19:14.1266144Z ##[endgroup]
2023-03-22T19:19:14.1553126Z ##[group]Run npm install -g notion-backup
2023-03-22T19:19:14.1553509Z �[36;1mnpm install -g notion-backup�[0m
2023-03-22T19:19:14.1619073Z shell: /usr/bin/bash -e {0}
2023-03-22T19:19:14.1619354Z ##[endgroup]
2023-03-22T19:19:23.0115087Z 
2023-03-22T19:19:23.0125485Z added 54 packages in 3s
2023-03-22T19:19:23.0126368Z 
2023-03-22T19:19:23.0129540Z 12 packages are looking for funding
2023-03-22T19:19:23.0130116Z   run `npm fund` for details
2023-03-22T19:19:23.0294998Z ##[group]Run notion-backup
2023-03-22T19:19:23.0295348Z �[36;1mnotion-backup�[0m
2023-03-22T19:19:23.0365020Z shell: /usr/bin/bash -e {0}
2023-03-22T19:19:23.0365322Z env:
2023-03-22T19:19:23.0366534Z   NOTION_TOKEN: ***
2023-03-22T19:19:23.0366876Z   NOTION_SPACE_ID: ***
2023-03-22T19:19:23.0367195Z   NODE_OPTIONS: --max-http-header-size 15000
2023-03-22T19:19:23.0367496Z ##[endgroup]
2023-03-22T19:19:23.4764800Z Enqueued task 9f7da712-0fda-45eb-83b8-5b1a8194c18c
2023-03-22T19:19:33.6041880Z Pages exported: 39
2023-03-22T19:19:43.7275106Z Pages exported: 40
2023-03-22T19:19:53.8676424Z Pages exported: 51
2023-03-22T19:20:04.0045826Z Pages exported: 87
2023-03-22T19:20:14.1344806Z Pages exported: 108
2023-03-22T19:20:24.2687389Z Pages exported: 195
2023-03-22T19:20:34.3933329Z Pages exported: 294
2023-03-22T19:20:45.0307114Z Error: Request failed with status code 403
2023-03-22T19:20:45.0308520Z     at createError (/opt/hostedtoolcache/node/18.15.0/x64/lib/node_modules/notion-backup/node_modules/axios/lib/core/createError.js:16:15)
2023-03-22T19:20:45.0311172Z     at settle (/opt/hostedtoolcache/node/18.15.0/x64/lib/node_modules/notion-backup/node_modules/axios/lib/core/settle.js:17:12)
2023-03-22T19:20:45.0312716Z     at RedirectableRequest.handleResponse (/opt/hostedtoolcache/node/18.15.0/x64/lib/node_modules/notion-backup/node_modules/axios/lib/adapters/http.js:238:9)
2023-03-22T19:20:45.0313441Z     at RedirectableRequest.emit (node:events:513:28)
2023-03-22T19:20:45.0314394Z     at RedirectableRequest._processResponse (/opt/hostedtoolcache/node/18.15.0/x64/lib/node_modules/notion-backup/node_modules/follow-redirects/index.js:356:10)
2023-03-22T19:20:45.0315864Z     at RedirectableRequest._onNativeResponse (/opt/hostedtoolcache/node/18.15.0/x64/lib/node_modules/notion-backup/node_modules/follow-redirects/index.js:62:10)
2023-03-22T19:20:45.0316505Z     at Object.onceWrapper (node:events:628:26)
2023-03-22T19:20:45.0316964Z     at ClientRequest.emit (node:events:513:28)
2023-03-22T19:20:45.0317842Z     at HTTPParser.parserOnIncomingClient (node:_http_client:701:27)
2023-03-22T19:20:45.0318649Z     at HTTPParser.parserOnHeadersComplete (node:_http_common:119:17) {
2023-03-22T19:20:45.0319262Z   config: {
2023-03-22T19:20:45.0321877Z     url: 'https://file.notion.so/f/t/a829b0ba-bfd2-478d-8ac3-4cb551bf00ca/Export-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip?id=116fced2-5ea5-40ed-b783-13b3e59b6d57&table=user_export&expirationTimestamp=1680117637294&signature=GMZwq2YdeavMzUIydB2UevrXmhsNtpu7ADFPxSkxIqg&download=true&downloadName=a829b0ba-bfd2-478d-8ac3-4cb551bf00ca%2FExport-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip',
2023-03-22T19:20:45.0323436Z     method: 'get',
2023-03-22T19:20:45.0323775Z     headers: {
2023-03-22T19:20:45.0324271Z       Accept: 'application/json, text/plain, */*',
2023-03-22T19:20:45.0325727Z       Cookie: 'token_v2=***',
2023-03-22T19:20:45.0326225Z       'User-Agent': 'axios/0.21.4'
2023-03-22T19:20:45.0326582Z     },
2023-03-22T19:20:45.0327065Z     baseURL: 'https://www.notion.so/api/v3',
2023-03-22T19:20:45.0327566Z     transformRequest: [ [Function: transformRequest] ],
2023-03-22T19:20:45.0328075Z     transformResponse: [ [Function: transformResponse] ],
2023-03-22T19:20:45.0328466Z     timeout: 0,
2023-03-22T19:20:45.0328848Z     adapter: [Function: httpAdapter],
2023-03-22T19:20:45.0329282Z     responseType: 'stream',
2023-03-22T19:20:45.0329810Z     xsrfCookieName: 'XSRF-TOKEN',
2023-03-22T19:20:45.0330282Z     xsrfHeaderName: 'X-XSRF-TOKEN',
2023-03-22T19:20:45.0330724Z     maxContentLength: -1,
2023-03-22T19:20:45.0331595Z     maxBodyLength: -1,
2023-03-22T19:20:45.0333879Z     validateStatus: [Function: validateStatus],
2023-03-22T19:20:45.0334194Z     transitional: {
2023-03-22T19:20:45.0334487Z       silentJSONParsing: true,
2023-03-22T19:20:45.0334776Z       forcedJSONParsing: true,
2023-03-22T19:20:45.0335088Z       clarifyTimeoutError: false
2023-03-22T19:20:45.0335431Z     },
2023-03-22T19:20:45.0335736Z     data: undefined
2023-03-22T19:20:45.0335958Z   },
2023-03-22T19:20:45.0336553Z   request: <ref *1> ClientRequest {
2023-03-22T19:20:45.0336904Z     _events: [Object: null prototype] {
2023-03-22T19:20:45.0337228Z       abort: [Function (anonymous)],
2023-03-22T19:20:45.0337546Z       aborted: [Function (anonymous)],
2023-03-22T19:20:45.0337862Z       connect: [Function (anonymous)],
2023-03-22T19:20:45.0338365Z       error: [Function (anonymous)],
2023-03-22T19:20:45.0338666Z       socket: [Function (anonymous)],
2023-03-22T19:20:45.0338954Z       timeout: [Function (anonymous)],
2023-03-22T19:20:45.0339271Z       finish: [Function: requestOnFinish]
2023-03-22T19:20:45.0339525Z     },
2023-03-22T19:20:45.0339749Z     _eventsCount: 7,
2023-03-22T19:20:45.0340184Z     _maxListeners: undefined,
2023-03-22T19:20:45.0340447Z     outputData: [],
2023-03-22T19:20:45.0340675Z     outputSize: 0,
2023-03-22T19:20:45.0340919Z     writable: true,
2023-03-22T19:20:45.0341162Z     destroyed: false,
2023-03-22T19:20:45.0341400Z     _last: true,
2023-03-22T19:20:45.0341658Z     chunkedEncoding: false,
2023-03-22T19:20:45.0341922Z     shouldKeepAlive: false,
2023-03-22T19:20:45.0342273Z     maxRequestsOnConnectionReached: false,
2023-03-22T19:20:45.0342592Z     _defaultKeepAlive: true,
2023-03-22T19:20:45.0342926Z     useChunkedEncodingByDefault: false,
2023-03-22T19:20:45.0343214Z     sendDate: false,
2023-03-22T19:20:45.0343656Z     _removedConnection: false,
2023-03-22T19:20:45.0343905Z     _removedContLen: false,
2023-03-22T19:20:45.0344156Z     _removedTE: false,
2023-03-22T19:20:45.0344437Z     strictContentLength: false,
2023-03-22T19:20:45.0344701Z     _contentLength: 0,
2023-03-22T19:20:45.0345001Z     _hasBody: true,
2023-03-22T19:20:45.0345323Z     _trailer: '',
2023-03-22T19:20:45.0345559Z     finished: true,
2023-03-22T19:20:45.0345783Z     _headerSent: true,
2023-03-22T19:20:45.0346019Z     _closed: false,
2023-03-22T19:20:45.0346256Z     socket: TLSSocket {
2023-03-22T19:20:45.0346615Z       _tlsOptions: [Object],
2023-03-22T19:20:45.0346913Z       _secureEstablished: true,
2023-03-22T19:20:45.0347186Z       _securePending: false,
2023-03-22T19:20:45.0347459Z       _newSessionPending: false,
2023-03-22T19:20:45.0347733Z       _controlReleased: true,
2023-03-22T19:20:45.0348023Z       secureConnecting: false,
2023-03-22T19:20:45.0348285Z       _SNICallback: null,
2023-03-22T19:20:45.0348639Z       servername: 'file.notion.so',
2023-03-22T19:20:45.0348914Z       alpnProtocol: false,
2023-03-22T19:20:45.0349149Z       authorized: true,
2023-03-22T19:20:45.0349433Z       authorizationError: null,
2023-03-22T19:20:45.0349695Z       encrypted: true,
2023-03-22T19:20:45.0349989Z       _events: [Object: null prototype],
2023-03-22T19:20:45.0350436Z       _eventsCount: 9,
2023-03-22T19:20:45.0350680Z       connecting: false,
2023-03-22T19:20:45.0350909Z       _hadError: false,
2023-03-22T19:20:45.0351323Z       _parent: null,
2023-03-22T19:20:45.0351664Z       _host: 'file.notion.so',
2023-03-22T19:20:45.0351987Z       _closeAfterHandlingError: false,
2023-03-22T19:20:45.0352697Z       _readableState: [ReadableState],
2023-03-22T19:20:45.0353009Z       _maxListeners: undefined,
2023-03-22T19:20:45.0353305Z       _writableState: [WritableState],
2023-03-22T19:20:45.0353589Z       allowHalfOpen: false,
2023-03-22T19:20:45.0353846Z       _sockname: null,
2023-03-22T19:20:45.0354099Z       _pendingData: null,
2023-03-22T19:20:45.0354417Z       _pendingEncoding: '',
2023-03-22T19:20:45.0354839Z       server: undefined,
2023-03-22T19:20:45.0355064Z       _server: null,
2023-03-22T19:20:45.0355296Z       ssl: [TLSWrap],
2023-03-22T19:20:45.0355614Z       _requestCert: true,
2023-03-22T19:20:45.0355904Z       _rejectUnauthorized: true,
2023-03-22T19:20:45.0356230Z       parser: null,
2023-03-22T19:20:45.0356491Z       _httpMessage: [Circular *1],
2023-03-22T19:20:45.0356778Z       [Symbol(res)]: [TLSWrap],
2023-03-22T19:20:45.0357169Z       [Symbol(verified)]: true,
2023-03-22T19:20:45.0357469Z       [Symbol(pendingSession)]: null,
2023-03-22T19:20:45.0357921Z       [Symbol(async_id_symbol)]: 232,
2023-03-22T19:20:45.0358242Z       [Symbol(kHandle)]: [TLSWrap],
2023-03-22T19:20:45.0358537Z       [Symbol(lastWriteQueueSize)]: 0,
2023-03-22T19:20:45.0358836Z       [Symbol(timeout)]: null,
2023-03-22T19:20:45.0359111Z       [Symbol(kBuffer)]: null,
2023-03-22T19:20:45.0359393Z       [Symbol(kBufferCb)]: null,
2023-03-22T19:20:45.0359754Z       [Symbol(kBufferGen)]: null,
2023-03-22T19:20:45.0360048Z       [Symbol(kCapture)]: false,
2023-03-22T19:20:45.0360326Z       [Symbol(kSetNoDelay)]: false,
2023-03-22T19:20:45.0361454Z       [Symbol(kSetKeepAlive)]: false,
2023-03-22T19:20:45.0361815Z       [Symbol(kSetKeepAliveInitialDelay)]: 0,
2023-03-22T19:20:45.0362146Z       [Symbol(kBytesRead)]: 0,
2023-03-22T19:20:45.0362438Z       [Symbol(kBytesWritten)]: 0,
2023-03-22T19:20:45.0362857Z       [Symbol(connect-options)]: [Object]
2023-03-22T19:20:45.0363094Z     },
2023-03-22T19:20:45.0364511Z     _header: 'GET /f/t/a829b0ba-bfd2-478d-8ac3-4cb551bf00ca/Export-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip?id=116fced2-5ea5-40ed-b783-13b3e59b6d57&table=user_export&expirationTimestamp=1680117637294&signature=GMZwq2YdeavMzUIydB2UevrXmhsNtpu7ADFPxSkxIqg&download=true&downloadName=a829b0ba-bfd2-478d-8ac3-4cb551bf00ca%2FExport-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip HTTP/1.1\r\n' +
2023-03-22T19:20:45.0365481Z       'Accept: application/json, text/plain, */*\r\n' +
2023-03-22T19:20:45.0366663Z       'Cookie: token_v2=***\r\n' +
2023-03-22T19:20:45.0367026Z       'User-Agent: axios/0.21.4\r\n' +
2023-03-22T19:20:45.0367374Z       'Host: file.notion.so\r\n' +
2023-03-22T19:20:45.0367710Z       'Connection: close\r\n' +
2023-03-22T19:20:45.0367985Z       '\r\n',
2023-03-22T19:20:45.0368221Z     _keepAliveTimeout: 0,
2023-03-22T19:20:45.0368526Z     _onPendingData: [Function: nop],
2023-03-22T19:20:45.0368788Z     agent: Agent {
2023-03-22T19:20:45.0369079Z       _events: [Object: null prototype],
2023-03-22T19:20:45.0369351Z       _eventsCount: 2,
2023-03-22T19:20:45.0369628Z       _maxListeners: undefined,
2023-03-22T19:20:45.0369882Z       defaultPort: 443,
2023-03-22T19:20:45.0370183Z       protocol: 'https:',
2023-03-22T19:20:45.0370487Z       options: [Object: null prototype],
2023-03-22T19:20:45.0370820Z       requests: [Object: null prototype] {},
2023-03-22T19:20:45.0371145Z       sockets: [Object: null prototype],
2023-03-22T19:20:45.0371487Z       freeSockets: [Object: null prototype] {},
2023-03-22T19:20:45.0371759Z       keepAliveMsecs: 1000,
2023-03-22T19:20:45.0372017Z       keepAlive: false,
2023-03-22T19:20:45.0372268Z       maxSockets: Infinity,
2023-03-22T19:20:45.0373379Z       maxFreeSockets: 256,
2023-03-22T19:20:45.0373769Z       scheduling: 'lifo',
2023-03-22T19:20:45.0374394Z       maxTotalSockets: Infinity,
2023-03-22T19:20:45.0374721Z       totalSocketCount: 1,
2023-03-22T19:20:45.0375016Z       maxCachedSessions: 100,
2023-03-22T19:20:45.0375335Z       _sessionCache: [Object],
2023-03-22T19:20:45.0375650Z       [Symbol(kCapture)]: false
2023-03-22T19:20:45.0375907Z     },
2023-03-22T19:20:45.0376161Z     socketPath: undefined,
2023-03-22T19:20:45.0376794Z     method: 'GET',
2023-03-22T19:20:45.0377291Z     maxHeaderSize: undefined,
2023-03-22T19:20:45.0377596Z     insecureHTTPParser: undefined,
2023-03-22T19:20:45.0377916Z     joinDuplicateHeaders: undefined,
2023-03-22T19:20:45.0379523Z     path: '/f/t/a829b0ba-bfd2-478d-8ac3-4cb551bf00ca/Export-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip?id=116fced2-5ea5-40ed-b783-13b3e59b6d57&table=user_export&expirationTimestamp=1680117637294&signature=GMZwq2YdeavMzUIydB2UevrXmhsNtpu7ADFPxSkxIqg&download=true&downloadName=a829b0ba-bfd2-478d-8ac3-4cb551bf00ca%2FExport-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip',
2023-03-22T19:20:45.0380325Z     _ended: false,
2023-03-22T19:20:45.0380583Z     res: IncomingMessage {
2023-03-22T19:20:45.0380879Z       _readableState: [ReadableState],
2023-03-22T19:20:45.0381542Z       _events: [Object: null prototype],
2023-03-22T19:20:45.0382055Z       _eventsCount: 1,
2023-03-22T19:20:45.0382512Z       _maxListeners: undefined,
2023-03-22T19:20:45.0382952Z       socket: [TLSSocket],
2023-03-22T19:20:45.0383239Z       httpVersionMajor: 1,
2023-03-22T19:20:45.0383492Z       httpVersionMinor: 1,
2023-03-22T19:20:45.0383815Z       httpVersion: '1.1',
2023-03-22T19:20:45.0384075Z       complete: true,
2023-03-22T19:20:45.0384326Z       rawHeaders: [Array],
2023-03-22T19:20:45.0384747Z       rawTrailers: [],
2023-03-22T19:20:45.0385227Z       joinDuplicateHeaders: undefined,
2023-03-22T19:20:45.0385843Z       aborted: false,
2023-03-22T19:20:45.0386077Z       upgrade: false,
2023-03-22T19:20:45.0386338Z       url: '',
2023-03-22T19:20:45.0388768Z       method: null,
2023-03-22T19:20:45.0389042Z       statusCode: 403,
2023-03-22T19:20:45.0389423Z       statusMessage: 'Forbidden',
2023-03-22T19:20:45.0389706Z       client: [TLSSocket],
2023-03-22T19:20:45.0389970Z       _consuming: false,
2023-03-22T19:20:45.0390224Z       _dumped: false,
2023-03-22T19:20:45.0390477Z       req: [Circular *1],
2023-03-22T19:20:45.0392067Z       responseUrl: 'https://file.notion.so/f/t/a829b0ba-bfd2-478d-8ac3-4cb551bf00ca/Export-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip?id=116fced2-5ea5-40ed-b783-13b3e59b6d57&table=user_export&expirationTimestamp=1680117637294&signature=GMZwq2YdeavMzUIydB2UevrXmhsNtpu7ADFPxSkxIqg&download=true&downloadName=a829b0ba-bfd2-478d-8ac3-4cb551bf00ca%2FExport-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip',
2023-03-22T19:20:45.0392935Z       redirects: [],
2023-03-22T19:20:45.0393230Z       [Symbol(kCapture)]: false,
2023-03-22T19:20:45.0393528Z       [Symbol(kHeaders)]: [Object],
2023-03-22T19:20:45.0393848Z       [Symbol(kHeadersCount)]: 26,
2023-03-22T19:20:45.0394157Z       [Symbol(kTrailers)]: null,
2023-03-22T19:20:45.0394474Z       [Symbol(kTrailersCount)]: 0
2023-03-22T19:20:45.0394726Z     },
2023-03-22T19:20:45.0394951Z     aborted: false,
2023-03-22T19:20:45.0395186Z     timeoutCb: null,
2023-03-22T19:20:45.0395460Z     upgradeOrConnect: false,
2023-03-22T19:20:45.0395768Z     parser: null,
2023-03-22T19:20:45.0396024Z     maxHeadersCount: null,
2023-03-22T19:20:45.0396467Z     reusedSocket: false,
2023-03-22T19:20:45.0396789Z     host: 'file.notion.so',
2023-03-22T19:20:45.0397096Z     protocol: 'https:',
2023-03-22T19:20:45.0397361Z     _redirectable: Writable {
2023-03-22T19:20:45.0397662Z       _writableState: [WritableState],
2023-03-22T19:20:45.0397996Z       _events: [Object: null prototype],
2023-03-22T19:20:45.0398269Z       _eventsCount: 2,
2023-03-22T19:20:45.0398550Z       _maxListeners: undefined,
2023-03-22T19:20:45.0398814Z       _options: [Object],
2023-03-22T19:20:45.0399057Z       _ended: true,
2023-03-22T19:20:45.0399275Z       _ending: true,
2023-03-22T19:20:45.0399781Z       _redirectCount: 0,
2023-03-22T19:20:45.0400031Z       _redirects: [],
2023-03-22T19:20:45.0422941Z       _requestBodyLength: 0,
2023-03-22T19:20:45.0423350Z       _requestBodyBuffers: [],
2023-03-22T19:20:45.0423700Z       _onNativeResponse: [Function (anonymous)],
2023-03-22T19:20:45.0424018Z       _currentRequest: [Circular *1],
2023-03-22T19:20:45.0425868Z       _currentUrl: 'https://file.notion.so/f/t/a829b0ba-bfd2-478d-8ac3-4cb551bf00ca/Export-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip?id=116fced2-5ea5-40ed-b783-13b3e59b6d57&table=user_export&expirationTimestamp=1680117637294&signature=GMZwq2YdeavMzUIydB2UevrXmhsNtpu7ADFPxSkxIqg&download=true&downloadName=a829b0ba-bfd2-478d-8ac3-4cb551bf00ca%2FExport-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip',
2023-03-22T19:20:45.0426960Z       [Symbol(kCapture)]: false
2023-03-22T19:20:45.0427216Z     },
2023-03-22T19:20:45.0427649Z     [Symbol(kCapture)]: false,
2023-03-22T19:20:45.0428123Z     [Symbol(kBytesWritten)]: 0,
2023-03-22T19:20:45.0428629Z     [Symbol(kEndCalled)]: true,
2023-03-22T19:20:45.0429120Z     [Symbol(kNeedDrain)]: false,
2023-03-22T19:20:45.0429540Z     [Symbol(corked)]: 0,
2023-03-22T19:20:45.0429884Z     [Symbol(kOutHeaders)]: [Object: null prototype] {
2023-03-22T19:20:45.0430181Z       accept: [Array],
2023-03-22T19:20:45.0430425Z       cookie: [Array],
2023-03-22T19:20:45.0431230Z       'user-agent': [Array],
2023-03-22T19:20:45.0431673Z       host: [Array]
2023-03-22T19:20:45.0431896Z     },
2023-03-22T19:20:45.0432126Z     [Symbol(errored)]: null,
2023-03-22T19:20:45.0432430Z     [Symbol(kUniqueHeaders)]: null
2023-03-22T19:20:45.0432678Z   },
2023-03-22T19:20:45.0432890Z   response: {
2023-03-22T19:20:45.0433102Z     status: 403,
2023-03-22T19:20:45.0433419Z     statusText: 'Forbidden',
2023-03-22T19:20:45.0433672Z     headers: {
2023-03-22T19:20:45.0434005Z       'content-type': 'text/html',
2023-03-22T19:20:45.0434362Z       'content-length': '4714',
2023-03-22T19:20:45.0434670Z       connection: 'close',
2023-03-22T19:20:45.0435043Z       date: 'Wed, 22 Mar 2023 19:20:45 GMT',
2023-03-22T19:20:45.0435464Z       'last-modified': 'Tue, 21 Mar 2023 20:23:05 GMT',
2023-03-22T19:20:45.0435890Z       etag: '"f309608625dc9750dc5407c1c03ed7a9"',
2023-03-22T19:20:45.0436314Z       'x-amz-server-side-encryption': 'AES256',
2023-03-22T19:20:45.0436700Z       'accept-ranges': 'bytes',
2023-03-22T19:20:45.0437016Z       server: 'AmazonS3',
2023-03-22T19:20:45.0437445Z       'x-cache': 'LambdaGeneratedResponse from cloudfront',
2023-03-22T19:20:45.0438020Z       via: '1.1 caafbc8a9aa04b09dd564a3ddef60622.cloudfront.net (CloudFront)',
2023-03-22T19:20:45.0438473Z       'x-amz-cf-pop': 'IAD12-P3',
2023-03-22T19:20:45.0439006Z       'x-amz-cf-id': 'UL9E5byVqX-sTMZbRTt1zSSKg9wbe_fzveJT_7sUqQbOsQXkVhVqyw=='
2023-03-22T19:20:45.0439343Z     },
2023-03-22T19:20:45.0439558Z     config: {
2023-03-22T19:20:45.0441476Z       url: 'https://file.notion.so/f/t/a829b0ba-bfd2-478d-8ac3-4cb551bf00ca/Export-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip?id=116fced2-5ea5-40ed-b783-13b3e59b6d57&table=user_export&expirationTimestamp=1680117637294&signature=GMZwq2YdeavMzUIydB2UevrXmhsNtpu7ADFPxSkxIqg&download=true&downloadName=a829b0ba-bfd2-478d-8ac3-4cb551bf00ca%2FExport-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip',
2023-03-22T19:20:45.0442665Z       method: 'get',
2023-03-22T19:20:45.0442923Z       headers: [Object],
2023-03-22T19:20:45.0443357Z       baseURL: 'https://www.notion.so/api/v3',
2023-03-22T19:20:45.0443718Z       transformRequest: [Array],
2023-03-22T19:20:45.0444052Z       transformResponse: [Array],
2023-03-22T19:20:45.0444494Z       timeout: 0,
2023-03-22T19:20:45.0444801Z       adapter: [Function: httpAdapter],
2023-03-22T19:20:45.0445330Z       responseType: 'stream',
2023-03-22T19:20:45.0445720Z       xsrfCookieName: 'XSRF-TOKEN',
2023-03-22T19:20:45.0446125Z       xsrfHeaderName: 'X-XSRF-TOKEN',
2023-03-22T19:20:45.0446635Z       maxContentLength: -1,
2023-03-22T19:20:45.0446953Z       maxBodyLength: -1,
2023-03-22T19:20:45.0447476Z       validateStatus: [Function: validateStatus],
2023-03-22T19:20:45.0448035Z       transitional: [Object],
2023-03-22T19:20:45.0448310Z       data: undefined
2023-03-22T19:20:45.0448555Z     },
2023-03-22T19:20:45.0449006Z     request: <ref *1> ClientRequest {
2023-03-22T19:20:45.0449344Z       _events: [Object: null prototype],
2023-03-22T19:20:45.0449608Z       _eventsCount: 7,
2023-03-22T19:20:45.0449914Z       _maxListeners: undefined,
2023-03-22T19:20:45.0450192Z       outputData: [],
2023-03-22T19:20:45.0450448Z       outputSize: 0,
2023-03-22T19:20:45.0450702Z       writable: true,
2023-03-22T19:20:45.0450958Z       destroyed: false,
2023-03-22T19:20:45.0451190Z       _last: true,
2023-03-22T19:20:45.0451450Z       chunkedEncoding: false,
2023-03-22T19:20:45.0451730Z       shouldKeepAlive: false,
2023-03-22T19:20:45.0452093Z       maxRequestsOnConnectionReached: false,
2023-03-22T19:20:45.0452447Z       _defaultKeepAlive: true,
2023-03-22T19:20:45.0452798Z       useChunkedEncodingByDefault: false,
2023-03-22T19:20:45.0453086Z       sendDate: false,
2023-03-22T19:20:45.0453394Z       _removedConnection: false,
2023-03-22T19:20:45.0453679Z       _removedContLen: false,
2023-03-22T19:20:45.0453948Z       _removedTE: false,
2023-03-22T19:20:45.0454250Z       strictContentLength: false,
2023-03-22T19:20:45.0454533Z       _contentLength: 0,
2023-03-22T19:20:45.0454776Z       _hasBody: true,
2023-03-22T19:20:45.0455234Z       _trailer: '',
2023-03-22T19:20:45.0455501Z       finished: true,
2023-03-22T19:20:45.0455762Z       _headerSent: true,
2023-03-22T19:20:45.0456020Z       _closed: false,
2023-03-22T19:20:45.0456260Z       socket: [TLSSocket],
2023-03-22T19:20:45.0457997Z       _header: 'GET /f/t/a829b0ba-bfd2-478d-8ac3-4cb551bf00ca/Export-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip?id=116fced2-5ea5-40ed-b783-13b3e59b6d57&table=user_export&expirationTimestamp=1680117637294&signature=GMZwq2YdeavMzUIydB2UevrXmhsNtpu7ADFPxSkxIqg&download=true&downloadName=a829b0ba-bfd2-478d-8ac3-4cb551bf00ca%2FExport-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip HTTP/1.1\r\n' +
2023-03-22T19:20:45.0460731Z         'Accept: application/json, text/plain, */*\r\n' +
2023-03-22T19:20:45.0462115Z         'Cookie: token_v2=***\r\n' +
2023-03-22T19:20:45.0462715Z         'User-Agent: axios/0.21.4\r\n' +
2023-03-22T19:20:45.0463285Z         'Host: file.notion.so\r\n' +
2023-03-22T19:20:45.0463641Z         'Connection: close\r\n' +
2023-03-22T19:20:45.0463936Z         '\r\n',
2023-03-22T19:20:45.0464187Z       _keepAliveTimeout: 0,
2023-03-22T19:20:45.0464678Z       _onPendingData: [Function: nop],
2023-03-22T19:20:45.0464957Z       agent: [Agent],
2023-03-22T19:20:45.0465220Z       socketPath: undefined,
2023-03-22T19:20:45.0465533Z       method: 'GET',
2023-03-22T19:20:45.0466071Z       maxHeaderSize: undefined,
2023-03-22T19:20:45.0466746Z       insecureHTTPParser: undefined,
2023-03-22T19:20:45.0467093Z       joinDuplicateHeaders: undefined,
2023-03-22T19:20:45.0468983Z       path: '/f/t/a829b0ba-bfd2-478d-8ac3-4cb551bf00ca/Export-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip?id=116fced2-5ea5-40ed-b783-13b3e59b6d57&table=user_export&expirationTimestamp=1680117637294&signature=GMZwq2YdeavMzUIydB2UevrXmhsNtpu7ADFPxSkxIqg&download=true&downloadName=a829b0ba-bfd2-478d-8ac3-4cb551bf00ca%2FExport-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip',
2023-03-22T19:20:45.0470219Z       _ended: false,
2023-03-22T19:20:45.0470663Z       res: [IncomingMessage],
2023-03-22T19:20:45.0470940Z       aborted: false,
2023-03-22T19:20:45.0471204Z       timeoutCb: null,
2023-03-22T19:20:45.0471726Z       upgradeOrConnect: false,
2023-03-22T19:20:45.0471984Z       parser: null,
2023-03-22T19:20:45.0472249Z       maxHeadersCount: null,
2023-03-22T19:20:45.0472583Z       reusedSocket: false,
2023-03-22T19:20:45.0472931Z       host: 'file.notion.so',
2023-03-22T19:20:45.0473248Z       protocol: 'https:',
2023-03-22T19:20:45.0473550Z       _redirectable: [Writable],
2023-03-22T19:20:45.0473843Z       [Symbol(kCapture)]: false,
2023-03-22T19:20:45.0476331Z       [Symbol(kBytesWritten)]: 0,
2023-03-22T19:20:45.0477508Z       [Symbol(kEndCalled)]: true,
2023-03-22T19:20:45.0477837Z       [Symbol(kNeedDrain)]: false,
2023-03-22T19:20:45.0478625Z       [Symbol(corked)]: 0,
2023-03-22T19:20:45.0479016Z       [Symbol(kOutHeaders)]: [Object: null prototype],
2023-03-22T19:20:45.0481669Z       [Symbol(errored)]: null,
2023-03-22T19:20:45.0482030Z       [Symbol(kUniqueHeaders)]: null
2023-03-22T19:20:45.0482318Z     },
2023-03-22T19:20:45.0482571Z     data: IncomingMessage {
2023-03-22T19:20:45.0482977Z       _readableState: [ReadableState],
2023-03-22T19:20:45.0483462Z       _events: [Object: null prototype],
2023-03-22T19:20:45.0483742Z       _eventsCount: 1,
2023-03-22T19:20:45.0484053Z       _maxListeners: undefined,
2023-03-22T19:20:45.0484527Z       socket: [TLSSocket],
2023-03-22T19:20:45.0484802Z       httpVersionMajor: 1,
2023-03-22T19:20:45.0485118Z       httpVersionMinor: 1,
2023-03-22T19:20:45.0485485Z       httpVersion: '1.1',
2023-03-22T19:20:45.0485753Z       complete: true,
2023-03-22T19:20:45.0486014Z       rawHeaders: [Array],
2023-03-22T19:20:45.0486295Z       rawTrailers: [],
2023-03-22T19:20:45.0486800Z       joinDuplicateHeaders: undefined,
2023-03-22T19:20:45.0487101Z       aborted: false,
2023-03-22T19:20:45.0487676Z       upgrade: false,
2023-03-22T19:20:45.0487999Z       url: '',
2023-03-22T19:20:45.0488251Z       method: null,
2023-03-22T19:20:45.0488754Z       statusCode: 403,
2023-03-22T19:20:45.0489188Z       statusMessage: 'Forbidden',
2023-03-22T19:20:45.0489479Z       client: [TLSSocket],
2023-03-22T19:20:45.0489734Z       _consuming: false,
2023-03-22T19:20:45.0490000Z       _dumped: false,
2023-03-22T19:20:45.0490266Z       req: [ClientRequest],
2023-03-22T19:20:45.0492147Z       responseUrl: 'https://file.notion.so/f/t/a829b0ba-bfd2-478d-8ac3-4cb551bf00ca/Export-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip?id=116fced2-5ea5-40ed-b783-13b3e59b6d57&table=user_export&expirationTimestamp=1680117637294&signature=GMZwq2YdeavMzUIydB2UevrXmhsNtpu7ADFPxSkxIqg&download=true&downloadName=a829b0ba-bfd2-478d-8ac3-4cb551bf00ca%2FExport-dfd8e5dd-2331-4c84-82be-d4a3fbf4324f.zip',
2023-03-22T19:20:45.0493040Z       redirects: [],
2023-03-22T19:20:45.0493335Z       [Symbol(kCapture)]: false,
2023-03-22T19:20:45.0493650Z       [Symbol(kHeaders)]: [Object],
2023-03-22T19:20:45.0493952Z       [Symbol(kHeadersCount)]: 26,
2023-03-22T19:20:45.0494323Z       [Symbol(kTrailers)]: null,
2023-03-22T19:20:45.0494827Z       [Symbol(kTrailersCount)]: 0
2023-03-22T19:20:45.0495099Z     }
2023-03-22T19:20:45.0495316Z   },
2023-03-22T19:20:45.0495625Z   isAxiosError: true,
2023-03-22T19:20:45.0495890Z   toJSON: [Function: toJSON]
2023-03-22T19:20:45.0496299Z }
2023-03-22T19:20:45.0512745Z ##[error]Process completed with exit code 1.
2023-03-22T19:20:45.0596496Z Post job cleanup.
2023-03-22T19:20:45.2558221Z [command]/usr/bin/git version
2023-03-22T19:20:45.2653691Z git version 2.39.2
2023-03-22T19:20:45.2764089Z Temporarily overriding HOME='/home/runner/work/_temp/743753f0-35ae-494d-b3d0-a0584eefa9d7' before making global git config changes
2023-03-22T19:20:45.2773096Z Adding repository directory to the temporary git global config as a safe directory
2023-03-22T19:20:45.2788217Z [command]/usr/bin/git config --global --add safe.directory /home/runner/work/notion-backup/notion-backup
2023-03-22T19:20:45.2895470Z [command]/usr/bin/git config --local --name-only --get-regexp core\.sshCommand
2023-03-22T19:20:45.2956807Z [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :"
2023-03-22T19:20:45.3284660Z [command]/usr/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader
2023-03-22T19:20:45.3322039Z http.https://github.com/.extraheader
2023-03-22T19:20:45.3344055Z [command]/usr/bin/git config --local --unset-all http.https://github.com/.extraheader
2023-03-22T19:20:45.3395161Z [command]/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :"
2023-03-22T19:20:45.4023419Z Cleaning up orphan processes
.github/workflows/notion-backup.yaml
name: "Notion backup"

on:
  push:
    branches:
      - master
  schedule:
    -   cron: "0 */4 * * *"
  workflow_dispatch:

jobs:
  backup:
    runs-on: ubuntu-latest
    name: Backup
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v3

      - uses: actions/setup-node@v2
        with:
          node-version: '18'

      - name: Delete previous backup
        run: rm -rf markdown html *.zip
      
      - name: Setup dependencies
        run: npm install -g notion-backup

      - name: Run backup
        run: notion-backup
        env:
          NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }}
          NOTION_SPACE_ID: ${{ secrets.NOTION_SPACE_ID }}
          NODE_OPTIONS: "--max-http-header-size 15000"
      
      - name: Delete zips
        run: |
          rm -f *.zip
          rm -f markdown/*-Part*.zip
          rm -f html/*-Part*.zip
      - name: Commit changes
        run: |
          git config user.name github-actions
          git config user.email [email protected]
          git add .
          git commit -m "Automated snapshot"
          git push

No Output?

Hello,

Thank you very much for creating this wonderful tool! 👍🏼

I have cloned / configured the repo and was expecting the results to show up in the same repository after the first run since there was no repository_const or something in the instructions. Now the first run was completed successfully but no files in sight, I received an email from notion that the backup-zip has been created, so that worked.
Where can I find the files?

Screenshot 2021-05-14 at 20 58 47

Screenshot 2021-05-14 at 21 00 31

Error: Request failed with status code 400

Thanks for releasing this!

Ever seen / any ideas about this 400 error?

...
Pages exported: 558
Pages exported: 558
Pages exported: 558
Error: Request failed with status code 400
    at createError (/Users/yang/proj/mono/sandbox/notion-exp/notion-backup/node_modules/axios/lib/core/createError.js:16:15)
    at settle (/Users/yang/proj/mono/sandbox/notion-exp/notion-backup/node_modules/axios/lib/core/settle.js:17:12)
    at RedirectableRequest.handleResponse (/Users/yang/proj/mono/sandbox/notion-exp/notion-backup/node_modules/axios/lib/adapters/http.js:231:9)
    at RedirectableRequest.emit (node:events:514:28)
    at RedirectableRequest._processResponse (/Users/yang/proj/mono/sandbox/notion-exp/notion-backup/node_modules/follow-redirects/index.js:403:10)
    at RedirectableRequest._onNativeResponse (/Users/yang/proj/mono/sandbox/notion-exp/notion-backup/node_modules/follow-redirects/index.js:57:10)
    at Object.onceWrapper (node:events:629:26)
    at ClientRequest.emit (node:events:514:28)
    at HTTPParser.parserOnIncomingClient (node:_http_client:700:27)
    at HTTPParser.parserOnHeadersComplete (node:_http_common:119:17) {
  config: {
    url: 'https://file.notion.so/f/t/d374fab0-b9f1-4e7a-b5e2-2328aca3b7d8/Export-eae043bb-1074-4aa0-81e1-cf33c8779fb4.zip?id=2cf9c565-dca6-40f8-8692-11e23bde7797&table=user_export&spaceId=&expirationTimestamp=1711651328435&signature=EkjU7P1S3xqkEI5ctuy_o219zt3Q8xqxtx6IIfg4TIo&download=true&downloadName=d344fab0-b8f1-4e7a-b5e2-2328aca3b7d8%2FExport-eae0c3bb-1074-4a80-81e1-cf33c8779fb4.zip',
    method: 'get',
...
  response: {
    status: 400,
    statusText: 'PermissionCheckError',
    headers: {
      'content-length': '205',
      connection: 'close',
      server: 'CloudFront',
      date: 'Thu, 21 Mar 2024 07:35:33 GMT',
      location: 'https://www.notion.so/login',
      'x-cache': 'Miss from cloudfront',
      via: '1.1 7bd77f679e52167da498bb1812108688.cloudfront.net (CloudFront)',
      'x-amz-cf-pop': 'SFO5-C1',
      'x-amz-cf-id': 'hzFL2cOJUHFqfN8Oppe6cD14vsEAtkKn7GWAoDZCeZ7MQcCddxV_Vw==',
      'content-security-policy': "default-src 'none'; media-src 'self'; style-src 'unsafe-inline'"
    },
...

When I visit that URL in my (logged-in) browser I can download it. (It is the actual export.)

Header overflow issue

Hi!

I found it sometimes causes header overflow problem like below.

Error: Parse Error: Header overflow
    at TLSSocket.socketOnData (_http_client.js:474:22)
    at TLSSocket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:272:9)
    at TLSSocket.Readable.push (_stream_readable.js:213:10)
    at TLSWrap.onStreamRead (internal/stream_base_commons.js:1[8]
    ...

In this case, I could solve this problem by adding a node option to workflow file.

      - name: Run backup
        run: notion-backup
        env:
          NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }}
          NOTION_SPACE_ID: ${{ secrets.NOTION_SPACE_ID }}
          NODE_OPTIONS: "--max-http-header-size 15000"    # ADD THIS LINE

Error: Process completed with exit code 1.

Hi!

There was an error occurred when backup run: "Error: Process completed with exit code 1."

I have checked my NOTION_SPACE_ID and NOTION_TOKEN yet.

NOTION_TOKEN may be token_v2?
and should '-' in NOTION_SPACE_ID?

I received mail from notion,

Your Notion export is ready
Click [here] to download it. The link will expire after 30 days.

but backup also stop with error "Error: Process completed with exit code 1."

Error during first run

Hi, thanks for publishing this. I am trying it out but I get this error during the export:

[...]
Pages exported: 966
Task error: You cannot pipe after data has been emitted from the response.
Task error: You cannot pipe after data has been emitted from the response.
Task error: You cannot pipe after data has been emitted from the response.
Task error: You cannot pipe after data has been emitted from the response.
Task error: You cannot pipe after data has been emitted from the response.
(node:1837) UnhandledPromiseRejectionWarning: Error: end of central directory record signature not found
at /opt/hostedtoolcache/node/12.22.3/x64/lib/node_modules/notion-backup/node_modules/yauzl/index.js:187:14
at /opt/hostedtoolcache/node/12.22.3/x64/lib/node_modules/notion-backup/node_modules/yauzl/index.js:631:5
at /opt/hostedtoolcache/node/12.22.3/x64/lib/node_modules/notion-backup/node_modules/fd-slicer/index.js:32:7
at FSReqCallback.wrapper [as oncomplete] (fs.js:520:5)
(node:1837) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:1837) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Suddenly failing "Invalid input.", "No task status, waiting".

two separate actions-based workflows of mine are suddenly failing. Any leads? I have confirmed all 3 secrets are correct.

Enqueued task [redacted]
No task status, waiting. Task was:
{
  "id": "redacted",
  "eventName": "exportSpace",
  "request": {
    "spaceId": "***",
    "exportOptions": {
      "exportType": "markdown",
      "timeZone": "America/New_York",
      "locale": "en"
    }
  },
  "actor": {
    "table": "notion_user",
    "id": "redacted"
  },
  "rootRequest": {
    "eventName": "exportSpace",
    "requestId": "redacted"
  },
  "headers": {
    "ip": "[13](redacted:6:14).66.79.84",
    "cityFromIp": "San Antonio",
    "countryCodeFromIp": "US",
    "subdivision1FromIp": "US-TX"
  },
  "equeuedAt": [16](redactedstep:6:18),
  "error": "Invalid input.",
  "state": "retryable_failure"
}

Then after a few repeats of that message:

/opt/hostedtoolcache/node/18.18.0/x64/lib/node_modules/notion-backup/node_modules/yauzl/index.js:187
    callback(new Error("end of central directory record signature not found"));
             ^

Error: end of central directory record signature not found
    at /opt/hostedtoolcache/node/18.18.0/x64/lib/node_modules/notion-backup/node_modules/yauzl/index.js:187:14
    at /opt/hostedtoolcache/node/18.18.0/x64/lib/node_modules/notion-backup/node_modules/yauzl/index.js:631:5
    at /opt/hostedtoolcache/node/18.18.0/x64/lib/node_modules/notion-backup/node_modules/fd-slicer/index.js:32:7
    at FSReqCallback.wrapper [as oncomplete] (node:fs:684:5)

Node.js v18.18.0
Error: Process completed with exit code 1.

Error: The operation was canceled. when running the Run Backup step

In the 'Run Backup' step it seems to go wrong. Any ideas what is happening? Cheers.

Pages exported: 3593
Pages exported: 3593
Enqueued task 598be3a9-0e63-45b2-b8e1-ccd7fa45bae8
Pages exported: 21
Pages exported: 41
Pages exported: 68
Pages exported: 82
Pages exported: 93
Pages exported: 111
Pages exported: 118
Pages exported: 123
Pages exported: 126
Pages exported: 139
Pages exported: 154
Pages exported: 157
Pages exported: 158
Pages exported: 160
Pages exported: 162
Pages exported: 166
Pages exported: 180
Pages exported: 206
Pages exported: 214
Pages exported: 233
Pages exported: 246
Pages exported: 253
Pages exported: 267
Pages exported: 302
##[debug]Re-evaluate condition on job cancellation for step: 'Run backup'.
Pages exported: 321
Error: The operation was canceled.
##[debug]System.OperationCanceledException: The operation was canceled.
##[debug]   at System.Threading.CancellationToken.ThrowOperationCanceledException()
##[debug]   at GitHub.Runner.Sdk.ProcessInvoker.ExecuteAsync(String workingDirectory, String fileName, String arguments, IDictionary`2 environment, Boolean requireExitCodeZero, Encoding outputEncoding, Boolean killProcessOnCancel, Channel`1 redirectStandardIn, Boolean inheritConsoleHandler, Boolean keepStandardInOpen, Boolean highPriorityProcess, CancellationToken cancellationToken)
##[debug]   at GitHub.Runner.Common.ProcessInvokerWrapper.ExecuteAsync(String workingDirectory, String fileName, String arguments, IDictionary`2 environment, Boolean requireExitCodeZero, Encoding outputEncoding, Boolean killProcessOnCancel, Channel`1 redirectStandardIn, Boolean inheritConsoleHandler, Boolean keepStandardInOpen, Boolean highPriorityProcess, CancellationToken cancellationToken)
##[debug]   at GitHub.Runner.Worker.Handlers.DefaultStepHost.ExecuteAsync(IExecutionContext context, String workingDirectory, String fileName, String arguments, IDictionary`2 environment, Boolean requireExitCodeZero, Encoding outputEncoding, Boolean killProcessOnCancel, Boolean inheritConsoleHandler, String standardInInput, CancellationToken cancellationToken)
##[debug]   at GitHub.Runner.Worker.Handlers.ScriptHandler.RunAsync(ActionRunStage stage)
##[debug]   at GitHub.Runner.Worker.ActionRunner.RunAsync()
##[debug]   at GitHub.Runner.Worker.StepsRunner.RunStepAsync(IStep step, CancellationToken jobCancellationToken)
##[debug]Finishing: Run backup

Create backup in pdf

We are getting Notion backup with two copies stored in md and html with this action.

Is it possible to select either pdf or just md or html format with API?

This exceeds GitHub's file size limit of 100.00 MB

remote: error: See http://git.io/iEPt8g for more information.
remote: error: File html/Export-db06c75a-edcf-44fe-89f4-8b90df378eda-Part-1.zip is 162.01 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: File markdown/Export-7b3dc522-7a1e-472c-940b-6abf10850007-Part-1.zip is 159.20 MB; this exceeds GitHub's file size limit of 100.00 MB

Can't find backup files - Nothing to commit

When I run the action, everything seems to run successfully and I get an email from Notion. The backup step ends with "Pages exported: 991" and then it deletes the zips, and runs commit. However, I do not see any backup files added to the repo. On the commit step it shows this:

Run elstudio/actions-js-build/commit@v3
/usr/bin/docker run [ ... ]
Checking for uncommitted changes in the git working tree.
0
Working tree clean. Nothing to commit.

I assume nothing is added because it says nothing to commit - any idea how I can resolve this?

Thank you

Error at the "Run backup" step

I am recieving this error at the "Run backup" step.

Run notion-backup
  notion-backup
  shell: /usr/bin/bash -e {0}
  env:
    NOTION_TOKEN: ***
    NOTION_SPACE_ID: ***
Enqueued task <enqueued_task>
TypeError: Cannot read property 'pagesExported' of undefined
    at exportFromNotion (/opt/hostedtoolcache/node/12.22.1/x64/lib/node_modules/notion-backup/notion-backup.js:61:51)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async run (/opt/hostedtoolcache/node/12.22.1/x64/lib/node_modules/notion-backup/notion-backup.js:90:3)
Error: Process completed with exit code 1.

Missing output files

Hi Darobin!

First of all, thanks for creating a simple workflow for automating notion backups. I forked the repository and have successfully ran the workflow through github actions. It says the workflow was run successfully.

Unfortunately, I cant seem to locate the output files in my github repo. Do I first need to create the markdown and html directories? Please let me know thanks.

enhancements

Hi, when Notion workspace content has a lot of content, if the
Exporting backup files in Markdown format and HTML format will cause Action to be very time consuming, so I would like to add
an optional environment parameter, the default is to export both formats, but when the optional environment parameter is configured, the exported
format is the value of the optional environment parameter
image
image

Action limit

Create a repo for your backup. You probably want it private.

I'm not sure if this counts as abuse of github's free action for public repositories, but if not one can add an encryption step to the action with a public key of their own and make the repository public, right?

Expiration

There is currently no practical way to automize this until Notion decide to add a backup endpoint to their official API, at which point this script will be able to use a proper authentication token.

What if I just put login information into the secret variable? Is it possible to implement an automation for that?

How to enable saving Subpages in exportSpace

Hi! Thanks so much for this cool github action.
It seems very helpful but when I reviewed the exports the subpage are not exported. Is there a way to enable that in the .js file.

Thanks so much for your reply.

ERROR: Job failed: execution took longer than 1h0m0s seconds

I got this error. Has anyone else had this issue too?

Executing "step_script" stage of the job script
Using docker image sha256:e96a212a8ca82ea842c95bd6f96e3fb3b03d1574275bf13de92170b4c8deb69c for python:3.8 with digest python@sha256:0bdd43369c583eb82a809fbe6908d6ec721b7a29f7d9dce427d70924baf0ab7b ...
$ cat >notion_export_gen.py <<EOL # collapsed multi-line command
$ git remote set-url origin https://${GITLAB_USER_ID}:${CI_PUSH_TOKEN}@gitlab.com/${CI_PROJECT_PATH}.git
$ git config --global user.email ${GITLAB_USER_EMAIL}
$ git config --global user.name ${GITLAB_USER_ID}
$ ./notion_export_gen.py && ./merge_gen.sh
Enqueued task 48b578ed-aec2-4c8b-a443-4b56d6f77737

Status: ?, pages exported: ?
Status: ?, pages exported: ?
Status: ?, pages exported: ?
Status: ?, pages exported: ?
ERROR: Job failed: execution took longer than 1h0m0s seconds

The opration was cancelled failure

Hi,

Thanks for the tool.
I haven't got the chance to make it work due the following error:

Pages exported: 835
Pages exported: [95](https://github.com/gmarokov/notion-backup/actions/runs/5050287943/jobs/9060814600#step:6:96)0
Pages exported: 1164
Pages exported: 1436
Pages exported: 1554
Error: The operation was canceled.

Any idea how to resolve it?
Thanks in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.