forked from kjk/notionapi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
get_record_values.go
153 lines (139 loc) · 3.8 KB
/
get_record_values.go
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package notionapi
import (
"encoding/json"
"fmt"
)
// /api/v3/getRecordValues request
type getRecordValuesRequest struct {
Requests []RecordRequest `json:"requests"`
}
// RecordRequest represents argument to GetRecordValues
type RecordRequest struct {
Table string `json:"table"`
ID string `json:"id"`
}
// Record represents a polymorphic record
type Record struct {
// fields returned by the server
Role string `json:"role"`
// polymorphic value of the record, which we decode into Block, Space etc.
Value json.RawMessage `json:"value"`
// fields set from Value based on type
ID string `json:"-"`
Table string `json:"-"`
Block *Block `json:"-"`
Space *Space `json:"-"`
User *User `json:"-"`
Collection *Collection `json:"-"`
CollectionView *CollectionView `json:"-"`
Comment *Comment `json:"-"`
Discussion *Discussion `json:"-"`
// TODO: add more types
}
// GetRecordValuesResponse represents response to /api/v3/getRecordValues api
// Note: it depends on Table type in request
type GetRecordValuesResponse struct {
Results []*Record `json:"results"`
RawJSON map[string]interface{} `json:"-"`
}
// table is not always present in Record returned by the server
// so must be provided based on what was asked
func parseRecord(table string, r *Record) error {
// it's ok if some records don't return a value
if len(r.Value) == 0 {
return nil
}
if r.Table == "" {
r.Table = table
} else {
// TODO: probably never happens
panicIf(r.Table != table)
}
// set Block/Space etc. based on TableView type
var pRawJSON *map[string]interface{}
var obj interface{}
switch table {
case TableBlock:
r.Block = &Block{}
obj = r.Block
pRawJSON = &r.Block.RawJSON
case TableUser:
r.User = &User{}
obj = r.User
pRawJSON = &r.User.RawJSON
case TableSpace:
r.Space = &Space{}
obj = r.Space
pRawJSON = &r.Space.RawJSON
case TableCollection:
r.Collection = &Collection{}
obj = r.Collection
pRawJSON = &r.Collection.RawJSON
case TableCollectionView:
r.CollectionView = &CollectionView{}
obj = r.CollectionView
pRawJSON = &r.CollectionView.RawJSON
case TableDiscussion:
r.Discussion = &Discussion{}
obj = r.Discussion
pRawJSON = &r.Discussion.RawJSON
case TableComment:
r.Comment = &Comment{}
obj = r.Comment
pRawJSON = &r.Comment.RawJSON
}
if obj == nil {
return fmt.Errorf("unsupported table '%s'", r.Table)
}
if false {
if table == TableCollectionView {
s := string(r.Value)
fmt.Printf("collection_view json:\n%s\n\n", s)
}
}
if err := json.Unmarshal(r.Value, pRawJSON); err != nil {
return err
}
id := (*pRawJSON)["id"]
if id != nil {
r.ID = id.(string)
}
if err := json.Unmarshal(r.Value, &obj); err != nil {
return err
}
return nil
}
// GetBlockRecords executes a raw API call /api/v3/getRecordValues
// to get records for blocks with given ids
func (c *Client) GetBlockRecords(ids []string) (*GetRecordValuesResponse, error) {
records := make([]RecordRequest, len(ids))
for pos, id := range ids {
dashID := ToDashID(id)
if !IsValidDashID(dashID) {
return nil, fmt.Errorf("'%s' is not a valid notion id", id)
}
records[pos].Table = TableBlock
records[pos].ID = dashID
}
return c.GetRecordValues(records)
}
// GetRecordValues executes a raw API call /api/v3/getRecordValues
func (c *Client) GetRecordValues(records []RecordRequest) (*GetRecordValuesResponse, error) {
req := &getRecordValuesRequest{
Requests: records,
}
apiURL := "/api/v3/getRecordValues"
var rsp GetRecordValuesResponse
var err error
if rsp.RawJSON, err = doNotionAPI(c, apiURL, req, &rsp); err != nil {
return nil, err
}
for idx, r := range rsp.Results {
table := records[idx].Table
err = parseRecord(table, r)
if err != nil {
return nil, err
}
}
return &rsp, nil
}