├── README.md ├── go.mod ├── go.sum └── main.go /README.md: -------------------------------------------------------------------------------- 1 | # Raindrop.io to Notion 2 | 3 | Script to migrate your bookmarks from Raindrop.io to Notion. Written in Go. 4 | 5 | ## How to use 6 | 7 | 0. Export bookmarks from Raindrop.io 8 | 9 | https://app.raindrop.io/settings/backups (html) 10 | 11 | 1. Create Notion integration 12 | 13 | Follow offical Notion documentation and use default settings. 14 | https://developers.notion.com/docs/getting-started 15 | 16 | 2. Put your integration secret key 17 | 18 | [NotionSecret](https://github.com/kirillshevch/raindrop_to_notion/blob/master/main.go#L14) 19 | 20 | 3. Create a new page in Notion and share for following integration 21 | 22 | 4. Put your page UUID (for e.g. `e03226c471c94116b8fdfdeefb02b74565`) 23 | 24 | [ParentID](https://github.com/kirillshevch/raindrop_to_notion/blob/master/main.go#L13) 25 | 26 | 5. Copy your exported HTML backup from Raindrop to local script folder and rename to `import.html` 27 | 28 | ```sh 29 | cp ~/Downloads/Raindrop.io.html ~/workspace/raindrop_to_notion/import.html 30 | ``` 31 | 32 | 6. Install dependencies and run the script 33 | 34 | ```sh 35 | go get 36 | go run main.go 37 | ``` -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module raindrop_to_notion 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/PuerkitoBio/goquery v1.8.0 7 | github.com/dstotijn/go-notion v0.6.0 8 | ) 9 | 10 | require ( 11 | github.com/andybalholm/cascadia v1.3.1 // indirect 12 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect 13 | ) 14 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U= 2 | github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI= 3 | github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= 4 | github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= 5 | github.com/dstotijn/go-notion v0.6.0 h1:/Jk4CQVn3uQjR/e+VPxZXfh+28ySS/00IS5HxY9YDuQ= 6 | github.com/dstotijn/go-notion v0.6.0/go.mod h1:oxd+T9Wxduj5ZN7MRiHWtyGhGZLUFsUpZHMLS4uI1Qc= 7 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 8 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 9 | golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 10 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= 11 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 12 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 13 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 14 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 15 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 16 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 17 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 18 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 19 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 20 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 21 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 22 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "log" 7 | "os" 8 | 9 | "github.com/PuerkitoBio/goquery" 10 | "github.com/dstotijn/go-notion" 11 | ) 12 | 13 | const ParentID string = "" 14 | const NotionSecret string = "" 15 | 16 | func main() { 17 | data, err := os.Open("import.html") 18 | 19 | if err != nil { 20 | log.Fatal(err) 21 | } 22 | 23 | doc, err := goquery.NewDocumentFromReader(data) 24 | if err != nil { 25 | log.Fatal(err) 26 | } 27 | 28 | // Notion Client 29 | client := notion.NewClient(NotionSecret) 30 | 31 | // Find a Category 32 | doc.Find("dt").Each(func(i int, s *goquery.Selection) { 33 | category := s.Find("h3").Text() 34 | 35 | if category != "" { 36 | params := notion.CreatePageParams{ 37 | 38 | ParentType: notion.ParentTypePage, 39 | ParentID: ParentID, 40 | 41 | Title: []notion.RichText{ 42 | { 43 | Text: ¬ion.Text{ 44 | Content: category, 45 | }, 46 | }, 47 | }, 48 | } 49 | 50 | // Create a Page 51 | page, err := client.CreatePage(context.Background(), params) 52 | 53 | if err != nil { 54 | fmt.Println("Cant create page: ", err) 55 | } else { 56 | s.Find("dt").Each(func(i int, s *goquery.Selection) { 57 | a := s.Find("a") 58 | link, _ := a.Attr("href") 59 | 60 | // Add Bookmark 61 | _, err := client.AppendBlockChildren(context.Background(), page.ID, []notion.Block{ 62 | { 63 | Object: "block", 64 | Type: notion.BlockTypeBookmark, 65 | Bookmark: ¬ion.Bookmark{ 66 | URL: link, 67 | Caption: []notion.RichText{ 68 | { 69 | Text: ¬ion.Text{ 70 | Content: a.Text(), 71 | }, 72 | }, 73 | }, 74 | }, 75 | }, 76 | }) 77 | 78 | if err != nil { 79 | fmt.Println(err) 80 | } else { 81 | fmt.Println("Added: ", link) 82 | } 83 | }) 84 | } 85 | } 86 | }) 87 | } 88 | --------------------------------------------------------------------------------