notion 1.0.2 → 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +75 -7
- data/lib/notion_api/core.rb +61 -5
- data/lib/notion_api/notion_types/collection_view_blocks.rb +314 -217
- data/lib/notion_api/notion_types/template.rb +9 -1
- data/lib/notion_api/utils.rb +142 -56
- data/lib/notion_api/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 260bf00a0f7ffc3dec1cbf364c69815e5dcbf829677710e5b740bd58476ca9f7
|
4
|
+
data.tar.gz: 7220c9399aca9756e4773dda4b5fbdd573bd3decfe32758797ea11e309e6f0e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5933ae50944a7f77e6c68410d4291935b769869b59f71817dabd98df2e5a50f86f6200c4b7bc9800249e274c4e3ecd1e5d339df66cb08e258c50c25308e3bba
|
7
|
+
data.tar.gz: e01f29a16242b81b586d7852062efe030a760f30620096a691be6ee47c45de3d5f1b1ef7ce0f166a6c3328e3972ca470aaffd51b235f8d9f2f6c8b6ead69c193
|
data/README.md
CHANGED
@@ -1,5 +1,30 @@
|
|
1
|
+
|
2
|
+
|
1
3
|
# Unofficial Notion Client for Ruby.
|
2
|
-
[![
|
4
|
+
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/f13e49a8807e4fe297273f48bd8d7a61)](https://app.codacy.com/gh/danmurphy1217/notion-ruby?utm_source=github.com&utm_medium=referral&utm_content=danmurphy1217/notion-ruby&utm_campaign=Badge_Grade)
|
5
|
+
[![Build Status](https://travis-ci.com/danmurphy1217/notion-ruby.svg?branch=master)](https://travis-ci.com/danmurphy1217/notion-ruby) [![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop-hq/rubocop) [![Gem Version](https://badge.fury.io/rb/notion.svg)](https://badge.fury.io/rb/notion)
|
6
|
+
|
7
|
+
- Read the [blog post](https://towardsdatascience.com/introducing-the-notion-api-ruby-gem-d47d4a6ef0ca), which outlines why I built this and some of the functionality.
|
8
|
+
- Check out the [Gem](https://rubygems.org/gems/notion)!
|
9
|
+
|
10
|
+
## Table of Contents
|
11
|
+
- [Unofficial Notion Client for Ruby.](#unofficial-notion-client-for-ruby)
|
12
|
+
- [Table of Contents](#table-of-contents)
|
13
|
+
- [Getting Started](#getting-started)
|
14
|
+
- [Installation](#installation)
|
15
|
+
- [Retrieving a Page](#retrieving-a-page)
|
16
|
+
- [Retrieving a CollectionView Page](#retrieving-a-collectionview-page)
|
17
|
+
- [Retrieving a Block within the Page](#retrieving-a-block-within-the-page)
|
18
|
+
- [Get a Block](#get-a-block)
|
19
|
+
- [Get a Collection View](#get-a-collection-view)
|
20
|
+
- [Creating New Blocks](#creating-new-blocks)
|
21
|
+
- [Create a block whose parent is the page](#create-a-block-whose-parent-is-the-page)
|
22
|
+
- [Create a block whose parent is another block](#create-a-block-whose-parent-is-another-block)
|
23
|
+
- [Creating New Collections](#creating-new-collections)
|
24
|
+
- [Updating Collection View Cells](#updating-collection-view-cells)
|
25
|
+
- [Troubleshooting](#troubleshooting)
|
26
|
+
- [No results returned when attempting to get a page](#no-results-returned-when-attempting-to-get-a-page)
|
27
|
+
- [Retrieve a full-page Collection View](#retrieve-a-full-page-collection-view)
|
3
28
|
|
4
29
|
## Getting Started
|
5
30
|
### Installation
|
@@ -9,7 +34,7 @@ gem install notion
|
|
9
34
|
```
|
10
35
|
Then, place this at the top of your file:
|
11
36
|
```ruby
|
12
|
-
require 'notion_api'
|
37
|
+
require 'notion_api'
|
13
38
|
```
|
14
39
|
To get started using the gem, you'll first need to retrieve your token_v2 credentials by signing into Notion online, navigating to the developer tools, inspecting the cookies, and finding the value associated with the **token_v2** key.
|
15
40
|
|
@@ -40,6 +65,8 @@ The following attributes can be read from any block class instance:
|
|
40
65
|
To update the title of the page:
|
41
66
|
![Update the title of a page](https://github.com/danmurphy1217/notion-ruby/blob/master/gifs/change_title.gif)
|
42
67
|
|
68
|
+
## Retrieving a CollectionView Page
|
69
|
+
This is achieved by passing the ID of the Collection View to the `get_page` method. Currently, the full URL of a Collection View Page is not supported (next up on the features list!). Once you retrieve the Collection View Page, all of the methods exposed to a normal Collection View instance are available (such as `.rows`, `.row(<row_id>)`, and all else outlined in [Updating a Collection](#updating-collection-view-cells)).
|
43
70
|
## Retrieving a Block within the Page
|
44
71
|
Now that you have retrieved a Notion Page, you have full access to the blocks on that page. You can retrieve a specific block or collection view, retrieve all children IDs (array of children IDs), or retrieve all children (array of children class instances).
|
45
72
|
|
@@ -94,7 +121,7 @@ For example:
|
|
94
121
|
```
|
95
122
|
For example:
|
96
123
|
![move a block](https://github.com/danmurphy1217/notion-ruby/blob/master/gifs/move_before_and_after.gif)
|
97
|
-
### Get a Collection View
|
124
|
+
### Get a Collection View
|
98
125
|
To retrieve a collection, you use the `get_collection` method. This method is designed to work with Table collections, but the codebase is actively being updated to support others:
|
99
126
|
```ruby
|
100
127
|
>>> @page = @client.get_page("https://www.notion.so/danmurphy/TEST-PAGE-d2ce338f19e847f586bd17679f490e66")
|
@@ -128,8 +155,8 @@ Here's a high-level example:
|
|
128
155
|
The block types available to the `create` method are:
|
129
156
|
1. `DividerBlock`
|
130
157
|
2. `TodoBlock`
|
131
|
-
3. `CodeBlock`
|
132
|
-
4. `HeaderBlock`
|
158
|
+
3. `CodeBlock`
|
159
|
+
4. `HeaderBlock`
|
133
160
|
5. `SubHeaderBlock`
|
134
161
|
6. `SubSubHeaderBlock`
|
135
162
|
7. `PageBlock`
|
@@ -139,8 +166,8 @@ The block types available to the `create` method are:
|
|
139
166
|
11. `QuoteBlock`
|
140
167
|
12. `CalloutBlock`
|
141
168
|
13. `LatexBlock`
|
142
|
-
14. `TextBlock`
|
143
|
-
15. `ImageBlock` and
|
169
|
+
14. `TextBlock`
|
170
|
+
15. `ImageBlock` and
|
144
171
|
16. `TableOfContentsBlock`.
|
145
172
|
If you want to create a collection, utilize the `create_collection` method [defined below].
|
146
173
|
|
@@ -247,3 +274,44 @@ The first argument passed to `create_collection` determines which type of collec
|
|
247
274
|
3. calendar
|
248
275
|
4. timeline
|
249
276
|
5. gallery
|
277
|
+
|
278
|
+
## Updating Collection View Cells
|
279
|
+
When you retrieve a `CollectionViewRow` instance with `.row(<row_id>)` or a list of `CollectionViewRow` instances with `.rows`, a handful of methods are created. Each row instance has access attributes that represent the properties in the Notion Collection View. So, let's say we are working with the following Notion Collection View:
|
280
|
+
| emoji | description | category | aliases | tags | unicode_version | ios_version |
|
281
|
+
|-------|--------------|---------------------|---------|---------|-----------------|-------------|
|
282
|
+
| 😉 | "winking face" | "Smileys & Emotion" | "wink" | "flirt" | "6.0" | "6.0" |
|
283
|
+
|
284
|
+
If you wanted to update the unicode and ios versions, you could use the following code:
|
285
|
+
```ruby
|
286
|
+
>>> collection_view = @page.get_collection("1234567") # the ID of the collection block is 1234567
|
287
|
+
>>> rows = collection_view.rows
|
288
|
+
>>> row[0].unicode_version = "updated version here!"
|
289
|
+
>>> row[0].ios_version = "I was updated too!"
|
290
|
+
```
|
291
|
+
Now, your Collection View will look like this:
|
292
|
+
| emoji | description | category | aliases | tags | unicode_version | ios_version |
|
293
|
+
|-------|--------------|---------------------|---------|---------|-----------------|-------------|
|
294
|
+
| 😉 | "winking face" | "Smileys & Emotion" | "wink" | "flirt" | "updated version here!" | "I was updated too!" |
|
295
|
+
|
296
|
+
You can also add new rows with the `.add_row({<data!>})` method and add new properties with the `.add_property("name_of_property", "type_of_property")` method.
|
297
|
+
|
298
|
+
**One important thing to be aware of:**
|
299
|
+
When adding a row with `.add_row`, the hash of data passed must be in the same order as it appears in your Notion Collection View.
|
300
|
+
## Troubleshooting
|
301
|
+
### No results returned when attempting to get a page
|
302
|
+
If an empty hash is returned when you attempt to retrieve a Notion page, you'll need to include the `x-notion-active-user-header` when instantiating the Notion Client.
|
303
|
+
The endpoint used by this wrapper to load a page is `/loadPageChunk`, check out the request headers in your developer tools Network tab.
|
304
|
+
|
305
|
+
From here, you can instantiate the Notion Client with the following code:
|
306
|
+
```ruby
|
307
|
+
>>> @client = NotionAPI::Client.new(
|
308
|
+
"<insert_v2_token_here>",
|
309
|
+
"<insert_x_notion_active_user_header_here>"
|
310
|
+
)
|
311
|
+
```
|
312
|
+
### Retrieve a full-page Collection View
|
313
|
+
Currently, either a "normal" Page URL or the Page Block ID is accepted to the `get_page` method. Therefore, if you pass the full URL to the CV Table, it will raise an error:
|
314
|
+
```text
|
315
|
+
the URL or ID passed to the get_page method must be that of a Page Block.
|
316
|
+
```
|
317
|
+
To avoid this, you must pass only the ID of the full-page collection-view to the `get_page` method. This is next up on the features list, so passing the full URL will be supported soon:smile:
|
data/lib/notion_api/core.rb
CHANGED
@@ -42,13 +42,27 @@ module NotionAPI
|
|
42
42
|
end
|
43
43
|
|
44
44
|
block_id = clean_id
|
45
|
-
block_title = extract_title(clean_id, jsonified_record_response)
|
46
45
|
block_type = extract_type(clean_id, jsonified_record_response)
|
47
46
|
block_parent_id = extract_parent_id(clean_id, jsonified_record_response)
|
48
47
|
|
49
|
-
raise 'the URL or ID passed to the get_page method must be that of a Page Block.' if
|
50
|
-
|
51
|
-
|
48
|
+
raise 'the URL or ID passed to the get_page method must be that of a Page Block.' if !['collection_view_page', 'page'].include?(block_type)
|
49
|
+
|
50
|
+
if block_type == "page"
|
51
|
+
block_title = extract_title(clean_id, jsonified_record_response)
|
52
|
+
PageBlock.new(block_id, block_title, block_parent_id)
|
53
|
+
elsif block_type == "collection_view_page"
|
54
|
+
collection_id = extract_collection_id(block_id, jsonified_record_response)
|
55
|
+
block_title = extract_collection_title(clean_id, collection_id, jsonified_record_response)
|
56
|
+
view_id = extract_view_ids(block_id, jsonified_record_response)[0]
|
57
|
+
schema = extract_collection_schema(collection_id, view_id, jsonified_record_response)
|
58
|
+
column_mappings = schema.keys
|
59
|
+
column_names = column_mappings.map { |mapping| schema[mapping]['name']}
|
60
|
+
|
61
|
+
collection_view_page = CollectionViewPage.new(block_id, block_title, block_parent_id, collection_id, view_id)
|
62
|
+
collection_view_page.instance_variable_set(:@column_names, column_names)
|
63
|
+
CollectionView.class_eval{attr_reader :column_names}
|
64
|
+
collection_view_page
|
65
|
+
end
|
52
66
|
end
|
53
67
|
|
54
68
|
def children(url_or_id = @id)
|
@@ -140,7 +154,7 @@ module NotionAPI
|
|
140
154
|
# ! retrieves all info pertaining to a block Id.
|
141
155
|
# ! clean_id -> the block ID or URL cleaned : ``str``
|
142
156
|
Core.options['cookies'][:token_v2] = @@token_v2
|
143
|
-
Core.options['headers']['x-notion-active-user-header'] =
|
157
|
+
Core.options['headers']['x-notion-active-user-header'] = @@active_user_header
|
144
158
|
cookies = Core.options['cookies']
|
145
159
|
headers = Core.options['headers']
|
146
160
|
|
@@ -236,5 +250,47 @@ module NotionAPI
|
|
236
250
|
raise ArgumentError, 'Expected a Notion page URL or a page ID. Please consult the documentation for further information.'
|
237
251
|
end
|
238
252
|
end
|
253
|
+
|
254
|
+
def extract_collection_schema(collection_id, view_id, response = {})
|
255
|
+
# ! retrieve the collection scehma. Useful for 'building' the backbone for a table.
|
256
|
+
# ! collection_id -> the collection ID : ``str``
|
257
|
+
# ! view_id -> the view ID : ``str``
|
258
|
+
cookies = Core.options['cookies']
|
259
|
+
headers = Core.options['headers']
|
260
|
+
|
261
|
+
if response.empty?
|
262
|
+
query_collection_hash = Utils::CollectionViewComponents.query_collection(collection_id, view_id, '')
|
263
|
+
|
264
|
+
request_url = URLS[:GET_COLLECTION]
|
265
|
+
response = HTTParty.post(
|
266
|
+
request_url,
|
267
|
+
body: query_collection_hash.to_json,
|
268
|
+
cookies: cookies,
|
269
|
+
headers: headers
|
270
|
+
)
|
271
|
+
response['recordMap']['collection'][collection_id]['value']['schema']
|
272
|
+
else
|
273
|
+
response['collection'][collection_id]['value']['schema']
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
def extract_collection_data(collection_id, view_id)
|
278
|
+
# ! retrieve the collection scehma. Useful for 'building' the backbone for a table.
|
279
|
+
# ! collection_id -> the collection ID : ``str``
|
280
|
+
# ! view_id -> the view ID : ``str``
|
281
|
+
cookies = Core.options['cookies']
|
282
|
+
headers = Core.options['headers']
|
283
|
+
|
284
|
+
query_collection_hash = Utils::CollectionViewComponents.query_collection(collection_id, view_id, '')
|
285
|
+
|
286
|
+
request_url = URLS[:GET_COLLECTION]
|
287
|
+
response = HTTParty.post(
|
288
|
+
request_url,
|
289
|
+
body: query_collection_hash.to_json,
|
290
|
+
cookies: cookies,
|
291
|
+
headers: headers
|
292
|
+
)
|
293
|
+
response['recordMap']
|
294
|
+
end
|
239
295
|
end
|
240
296
|
end
|
@@ -1,228 +1,325 @@
|
|
1
1
|
module NotionAPI
|
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
|
-
|
2
|
+
# collection views such as tables and timelines.
|
3
|
+
class CollectionView < Core
|
4
|
+
attr_reader :id, :title, :parent_id, :collection_id, :view_id
|
5
|
+
|
6
|
+
@notion_type = "collection_view"
|
7
|
+
@type = "collection_view"
|
8
|
+
|
9
|
+
def type
|
10
|
+
NotionAPI::CollectionView.notion_type
|
11
|
+
end
|
12
|
+
|
13
|
+
class << self
|
14
|
+
attr_reader :notion_type, :type
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(id, title, parent_id, collection_id, view_id)
|
18
|
+
@id = id
|
19
|
+
@title = title
|
20
|
+
@parent_id = parent_id
|
21
|
+
@collection_id = collection_id
|
22
|
+
@view_id = view_id
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_row(data)
|
26
|
+
# ! add new row to Collection View table.
|
27
|
+
# ! data -> data to add to table : ``hash``
|
28
|
+
|
29
|
+
cookies = Core.options["cookies"]
|
30
|
+
headers = Core.options["headers"]
|
31
|
+
|
32
|
+
request_id = extract_id(SecureRandom.hex(16))
|
33
|
+
transaction_id = extract_id(SecureRandom.hex(16))
|
34
|
+
space_id = extract_id(SecureRandom.hex(16))
|
35
|
+
new_block_id = extract_id(SecureRandom.hex(16))
|
36
|
+
collection_data = extract_collection_data(collection_id, view_id)
|
37
|
+
last_row_id = collection_data["collection_view"][@view_id]["value"]["page_sort"][-1]
|
38
|
+
schema = collection_data['collection'][collection_id]['value']['schema']
|
39
|
+
keys = schema.keys
|
40
|
+
col_map = {}
|
41
|
+
keys.map { |key| col_map[schema[key]["name"]] = key }
|
42
|
+
|
43
|
+
request_ids = {
|
44
|
+
request_id: request_id,
|
45
|
+
transaction_id: transaction_id,
|
46
|
+
space_id: space_id,
|
47
|
+
}
|
48
|
+
|
49
|
+
instantiate_row = Utils::CollectionViewComponents.add_new_row(new_block_id)
|
50
|
+
set_block_alive = Utils::CollectionViewComponents.set_collection_blocks_alive(new_block_id, @collection_id)
|
51
|
+
new_block_edited_time = Utils::BlockComponents.last_edited_time(new_block_id)
|
52
|
+
page_sort = Utils::BlockComponents.row_location_add(last_row_id, new_block_id, @view_id)
|
53
|
+
|
54
|
+
operations = [
|
55
|
+
instantiate_row,
|
56
|
+
set_block_alive,
|
57
|
+
new_block_edited_time,
|
58
|
+
page_sort
|
59
|
+
]
|
60
|
+
|
61
|
+
data.keys.each_with_index do |col_name, j|
|
62
|
+
unless col_map.keys.include?(col_name.to_s); raise ArgumentError, "Column '#{col_name.to_s}' does not exist." end
|
63
|
+
if %q[select multi_select].include?(schema[col_map[col_name.to_s]]["type"])
|
64
|
+
options = schema[col_map[col_name.to_s]]["options"].map {|option| option["value"]}
|
65
|
+
if !options.include?(data[col_name])
|
66
|
+
create_new_option = Utils::CollectionViewComponents.add_new_option(col_map[col_name.to_s], data[col_name], @collection_id)
|
67
|
+
operations.push(create_new_option)
|
68
|
+
end
|
62
69
|
end
|
63
|
-
|
64
|
-
|
65
|
-
request_body = build_payload(operations, request_ids)
|
66
|
-
response = HTTParty.post(
|
67
|
-
request_url,
|
68
|
-
body: request_body.to_json,
|
69
|
-
cookies: cookies,
|
70
|
-
headers: headers
|
71
|
-
)
|
72
|
-
|
73
|
-
unless response.code == 200; raise "There was an issue completing your request. Here is the response from Notion: #{response.body}, and here is the payload that was sent: #{operations}.
|
74
|
-
Please try again, and if issues persist open an issue in GitHub."; end
|
75
|
-
|
76
|
-
NotionAPI::CollectionViewRow.new(new_block_id, @parent_id, @collection_id, @view_id)
|
70
|
+
child_component = Utils::CollectionViewComponents.insert_data(new_block_id, col_map[col_name.to_s], data[col_name], schema[col_map[col_name.to_s]]["type"])
|
71
|
+
operations.push(child_component)
|
77
72
|
end
|
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
|
-
request_body
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
73
|
+
|
74
|
+
request_url = URLS[:UPDATE_BLOCK]
|
75
|
+
request_body = build_payload(operations, request_ids)
|
76
|
+
response = HTTParty.post(
|
77
|
+
request_url,
|
78
|
+
body: request_body.to_json,
|
79
|
+
cookies: cookies,
|
80
|
+
headers: headers,
|
81
|
+
)
|
82
|
+
|
83
|
+
unless response.code == 200; raise "There was an issue completing your request. Here is the response from Notion: #{response.body}, and here is the payload that was sent: #{operations}.
|
84
|
+
Please try again, and if issues persist open an issue in GitHub."; end
|
85
|
+
|
86
|
+
NotionAPI::CollectionViewRow.new(new_block_id, @parent_id, @collection_id, @view_id)
|
87
|
+
end
|
88
|
+
|
89
|
+
def add_property(name, type)
|
90
|
+
# ! add a property (column) to the table.
|
91
|
+
# ! name -> name of the property : ``str``
|
92
|
+
# ! type -> type of the property : ``str``
|
93
|
+
cookies = Core.options["cookies"]
|
94
|
+
headers = Core.options["headers"]
|
95
|
+
|
96
|
+
request_id = extract_id(SecureRandom.hex(16))
|
97
|
+
transaction_id = extract_id(SecureRandom.hex(16))
|
98
|
+
space_id = extract_id(SecureRandom.hex(16))
|
99
|
+
|
100
|
+
request_ids = {
|
101
|
+
request_id: request_id,
|
102
|
+
transaction_id: transaction_id,
|
103
|
+
space_id: space_id,
|
104
|
+
}
|
105
|
+
|
106
|
+
# create updated schema
|
107
|
+
schema = extract_collection_schema(@collection_id, @view_id)
|
108
|
+
schema[name] = {
|
109
|
+
name: name,
|
110
|
+
type: type,
|
111
|
+
}
|
112
|
+
new_schema = {
|
113
|
+
schema: schema,
|
114
|
+
}
|
115
|
+
|
116
|
+
add_collection_property = Utils::CollectionViewComponents.add_collection_property(@collection_id, new_schema)
|
117
|
+
|
118
|
+
operations = [
|
119
|
+
add_collection_property,
|
120
|
+
]
|
121
|
+
|
122
|
+
request_url = URLS[:UPDATE_BLOCK]
|
123
|
+
request_body = build_payload(operations, request_ids)
|
124
|
+
response = HTTParty.post(
|
125
|
+
request_url,
|
126
|
+
body: request_body.to_json,
|
127
|
+
cookies: cookies,
|
128
|
+
headers: headers,
|
129
|
+
)
|
130
|
+
unless response.code == 200; raise "There was an issue completing your request. Here is the response from Notion: #{response.body}, and here is the payload that was sent: #{operations}.
|
131
|
+
Please try again, and if issues persist open an issue in GitHub."; end
|
132
|
+
|
133
|
+
true
|
134
|
+
end
|
135
|
+
|
136
|
+
def row(row_id)
|
137
|
+
# ! retrieve a row from a CollectionView Table.
|
138
|
+
# ! row_id -> the ID for the row to retrieve: ``str``
|
139
|
+
clean_id = extract_id(row_id)
|
140
|
+
|
141
|
+
request_body = {
|
142
|
+
pageId: clean_id,
|
143
|
+
chunkNumber: 0,
|
144
|
+
limit: 100,
|
145
|
+
verticalColumns: false,
|
146
|
+
}
|
147
|
+
jsonified_record_response = get_all_block_info(clean_id, request_body)
|
148
|
+
|
149
|
+
i = 0
|
150
|
+
while jsonified_record_response.empty? || jsonified_record_response["block"].empty?
|
151
|
+
return {} if i >= 10
|
152
|
+
|
137
153
|
jsonified_record_response = get_all_block_info(clean_id, request_body)
|
138
|
-
|
139
|
-
keys = schema.keys
|
140
|
-
column_names = keys.map { |key| schema[key]['name'] }
|
141
|
-
i = 0
|
142
|
-
while jsonified_record_response.empty? || jsonified_record_response['block'].empty?
|
143
|
-
return {} if i >= 10
|
144
|
-
|
145
|
-
jsonified_record_response = get_all_block_info(clean_id, request_body)
|
146
|
-
i += 1
|
147
|
-
end
|
148
|
-
row_jsonified_response = jsonified_record_response['block'][clean_id]['value']['properties']
|
149
|
-
row_data = {}
|
150
|
-
keys.each_with_index { |key, idx| row_data[column_names[idx]] = row_jsonified_response[key] ? row_jsonified_response[key].flatten : [] }
|
151
|
-
row_data
|
154
|
+
i += 1
|
152
155
|
end
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
156
|
+
|
157
|
+
collection_data = extract_collection_data(@collection_id, @view_id)
|
158
|
+
schema = collection_data["collection"][collection_id]["value"]["schema"]
|
159
|
+
column_mappings = schema.keys
|
160
|
+
column_names = column_mappings.map { |mapping| schema[mapping]["name"] }
|
161
|
+
|
162
|
+
collection_row = CollectionViewRow.new(row_id, @parent_id, @collection_id, @view_id)
|
163
|
+
collection_row.instance_variable_set(:@column_names, column_names)
|
164
|
+
CollectionViewRow.class_eval { attr_reader :column_names }
|
165
|
+
|
166
|
+
row_data = collection_data["block"][collection_row.id]
|
167
|
+
create_singleton_methods_and_instance_variables(collection_row, row_data)
|
168
|
+
|
169
|
+
collection_row
|
170
|
+
end
|
171
|
+
|
172
|
+
def row_ids
|
173
|
+
# ! retrieve all Collection View table rows.
|
174
|
+
clean_id = extract_id(@id)
|
175
|
+
|
176
|
+
request_body = {
|
177
|
+
pageId: clean_id,
|
178
|
+
chunkNumber: 0,
|
179
|
+
limit: 100,
|
180
|
+
verticalColumns: false,
|
181
|
+
}
|
182
|
+
|
183
|
+
jsonified_record_response = get_all_block_info(clean_id, request_body)
|
184
|
+
i = 0
|
185
|
+
while jsonified_record_response.empty? || jsonified_record_response["block"].empty?
|
186
|
+
return {} if i >= 10
|
187
|
+
|
165
188
|
jsonified_record_response = get_all_block_info(clean_id, request_body)
|
166
|
-
i
|
167
|
-
while jsonified_record_response.empty? || jsonified_record_response['block'].empty?
|
168
|
-
return {} if i >= 10
|
169
|
-
|
170
|
-
jsonified_record_response = get_all_block_info(clean_id, request_body)
|
171
|
-
i += 1
|
172
|
-
end
|
173
|
-
|
174
|
-
jsonified_record_response['collection_view'][@view_id]['value']['page_sort']
|
175
|
-
end
|
176
|
-
|
177
|
-
def rows
|
178
|
-
# ! returns all rows as instantiated class instances.
|
179
|
-
row_id_array = row_ids
|
180
|
-
parent_id = @parent_id
|
181
|
-
collection_id = @collection_id
|
182
|
-
view_id = @view_id
|
183
|
-
|
184
|
-
row_id_array.map { |row_id| NotionAPI::CollectionViewRow.new(row_id, parent_id, collection_id, view_id) }
|
185
|
-
end
|
186
|
-
|
187
|
-
private
|
188
|
-
|
189
|
-
def extract_collection_schema(collection_id, view_id)
|
190
|
-
# ! retrieve the collection scehma. Useful for 'building' the backbone for a table.
|
191
|
-
# ! collection_id -> the collection ID : ``str``
|
192
|
-
# ! view_id -> the view ID : ``str``
|
193
|
-
cookies = Core.options['cookies']
|
194
|
-
headers = Core.options['headers']
|
195
|
-
|
196
|
-
query_collection_hash = Utils::CollectionViewComponents.query_collection(collection_id, view_id, '')
|
197
|
-
|
198
|
-
request_url = URLS[:GET_COLLECTION]
|
199
|
-
response = HTTParty.post(
|
200
|
-
request_url,
|
201
|
-
body: query_collection_hash.to_json,
|
202
|
-
cookies: cookies,
|
203
|
-
headers: headers
|
204
|
-
)
|
205
|
-
response['recordMap']['collection'][collection_id]['value']['schema']
|
189
|
+
i += 1
|
206
190
|
end
|
191
|
+
|
192
|
+
jsonified_record_response["collection_view"][@view_id]["value"]["page_sort"]
|
207
193
|
end
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
194
|
+
|
195
|
+
def rows
|
196
|
+
# ! returns all rows as instantiated class instances.
|
197
|
+
row_id_array = row_ids
|
198
|
+
parent_id = @parent_id
|
199
|
+
collection_id = @collection_id
|
200
|
+
view_id = @view_id
|
201
|
+
collection_data = extract_collection_data(@collection_id, @view_id)
|
202
|
+
schema = collection_data["collection"][collection_id]["value"]["schema"]
|
203
|
+
column_mappings = schema.keys
|
204
|
+
column_names = column_mappings.map { |mapping| schema[mapping]["name"] }
|
205
|
+
|
206
|
+
row_instances = row_id_array.map { |row_id| NotionAPI::CollectionViewRow.new(row_id, parent_id, collection_id, view_id) }
|
207
|
+
clean_row_instances = row_instances.filter { |row| collection_data["block"][row.id] }
|
208
|
+
clean_row_instances.each { |row| row.instance_variable_set(:@column_names, column_names) }
|
209
|
+
CollectionViewRow.class_eval { attr_reader :column_names }
|
210
|
+
|
211
|
+
clean_row_instances.each do |collection_row|
|
212
|
+
row_data = collection_data["block"][collection_row.id]
|
213
|
+
create_singleton_methods_and_instance_variables(collection_row, row_data)
|
218
214
|
end
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
215
|
+
clean_row_instances
|
216
|
+
end
|
217
|
+
def create_singleton_methods_and_instance_variables(row, row_data)
|
218
|
+
# ! creates singleton methods for each property in a CollectionView.
|
219
|
+
# ! row -> the block ID of the 'row' to retrieve: ``str``
|
220
|
+
# ! row_data -> the data corresponding to that row, should be key-value pairs where the keys are the columns: ``hash``
|
221
|
+
collection_data = extract_collection_data(@collection_id, @view_id)
|
222
|
+
schema = collection_data["collection"][collection_id]["value"]["schema"]
|
223
|
+
column_mappings = schema.keys
|
224
|
+
column_hash = {}
|
225
|
+
column_names = column_mappings.map { |mapping| column_hash[mapping] = schema[mapping]["name"].downcase }
|
226
|
+
|
227
|
+
column_hash.keys.each_with_index do |column, i|
|
228
|
+
# loop over the column names...
|
229
|
+
# set instance variables for each column, allowing the dev to 'read' the column value
|
230
|
+
cleaned_column = column_hash[column].split(" ").join("_").downcase.to_sym
|
231
|
+
|
232
|
+
# p row_data["value"]["properties"][column_mappings[i]], !(row_data["value"]["properties"][column] or row_data["value"]["properties"][column_mappings[i]])
|
233
|
+
if row_data["value"]["properties"].nil? or row_data["value"]["properties"][column].nil?
|
234
|
+
value = ""
|
235
|
+
else
|
236
|
+
value = row_data["value"]["properties"][column][0][0]
|
237
|
+
end
|
238
|
+
|
239
|
+
row.instance_variable_set("@#{cleaned_column}", value)
|
240
|
+
CollectionViewRow.class_eval { attr_reader cleaned_column }
|
241
|
+
# then, define singleton methods for each column that are used to update the table cell
|
242
|
+
row.define_singleton_method("#{cleaned_column}=") do |new_value|
|
243
|
+
# neat way to get the name of the currently invoked method...
|
244
|
+
parsed_method = __method__.to_s[0...-1].split("_").join(" ")
|
245
|
+
cookies = Core.options["cookies"]
|
246
|
+
headers = Core.options["headers"]
|
247
|
+
|
248
|
+
request_id = extract_id(SecureRandom.hex(16))
|
249
|
+
transaction_id = extract_id(SecureRandom.hex(16))
|
250
|
+
space_id = extract_id(SecureRandom.hex(16))
|
251
|
+
|
252
|
+
request_ids = {
|
253
|
+
request_id: request_id,
|
254
|
+
transaction_id: transaction_id,
|
255
|
+
space_id: space_id,
|
256
|
+
}
|
257
|
+
|
258
|
+
update_property_value = Utils::CollectionViewComponents.update_property_value(@id, column_hash.key(parsed_method), new_value)
|
259
|
+
|
260
|
+
operations = [
|
261
|
+
update_property_value,
|
262
|
+
]
|
263
|
+
|
264
|
+
request_url = URLS[:UPDATE_BLOCK]
|
265
|
+
request_body = build_payload(operations, request_ids)
|
266
|
+
response = HTTParty.post(
|
267
|
+
request_url,
|
268
|
+
body: request_body.to_json,
|
269
|
+
cookies: cookies,
|
270
|
+
headers: headers,
|
271
|
+
)
|
272
|
+
unless response.code == 200; raise "There was an issue completing your request. Here is the response from Notion: #{response.body}, and here is the payload that was sent: #{operations}.
|
273
|
+
Please try again, and if issues persist open an issue in GitHub.";end
|
274
|
+
|
275
|
+
# set the instance variable to the updated value!
|
276
|
+
_ = row.instance_variable_set("@#{__method__.to_s[0...-1]}", new_value)
|
277
|
+
row
|
278
|
+
end
|
226
279
|
end
|
227
280
|
end
|
228
|
-
end
|
281
|
+
end
|
282
|
+
|
283
|
+
# class that represents each row in a CollectionView
|
284
|
+
class CollectionViewRow < Core
|
285
|
+
@notion_type = "table_row"
|
286
|
+
@type = "table_row"
|
287
|
+
|
288
|
+
def type
|
289
|
+
NotionAPI::CollectionViewRow.notion_type
|
290
|
+
end
|
291
|
+
|
292
|
+
def inspect
|
293
|
+
"CollectionViewRow - id: #{self.id} - parent id: #{self.parent_id}"
|
294
|
+
end
|
295
|
+
|
296
|
+
class << self
|
297
|
+
attr_reader :notion_type, :type, :parent_id
|
298
|
+
end
|
299
|
+
|
300
|
+
attr_reader :parent_id, :id
|
301
|
+
|
302
|
+
def initialize(id, parent_id, collection_id, view_id)
|
303
|
+
@id = id
|
304
|
+
@parent_id = parent_id
|
305
|
+
@collection_id = collection_id
|
306
|
+
@view_id = view_id
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
# class that represents a CollectionViewPage, inheriting all properties from CollectionView
|
311
|
+
class CollectionViewPage < CollectionView
|
312
|
+
@notion_type = "collection_view_page"
|
313
|
+
@type = "collection_view_page"
|
314
|
+
|
315
|
+
def type
|
316
|
+
NotionAPI::CollectionViewRow.notion_type
|
317
|
+
end
|
318
|
+
|
319
|
+
class << self
|
320
|
+
attr_reader :notion_type, :type, :parent_id
|
321
|
+
end
|
322
|
+
|
323
|
+
attr_reader :parent_id, :id
|
324
|
+
end
|
325
|
+
end
|
@@ -304,7 +304,15 @@ module NotionAPI
|
|
304
304
|
block_collection_id = extract_collection_id(clean_id, jsonified_record_response)
|
305
305
|
block_view_id = extract_view_ids(clean_id, jsonified_record_response)
|
306
306
|
collection_title = extract_collection_title(clean_id, block_collection_id, jsonified_record_response)
|
307
|
-
|
307
|
+
|
308
|
+
block = block_class.new(clean_id, collection_title, block_parent_id, block_collection_id, block_view_id.join)
|
309
|
+
schema = extract_collection_schema(block_collection_id, block_view_id[0])
|
310
|
+
column_mappings = schema.keys
|
311
|
+
column_names = column_mappings.map { |mapping| schema[mapping]['name']}
|
312
|
+
block.instance_variable_set(:@column_names, column_names)
|
313
|
+
CollectionView.class_eval{attr_reader :column_names}
|
314
|
+
|
315
|
+
block
|
308
316
|
else
|
309
317
|
block_title = extract_title(clean_id, jsonified_record_response)
|
310
318
|
block_class.new(clean_id, block_title, block_parent_id)
|
data/lib/notion_api/utils.rb
CHANGED
@@ -200,14 +200,14 @@ module Utils
|
|
200
200
|
|
201
201
|
args = if command == "listAfter"
|
202
202
|
{
|
203
|
-
|
204
|
-
|
205
|
-
|
203
|
+
after: target || block_id,
|
204
|
+
id: new_block_id || block_id,
|
205
|
+
}
|
206
206
|
else
|
207
207
|
{
|
208
|
-
|
209
|
-
|
210
|
-
|
208
|
+
before: target || block_id,
|
209
|
+
id: new_block_id || block_id,
|
210
|
+
}
|
211
211
|
end
|
212
212
|
|
213
213
|
{
|
@@ -219,6 +219,21 @@ module Utils
|
|
219
219
|
}
|
220
220
|
end
|
221
221
|
|
222
|
+
def self.row_location_add(last_row_id, block_id, view_id)
|
223
|
+
{
|
224
|
+
"table": "collection_view",
|
225
|
+
"id": view_id,
|
226
|
+
"path": [
|
227
|
+
"page_sort"
|
228
|
+
],
|
229
|
+
"command": "listAfter",
|
230
|
+
"args": {
|
231
|
+
"after": last_row_id,
|
232
|
+
"id": block_id
|
233
|
+
}
|
234
|
+
}
|
235
|
+
end
|
236
|
+
|
222
237
|
def self.block_location_remove(block_parent_id, block_id)
|
223
238
|
# ! removes a notion block
|
224
239
|
# ! block_parent_id -> the parent ID of the block to remove : ``str``
|
@@ -276,9 +291,9 @@ module Utils
|
|
276
291
|
def self.add_emoji_icon(block_id, icon)
|
277
292
|
{
|
278
293
|
id: block_id,
|
279
|
-
table:"block",
|
280
|
-
path:["format","page_icon"],
|
281
|
-
command:"set","args": icon
|
294
|
+
table: "block",
|
295
|
+
path: ["format", "page_icon"],
|
296
|
+
command: "set", "args": icon,
|
282
297
|
}
|
283
298
|
end
|
284
299
|
end
|
@@ -383,14 +398,14 @@ module Utils
|
|
383
398
|
# ! new_block_id -> id of the new block
|
384
399
|
# ! data -> json data to insert into table.
|
385
400
|
col_names = data[0].keys
|
386
|
-
data_mappings = {Integer => "number", String => "text", Array => "text", Float => "number", Date => "date"}
|
401
|
+
data_mappings = { Integer => "number", String => "text", Array => "text", Float => "number", Date => "date" }
|
387
402
|
exceptions = [ArgumentError, TypeError]
|
388
403
|
data_types = col_names.map do |name|
|
389
404
|
# TODO: this is a little hacky... should probably think about a better way or add a requirement for user input to match a certain criteria.
|
390
|
-
begin
|
405
|
+
begin
|
391
406
|
DateTime.parse(data[0][name]) ? data_mappings[Date] : nil
|
392
407
|
rescue *exceptions
|
393
|
-
data_mappings[data[0][name].class]
|
408
|
+
data_mappings[data[0][name].class]
|
394
409
|
end
|
395
410
|
end
|
396
411
|
|
@@ -403,18 +418,18 @@ module Utils
|
|
403
418
|
end
|
404
419
|
end
|
405
420
|
return {
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
421
|
+
id: collection_id,
|
422
|
+
table: "collection",
|
423
|
+
path: [],
|
424
|
+
command: "update",
|
425
|
+
args: {
|
426
|
+
id: collection_id,
|
427
|
+
schema: schema_conf,
|
428
|
+
parent_id: new_block_id,
|
429
|
+
parent_table: "block",
|
430
|
+
alive: true,
|
431
|
+
},
|
432
|
+
}, data_types
|
418
433
|
end
|
419
434
|
|
420
435
|
def self.set_collection_title(collection_title, collection_id)
|
@@ -440,6 +455,11 @@ module Utils
|
|
440
455
|
# ! column -> the name of the column to insert data into.
|
441
456
|
# ! value -> the value to insert into the column.
|
442
457
|
# ! mapping -> the column data type.
|
458
|
+
simple_mappings = ["title", "text", "phone_number", "email", "url", "number", "checkbox", "select", "multi_select"]
|
459
|
+
datetime_mappings = ["date"]
|
460
|
+
media_mappings = ["file"]
|
461
|
+
person_mappings = ["person"]
|
462
|
+
|
443
463
|
table = "block"
|
444
464
|
path = [
|
445
465
|
"properties",
|
@@ -447,12 +467,47 @@ module Utils
|
|
447
467
|
]
|
448
468
|
command = "set"
|
449
469
|
|
470
|
+
if simple_mappings.include?(mapping)
|
471
|
+
args = [[value]]
|
472
|
+
elsif media_mappings.include?(mapping)
|
473
|
+
args = [[value, [["a", value]]]]
|
474
|
+
elsif datetime_mappings.include?(mapping)
|
475
|
+
args = [["‣", [["d", { "type": "date", "start_date": value }]]]]
|
476
|
+
elsif person_mappings.include?(mapping)
|
477
|
+
args = [["‣",
|
478
|
+
[["u", value]]
|
479
|
+
]]
|
480
|
+
else
|
481
|
+
raise SchemaTypeError, "Invalid property type: #{mapping}"
|
482
|
+
end
|
483
|
+
|
450
484
|
{
|
451
|
-
id: block_id,
|
452
485
|
table: table,
|
486
|
+
id: block_id,
|
487
|
+
command: command,
|
453
488
|
path: path,
|
489
|
+
args: args,
|
490
|
+
}
|
491
|
+
end
|
492
|
+
|
493
|
+
def self.add_new_option(column, value, collection_id)
|
494
|
+
table = "collection"
|
495
|
+
path = ["schema", column, "options"]
|
496
|
+
command = "keyedObjectListAfter"
|
497
|
+
args = {
|
498
|
+
"value": {
|
499
|
+
"id": SecureRandom.hex(16),
|
500
|
+
"value": value,
|
501
|
+
"color": "green"
|
502
|
+
}
|
503
|
+
}
|
504
|
+
|
505
|
+
{
|
506
|
+
table: table,
|
507
|
+
id: collection_id,
|
454
508
|
command: command,
|
455
|
-
|
509
|
+
path: path,
|
510
|
+
args: args,
|
456
511
|
}
|
457
512
|
end
|
458
513
|
|
@@ -505,45 +560,45 @@ module Utils
|
|
505
560
|
args["format"] = {
|
506
561
|
"table_properties" => [
|
507
562
|
{
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
563
|
+
"property" => "title",
|
564
|
+
"visible" => true,
|
565
|
+
"width" => 280,
|
566
|
+
},
|
512
567
|
{
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
568
|
+
"property" => "aliases",
|
569
|
+
"visible" => true,
|
570
|
+
"width" => 200,
|
571
|
+
},
|
517
572
|
{
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
573
|
+
"property" => "category",
|
574
|
+
"visible" => true,
|
575
|
+
"width" => 200,
|
576
|
+
},
|
522
577
|
{
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
578
|
+
"property" => "description",
|
579
|
+
"visible" => true,
|
580
|
+
"width" => 200,
|
581
|
+
},
|
527
582
|
{
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
583
|
+
"property" => "ios_version",
|
584
|
+
"visible" => true,
|
585
|
+
"width" => 200,
|
586
|
+
},
|
587
|
+
{
|
588
|
+
"property" => "tags",
|
589
|
+
"visible" => true,
|
590
|
+
"width" => 200,
|
591
|
+
},
|
532
592
|
{
|
533
|
-
"property" => "tags",
|
534
|
-
"visible" => true,
|
535
|
-
"width" => 200,
|
536
|
-
},
|
537
|
-
{
|
538
593
|
"property" => "phone",
|
539
594
|
"visible" => true,
|
540
595
|
"width" => 200,
|
541
596
|
},
|
542
597
|
{
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
598
|
+
"property" => "unicode_version",
|
599
|
+
"visible" => true,
|
600
|
+
"width" => 200,
|
601
|
+
},
|
547
602
|
],
|
548
603
|
}
|
549
604
|
{
|
@@ -554,6 +609,37 @@ module Utils
|
|
554
609
|
args: args,
|
555
610
|
}
|
556
611
|
end
|
612
|
+
|
613
|
+
def self.update_property_value(page_id, column_name, new_value)
|
614
|
+
# ! update the specified column_name to new_value
|
615
|
+
# ! page_id -> the ID of the page: ``str``
|
616
|
+
# ! column_name -> the name of the column ["property"] to update: ``str``
|
617
|
+
# ! new_value -> the new value to assign to that column ["property"]: ``str``
|
618
|
+
table = "block"
|
619
|
+
path = [
|
620
|
+
"properties",
|
621
|
+
column_name,
|
622
|
+
]
|
623
|
+
command = "set"
|
624
|
+
args = [[
|
625
|
+
new_value,
|
626
|
+
]]
|
627
|
+
|
628
|
+
{
|
629
|
+
id: page_id,
|
630
|
+
table: table,
|
631
|
+
path: path,
|
632
|
+
command: command,
|
633
|
+
args: args,
|
634
|
+
}
|
635
|
+
end
|
636
|
+
end
|
637
|
+
|
638
|
+
class SchemaTypeError < StandardError
|
639
|
+
def initialize(msg="Custom exception that is raised when an invalid property type is passed as a mapping.", exception_type="schema_type")
|
640
|
+
@exception_type = exception_type
|
641
|
+
super(msg)
|
642
|
+
end
|
557
643
|
end
|
558
644
|
|
559
645
|
def build_payload(operations, request_ids)
|
@@ -576,4 +662,4 @@ module Utils
|
|
576
662
|
}
|
577
663
|
payload
|
578
664
|
end
|
579
|
-
end
|
665
|
+
end
|
data/lib/notion_api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: notion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Murphy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|