notion 1.0.7 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +8 -4
- data/lib/notion_api/blocks.rb +1 -0
- data/lib/notion_api/client.rb +2 -2
- data/lib/notion_api/core.rb +169 -111
- data/lib/notion_api/notion_types/code_block.rb +13 -13
- data/lib/notion_api/notion_types/collection_view_blocks.rb +66 -39
- data/lib/notion_api/notion_types/column_list_block.rb +13 -13
- data/lib/notion_api/notion_types/divider_block.rb +13 -13
- data/lib/notion_api/notion_types/header_block.rb +13 -13
- data/lib/notion_api/notion_types/image_block.rb +59 -12
- data/lib/notion_api/notion_types/latex_block.rb +13 -13
- data/lib/notion_api/notion_types/link_block.rb +51 -0
- data/lib/notion_api/notion_types/numbered_block.rb +13 -13
- data/lib/notion_api/notion_types/page_block.rb +117 -124
- data/lib/notion_api/notion_types/quote_block.rb +13 -13
- data/lib/notion_api/notion_types/sub_header_block.rb +13 -13
- data/lib/notion_api/notion_types/sub_sub_header.rb +13 -13
- data/lib/notion_api/notion_types/table_of_contents_block.rb +3 -3
- data/lib/notion_api/notion_types/template.rb +325 -328
- data/lib/notion_api/notion_types/text_block.rb +13 -13
- data/lib/notion_api/notion_types/todo_block.rb +56 -56
- data/lib/notion_api/notion_types/toggle_block.rb +13 -13
- data/lib/notion_api/utils.rb +100 -63
- data/lib/notion_api/version.rb +1 -1
- metadata +11 -10
@@ -1,15 +1,15 @@
|
|
1
1
|
module NotionAPI
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
class << self
|
12
|
-
attr_reader :notion_type, :type
|
13
|
-
end
|
2
|
+
# Numbered list Block: best for an ordered list
|
3
|
+
class NumberedBlock < BlockTemplate
|
4
|
+
@notion_type = "numbered_list"
|
5
|
+
@type = "numbered_list"
|
6
|
+
|
7
|
+
def type
|
8
|
+
NotionAPI::NumberedBlock.notion_type
|
14
9
|
end
|
15
|
-
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_reader :notion_type, :type
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,130 +1,123 @@
|
|
1
|
-
|
2
1
|
module NotionAPI
|
3
2
|
|
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
|
-
|
3
|
+
# Page Block, entrypoint for the application
|
4
|
+
class PageBlock < BlockTemplate
|
5
|
+
@notion_type = "page"
|
6
|
+
@type = "page"
|
7
|
+
|
8
|
+
def type
|
9
|
+
NotionAPI::PageBlock.notion_type
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_reader :notion_type, :type
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_block(url_or_id)
|
17
|
+
# ! retrieve a Notion Block and return its instantiated class object.
|
18
|
+
# ! url_or_id -> the block ID or URL : ``str``
|
19
|
+
get(url_or_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_collection(url_or_id)
|
23
|
+
# ! retrieve a Notion Collection and return its instantiated class object.
|
24
|
+
# ! url_or_id -> the block ID or URL : ``str``
|
25
|
+
clean_id = extract_id(url_or_id)
|
26
|
+
|
27
|
+
request_body = {
|
28
|
+
pageId: clean_id,
|
29
|
+
chunkNumber: 0,
|
30
|
+
limit: 100,
|
31
|
+
verticalColumns: false,
|
32
|
+
}
|
33
|
+
jsonified_record_response = get_all_block_info(request_body)
|
34
|
+
|
35
|
+
block_parent_id = extract_parent_id(clean_id, jsonified_record_response)
|
36
|
+
block_collection_id = extract_collection_id(clean_id, jsonified_record_response)
|
37
|
+
block_view_id = extract_view_ids(clean_id, jsonified_record_response).join
|
38
|
+
block_title = extract_collection_title(clean_id, block_collection_id, jsonified_record_response)
|
39
|
+
|
40
|
+
CollectionView.new(clean_id, block_title, block_parent_id, block_collection_id, block_view_id)
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_collection(collection_type, collection_title, data)
|
44
|
+
# ! create a Notion Collection View and return its instantiated class object.
|
45
|
+
# ! _collection_type -> the type of collection to create : ``str``
|
46
|
+
# ! collection_title -> the title of the collection view : ``str``
|
47
|
+
# ! data -> JSON data to add to the table : ``str``
|
48
|
+
|
49
|
+
valid_types = %w[table board list timeline calendar gallery]
|
50
|
+
unless valid_types.include?(collection_type); raise ArgumentError, "That collection type is not yet supported. Try: #{valid_types.join}."; end
|
51
|
+
cookies = Core.options["cookies"]
|
52
|
+
headers = Core.options["headers"]
|
53
|
+
|
54
|
+
new_block_id = extract_id(SecureRandom.hex(16))
|
55
|
+
parent_id = extract_id(SecureRandom.hex(16))
|
56
|
+
collection_id = extract_id(SecureRandom.hex(16))
|
57
|
+
view_id = extract_id(SecureRandom.hex(16))
|
58
|
+
|
59
|
+
children = []
|
60
|
+
alive_blocks = []
|
61
|
+
data.each do |_row|
|
62
|
+
child = extract_id(SecureRandom.hex(16))
|
63
|
+
children.push(child)
|
64
|
+
alive_blocks.push(Utils::CollectionViewComponents.set_collection_blocks_alive(child, collection_id))
|
48
65
|
end
|
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
|
-
column_data = Utils::CollectionViewComponents.set_collection_columns(collection_id, new_block_id, data)
|
89
|
-
configure_columns_hash = column_data[0]
|
90
|
-
column_mappings = column_data[1]
|
91
|
-
set_parent_alive_hash = Utils::BlockComponents.set_parent_to_alive(@id, new_block_id)
|
92
|
-
add_block_hash = Utils::BlockComponents.block_location_add(@id, @id, new_block_id, nil, 'listAfter')
|
93
|
-
new_block_edited_time = Utils::BlockComponents.last_edited_time(new_block_id)
|
94
|
-
collection_title_hash = Utils::CollectionViewComponents.set_collection_title(collection_title, collection_id)
|
95
|
-
|
96
|
-
operations = [
|
97
|
-
create_collection_view,
|
98
|
-
configure_view,
|
99
|
-
configure_columns_hash,
|
100
|
-
set_parent_alive_hash,
|
101
|
-
add_block_hash,
|
102
|
-
new_block_edited_time,
|
103
|
-
collection_title_hash
|
104
|
-
]
|
105
|
-
operations << alive_blocks
|
106
|
-
all_ops = operations.flatten
|
107
|
-
data.each_with_index do |row, i|
|
108
|
-
child = children[i]
|
109
|
-
row.keys.each_with_index do |col_name, j|
|
110
|
-
child_component = Utils::CollectionViewComponents.insert_data(child, j.zero? ? 'title' : col_name, row[col_name], column_mappings[j])
|
111
|
-
all_ops.push(child_component)
|
112
|
-
end
|
66
|
+
|
67
|
+
request_id = extract_id(SecureRandom.hex(16))
|
68
|
+
transaction_id = extract_id(SecureRandom.hex(16))
|
69
|
+
space_id = extract_id(SecureRandom.hex(16))
|
70
|
+
|
71
|
+
request_ids = {
|
72
|
+
request_id: request_id,
|
73
|
+
transaction_id: transaction_id,
|
74
|
+
space_id: space_id,
|
75
|
+
}
|
76
|
+
|
77
|
+
create_collection_view = Utils::CollectionViewComponents.create_collection_view(new_block_id, collection_id, view_id)
|
78
|
+
configure_view = Utils::CollectionViewComponents.set_view_config(collection_type, new_block_id, view_id, children)
|
79
|
+
|
80
|
+
# returns the JSON and some useful column mappings...
|
81
|
+
column_data = Utils::CollectionViewComponents.set_collection_columns(collection_id, new_block_id, data)
|
82
|
+
configure_columns_hash = column_data[0]
|
83
|
+
column_mappings = column_data[1]
|
84
|
+
set_parent_alive_hash = Utils::BlockComponents.set_parent_to_alive(@id, new_block_id)
|
85
|
+
add_block_hash = Utils::BlockComponents.block_location_add(@id, @id, new_block_id, nil, "listAfter")
|
86
|
+
new_block_edited_time = Utils::BlockComponents.last_edited_time(new_block_id)
|
87
|
+
collection_title_hash = Utils::CollectionViewComponents.set_collection_title(collection_title, collection_id)
|
88
|
+
|
89
|
+
operations = [
|
90
|
+
create_collection_view,
|
91
|
+
configure_view,
|
92
|
+
configure_columns_hash,
|
93
|
+
set_parent_alive_hash,
|
94
|
+
add_block_hash,
|
95
|
+
new_block_edited_time,
|
96
|
+
collection_title_hash,
|
97
|
+
]
|
98
|
+
operations << alive_blocks
|
99
|
+
all_ops = operations.flatten
|
100
|
+
data.each_with_index do |row, i|
|
101
|
+
child = children[i]
|
102
|
+
row.keys.each_with_index do |col_name, j|
|
103
|
+
child_component = Utils::CollectionViewComponents.insert_data(child, j.zero? ? "title" : col_name, row[col_name], column_mappings[j])
|
104
|
+
all_ops.push(child_component)
|
113
105
|
end
|
114
|
-
|
115
|
-
request_url = URLS[:UPDATE_BLOCK]
|
116
|
-
request_body = build_payload(all_ops, request_ids)
|
117
|
-
response = HTTParty.post(
|
118
|
-
request_url,
|
119
|
-
body: request_body.to_json,
|
120
|
-
cookies: cookies,
|
121
|
-
headers: headers
|
122
|
-
)
|
123
|
-
|
124
|
-
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}.
|
125
|
-
Please try again, and if issues persist open an issue in GitHub."; end
|
126
|
-
|
127
|
-
CollectionView.new(new_block_id, collection_title, parent_id, collection_id, view_id)
|
128
106
|
end
|
107
|
+
|
108
|
+
request_url = URLS[:UPDATE_BLOCK]
|
109
|
+
request_body = build_payload(all_ops, request_ids)
|
110
|
+
response = HTTParty.post(
|
111
|
+
request_url,
|
112
|
+
body: request_body.to_json,
|
113
|
+
cookies: cookies,
|
114
|
+
headers: headers,
|
115
|
+
)
|
116
|
+
|
117
|
+
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}.
|
118
|
+
Please try again, and if issues persist open an issue in GitHub."; end
|
119
|
+
|
120
|
+
CollectionView.new(new_block_id, collection_title, parent_id, collection_id, view_id)
|
129
121
|
end
|
130
|
-
end
|
122
|
+
end
|
123
|
+
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
module NotionAPI
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
3
|
+
# best for memorable information
|
4
|
+
class QuoteBlock < BlockTemplate
|
5
|
+
@notion_type = "quote"
|
6
|
+
@type = "quote"
|
7
|
+
|
8
|
+
def type
|
9
|
+
NotionAPI::QuoteBlock.notion_type
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_reader :notion_type, :type
|
15
14
|
end
|
16
|
-
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
module NotionAPI
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
3
|
+
# SubHeader Block: H2
|
4
|
+
class SubHeaderBlock < BlockTemplate
|
5
|
+
@notion_type = "sub_header"
|
6
|
+
@type = "sub_header"
|
7
|
+
|
8
|
+
def type
|
9
|
+
NotionAPI::SubHeaderBlock.notion_type
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_reader :notion_type, :type
|
15
14
|
end
|
16
|
-
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
module NotionAPI
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
3
|
+
# Sub-Sub Header Block: H3
|
4
|
+
class SubSubHeaderBlock < BlockTemplate
|
5
|
+
@notion_type = "sub_sub_header"
|
6
|
+
@type = "sub_sub_header"
|
7
|
+
|
8
|
+
def type
|
9
|
+
NotionAPI::SubSubHeaderBlock.notion_type
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_reader :notion_type, :type
|
15
14
|
end
|
16
|
-
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module NotionAPI
|
2
2
|
# maps out the headers - sub-headers - sub-sub-headers on the page
|
3
3
|
class TableOfContentsBlock < BlockTemplate
|
4
|
-
@notion_type =
|
5
|
-
@type =
|
4
|
+
@notion_type = "table_of_contents"
|
5
|
+
@type = "table_of_contents"
|
6
6
|
|
7
7
|
def type
|
8
8
|
NotionAPI::TableOfContentsBlock.notion_type
|
@@ -12,4 +12,4 @@ module NotionAPI
|
|
12
12
|
attr_reader :notion_type, :type
|
13
13
|
end
|
14
14
|
end
|
15
|
-
end
|
15
|
+
end
|
@@ -1,360 +1,357 @@
|
|
1
|
-
require_relative
|
2
|
-
require
|
1
|
+
require_relative "../core"
|
2
|
+
require "httparty"
|
3
3
|
|
4
4
|
module NotionAPI
|
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
|
-
request_url = URLS[:UPDATE_BLOCK]
|
38
|
-
|
39
|
-
# set random IDs for request
|
40
|
-
request_id = extract_id(SecureRandom.hex(16))
|
41
|
-
transaction_id = extract_id(SecureRandom.hex(16))
|
42
|
-
space_id = extract_id(SecureRandom.hex(16))
|
43
|
-
request_ids = {
|
44
|
-
request_id: request_id,
|
45
|
-
transaction_id: transaction_id,
|
46
|
-
space_id: space_id
|
47
|
-
}
|
48
|
-
|
49
|
-
# build hash's that contain the operations to send to Notions backend
|
50
|
-
convert_type_hash = Utils::BlockComponents.convert_type(@id, block_class_to_convert_to)
|
51
|
-
last_edited_time_parent_hash = Utils::BlockComponents.last_edited_time(@parent_id)
|
52
|
-
last_edited_time_child_hash = Utils::BlockComponents.last_edited_time(@id)
|
53
|
-
|
54
|
-
operations = [
|
55
|
-
convert_type_hash,
|
56
|
-
last_edited_time_parent_hash,
|
57
|
-
last_edited_time_child_hash
|
58
|
-
]
|
59
|
-
|
60
|
-
request_body = build_payload(operations, request_ids)
|
61
|
-
response = HTTParty.post(
|
62
|
-
request_url,
|
63
|
-
body: request_body.to_json,
|
64
|
-
cookies: cookies,
|
65
|
-
headers: headers
|
66
|
-
)
|
67
|
-
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}.
|
68
|
-
Please try again, and if issues persist open an issue in GitHub."; end
|
69
|
-
|
70
|
-
block_class_to_convert_to.new(@id, @title, @parent_id)
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def duplicate(target_block = nil)
|
76
|
-
# ! duplicate the block that this method is invoked upon.
|
77
|
-
# ! target_block -> the block to place the duplicated block after. Can be any valid Block ID! : ``str``
|
78
|
-
cookies = Core.options['cookies']
|
79
|
-
headers = Core.options['headers']
|
5
|
+
# Base Template for all blocks. Inherits core methods from the Block class defined in block.rb
|
6
|
+
class BlockTemplate < Core
|
7
|
+
include Utils
|
8
|
+
|
9
|
+
attr_reader :id, :title, :parent_id
|
10
|
+
|
11
|
+
def initialize(id, title, parent_id)
|
12
|
+
@id = id
|
13
|
+
@title = title
|
14
|
+
@parent_id = parent_id
|
15
|
+
end
|
16
|
+
|
17
|
+
def title=(new_title)
|
18
|
+
# ! Change the title of a block.
|
19
|
+
# ! new_title -> new title for the block : ``str``
|
20
|
+
request_id = extract_id(SecureRandom.hex(16))
|
21
|
+
transaction_id = extract_id(SecureRandom.hex(16))
|
22
|
+
space_id = extract_id(SecureRandom.hex(16))
|
23
|
+
update_title(new_title.to_s, request_id, transaction_id, space_id)
|
24
|
+
@title = new_title
|
25
|
+
end
|
26
|
+
|
27
|
+
def convert(block_class_to_convert_to)
|
28
|
+
# ! convert a block from its current type to another.
|
29
|
+
# ! block_class_to_convert_to -> the type of block to convert to : ``cls``
|
30
|
+
if type == block_class_to_convert_to.notion_type
|
31
|
+
# if converting to same type, skip and return self
|
32
|
+
self
|
33
|
+
else
|
34
|
+
# setup cookies, headers, and grab/create static vars for request
|
35
|
+
cookies = Core.options["cookies"]
|
36
|
+
headers = Core.options["headers"]
|
80
37
|
request_url = URLS[:UPDATE_BLOCK]
|
81
|
-
|
82
|
-
|
38
|
+
|
39
|
+
# set random IDs for request
|
83
40
|
request_id = extract_id(SecureRandom.hex(16))
|
84
41
|
transaction_id = extract_id(SecureRandom.hex(16))
|
85
42
|
space_id = extract_id(SecureRandom.hex(16))
|
86
|
-
|
87
|
-
root_children = children_ids(@id)
|
88
|
-
sub_children = []
|
89
|
-
root_children.each { |root_id| sub_children.push(children_ids(root_id)) }
|
90
|
-
|
91
43
|
request_ids = {
|
92
44
|
request_id: request_id,
|
93
45
|
transaction_id: transaction_id,
|
94
|
-
space_id: space_id
|
46
|
+
space_id: space_id,
|
95
47
|
}
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
user_notion_id = get_notion_id(body)
|
104
|
-
|
105
|
-
block = target_block ? get(target_block) : self # allows dev to place block anywhere!
|
106
|
-
|
107
|
-
props_and_formatting = get_block_props_and_format(@id, @title)
|
108
|
-
props = props_and_formatting[:properties]
|
109
|
-
formats = props_and_formatting[:format]
|
110
|
-
duplicate_hash = Utils::BlockComponents.duplicate(type, @title, block.id, new_block_id, user_notion_id, root_children, props, formats)
|
111
|
-
set_parent_alive_hash = Utils::BlockComponents.set_parent_to_alive(block.parent_id, new_block_id)
|
112
|
-
block_location_hash = Utils::BlockComponents.block_location_add(block.parent_id, block.id, new_block_id, target_block, 'listAfter')
|
113
|
-
last_edited_time_parent_hash = Utils::BlockComponents.last_edited_time(block.parent_id)
|
114
|
-
last_edited_time_child_hash = Utils::BlockComponents.last_edited_time(block.id)
|
115
|
-
|
48
|
+
|
49
|
+
# build hash's that contain the operations to send to Notion
|
50
|
+
convert_type_hash = Utils::BlockComponents.convert_type(@id, block_class_to_convert_to)
|
51
|
+
last_edited_time_parent_hash = Utils::BlockComponents.last_edited_time(@parent_id)
|
52
|
+
last_edited_time_child_hash = Utils::BlockComponents.last_edited_time(@id)
|
53
|
+
|
116
54
|
operations = [
|
117
|
-
|
118
|
-
set_parent_alive_hash,
|
119
|
-
block_location_hash,
|
55
|
+
convert_type_hash,
|
120
56
|
last_edited_time_parent_hash,
|
121
|
-
last_edited_time_child_hash
|
57
|
+
last_edited_time_child_hash,
|
122
58
|
]
|
123
|
-
|
124
|
-
request_body = build_payload(operations, request_ids)
|
125
|
-
response = HTTParty.post(
|
126
|
-
request_url,
|
127
|
-
body: request_body.to_json,
|
128
|
-
cookies: cookies,
|
129
|
-
headers: headers
|
130
|
-
)
|
131
|
-
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}.
|
132
|
-
Please try again, and if issues persist open an issue in GitHub."; end
|
133
|
-
|
134
|
-
class_to_return = NotionAPI.const_get(Classes.select { |cls| NotionAPI.const_get(cls).notion_type == type }.join.to_s)
|
135
|
-
class_to_return.new(new_block_id, @title, block.parent_id)
|
136
|
-
end
|
137
|
-
|
138
|
-
def move(target_block, position = 'after')
|
139
|
-
# ! move the block to a new location.
|
140
|
-
# ! target_block -> the targetted block to move to. : ``str``
|
141
|
-
# ! position -> where the block should be listed, in positions relative to the target_block [before, after, top-child, last-child]
|
142
|
-
positions_hash = {
|
143
|
-
'after' => 'listAfter',
|
144
|
-
'before' => 'listBefore'
|
145
|
-
}
|
146
|
-
|
147
|
-
unless positions_hash.keys.include?(position); raise ArgumentError, "Invalid position. You said: #{position}, valid options are: #{positions_hash.keys.join(', ')}"; end
|
148
|
-
|
149
|
-
position_command = positions_hash[position]
|
150
|
-
cookies = Core.options['cookies']
|
151
|
-
headers = Core.options['headers']
|
152
|
-
request_url = URLS[:UPDATE_BLOCK]
|
153
|
-
|
154
|
-
request_id = extract_id(SecureRandom.hex(16))
|
155
|
-
transaction_id = extract_id(SecureRandom.hex(16))
|
156
|
-
space_id = extract_id(SecureRandom.hex(16))
|
157
|
-
|
158
|
-
request_ids = {
|
159
|
-
request_id: request_id,
|
160
|
-
transaction_id: transaction_id,
|
161
|
-
space_id: space_id
|
162
|
-
}
|
163
|
-
|
164
|
-
check_parents = (@parent_id == target_block.parent_id)
|
165
|
-
set_block_dead_hash = Utils::BlockComponents.set_block_to_dead(@id) # kill the block this method is invoked on...
|
166
|
-
block_location_remove_hash = Utils::BlockComponents.block_location_remove(@parent_id, @id) # remove the block this method is invoked on...
|
167
|
-
parent_location_hash = Utils::BlockComponents.parent_location_add(check_parents ? @parent_id : target_block.parent_id, @id) # set parent location to alive
|
168
|
-
block_location_add_hash = Utils::BlockComponents.block_location_add(check_parents ? @parent_id : target_block.parent_id, @id, target_block.id, position_command)
|
169
|
-
last_edited_time_parent_hash = Utils::BlockComponents.last_edited_time(@parent_id)
|
170
|
-
|
171
|
-
if check_parents
|
172
|
-
last_edited_time_child_hash = Utils::BlockComponents.last_edited_time(@id)
|
173
|
-
operations = [
|
174
|
-
set_block_dead_hash,
|
175
|
-
block_location_remove_hash,
|
176
|
-
parent_location_hash,
|
177
|
-
block_location_add_hash,
|
178
|
-
last_edited_time_parent_hash,
|
179
|
-
last_edited_time_child_hash
|
180
|
-
]
|
181
|
-
else
|
182
|
-
last_edited_time_new_parent_hash = Utils::BlockComponents.last_edited_time(target_block.parent_id)
|
183
|
-
last_edited_time_child_hash = Utils::BlockComponents.last_edited_time(@id)
|
184
|
-
@parent_id = target_block.parent_id
|
185
|
-
operations = [
|
186
|
-
set_block_dead_hash,
|
187
|
-
block_location_remove_hash,
|
188
|
-
parent_location_hash,
|
189
|
-
block_location_add_hash,
|
190
|
-
last_edited_time_parent_hash,
|
191
|
-
last_edited_time_new_parent_hash,
|
192
|
-
last_edited_time_child_hash
|
193
|
-
]
|
194
|
-
end
|
59
|
+
|
195
60
|
request_body = build_payload(operations, request_ids)
|
196
61
|
response = HTTParty.post(
|
197
62
|
request_url,
|
198
63
|
body: request_body.to_json,
|
199
64
|
cookies: cookies,
|
200
|
-
headers: headers
|
65
|
+
headers: headers,
|
201
66
|
)
|
202
67
|
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}.
|
203
|
-
|
204
|
-
|
205
|
-
|
68
|
+
Please try again, and if issues persist open an issue in GitHub."; end
|
69
|
+
|
70
|
+
block_class_to_convert_to.new(@id, @title, @parent_id)
|
206
71
|
end
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
72
|
+
end
|
73
|
+
|
74
|
+
def duplicate(target_block = nil)
|
75
|
+
# ! duplicate the block that this method is invoked upon.
|
76
|
+
# ! target_block -> the block to place the duplicated block after. Can be any valid Block ID! : ``str``
|
77
|
+
cookies = Core.options["cookies"]
|
78
|
+
headers = Core.options["headers"]
|
79
|
+
request_url = URLS[:UPDATE_BLOCK]
|
80
|
+
|
81
|
+
new_block_id = extract_id(SecureRandom.hex(16))
|
82
|
+
request_id = extract_id(SecureRandom.hex(16))
|
83
|
+
transaction_id = extract_id(SecureRandom.hex(16))
|
84
|
+
space_id = extract_id(SecureRandom.hex(16))
|
85
|
+
|
86
|
+
root_children = children_ids(@id)
|
87
|
+
sub_children = []
|
88
|
+
root_children.each { |root_id| sub_children.push(children_ids(root_id)) }
|
89
|
+
|
90
|
+
request_ids = {
|
91
|
+
request_id: request_id,
|
92
|
+
transaction_id: transaction_id,
|
93
|
+
space_id: space_id,
|
94
|
+
}
|
95
|
+
body = {
|
96
|
+
pageId: @id,
|
97
|
+
chunkNumber: 0,
|
98
|
+
limit: 100,
|
99
|
+
verticalColumns: false,
|
100
|
+
}
|
101
|
+
|
102
|
+
user_notion_id = get_notion_id(body)
|
103
|
+
|
104
|
+
block = target_block ? get(target_block) : self # allows dev to place block anywhere!
|
105
|
+
|
106
|
+
props_and_formatting = get_block_props_and_format(@id, @title)
|
107
|
+
props = props_and_formatting[:properties]
|
108
|
+
formats = props_and_formatting[:format]
|
109
|
+
duplicate_hash = Utils::BlockComponents.duplicate(type, @title, block.id, new_block_id, user_notion_id, root_children, props, formats)
|
110
|
+
set_parent_alive_hash = Utils::BlockComponents.set_parent_to_alive(block.parent_id, new_block_id)
|
111
|
+
block_location_hash = Utils::BlockComponents.block_location_add(block.parent_id, block.id, new_block_id, target_block, "listAfter")
|
112
|
+
last_edited_time_parent_hash = Utils::BlockComponents.last_edited_time(block.parent_id)
|
113
|
+
last_edited_time_child_hash = Utils::BlockComponents.last_edited_time(block.id)
|
114
|
+
|
115
|
+
operations = [
|
116
|
+
duplicate_hash,
|
117
|
+
set_parent_alive_hash,
|
118
|
+
block_location_hash,
|
119
|
+
last_edited_time_parent_hash,
|
120
|
+
last_edited_time_child_hash,
|
121
|
+
]
|
122
|
+
|
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
|
+
class_to_return = NotionAPI.const_get(Classes.select { |cls| NotionAPI.const_get(cls).notion_type == type }.join.to_s)
|
134
|
+
class_to_return.new(new_block_id, @title, block.parent_id)
|
135
|
+
end
|
243
136
|
|
137
|
+
def move(target_block, position = "after")
|
138
|
+
# ! move the block to a new location.
|
139
|
+
# ! target_block -> the targetted block to move to. : ``str``
|
140
|
+
# ! position -> where the block should be listed, in positions relative to the target_block [before, after, top-child, last-child]
|
141
|
+
positions_hash = {
|
142
|
+
"after" => "listAfter",
|
143
|
+
"before" => "listBefore",
|
144
|
+
}
|
145
|
+
|
146
|
+
unless positions_hash.keys.include?(position); raise ArgumentError, "Invalid position. You said: #{position}, valid options are: #{positions_hash.keys.join(", ")}"; end
|
147
|
+
|
148
|
+
position_command = positions_hash[position]
|
149
|
+
cookies = Core.options["cookies"]
|
150
|
+
headers = Core.options["headers"]
|
151
|
+
request_url = URLS[:UPDATE_BLOCK]
|
152
|
+
|
153
|
+
request_id = extract_id(SecureRandom.hex(16))
|
154
|
+
transaction_id = extract_id(SecureRandom.hex(16))
|
155
|
+
space_id = extract_id(SecureRandom.hex(16))
|
156
|
+
|
157
|
+
request_ids = {
|
158
|
+
request_id: request_id,
|
159
|
+
transaction_id: transaction_id,
|
160
|
+
space_id: space_id,
|
161
|
+
}
|
162
|
+
|
163
|
+
is_same_parent = (@parent_id == target_block.parent_id)
|
164
|
+
set_block_dead_hash = Utils::BlockComponents.set_block_to_dead(@id) # kill the block this method is invoked on...
|
165
|
+
block_location_remove_hash = Utils::BlockComponents.block_location_remove(@parent_id, @id) # remove the block this method is invoked on...
|
166
|
+
parent_location_hash = Utils::BlockComponents.parent_location_add(is_same_parent ? @parent_id : target_block.parent_id, @id) # set parent location to alive
|
167
|
+
block_location_add_hash = Utils::BlockComponents.block_location_add(is_same_parent ? @parent_id : target_block.parent_id, @id, target_block.id, position_command)
|
168
|
+
last_edited_time_parent_hash = Utils::BlockComponents.last_edited_time(@parent_id)
|
169
|
+
|
170
|
+
if is_same_parent
|
171
|
+
last_edited_time_child_hash = Utils::BlockComponents.last_edited_time(@id)
|
244
172
|
operations = [
|
245
|
-
|
246
|
-
|
247
|
-
|
173
|
+
set_block_dead_hash,
|
174
|
+
block_location_remove_hash,
|
175
|
+
parent_location_hash,
|
176
|
+
block_location_add_hash,
|
248
177
|
last_edited_time_parent_hash,
|
249
178
|
last_edited_time_child_hash,
|
250
|
-
title_hash
|
251
179
|
]
|
180
|
+
else
|
181
|
+
last_edited_time_new_parent_hash = Utils::BlockComponents.last_edited_time(target_block.parent_id)
|
182
|
+
last_edited_time_child_hash = Utils::BlockComponents.last_edited_time(@id)
|
183
|
+
@parent_id = target_block.parent_id
|
184
|
+
operations = [
|
185
|
+
set_block_dead_hash,
|
186
|
+
block_location_remove_hash,
|
187
|
+
parent_location_hash,
|
188
|
+
block_location_add_hash,
|
189
|
+
last_edited_time_parent_hash,
|
190
|
+
last_edited_time_new_parent_hash,
|
191
|
+
last_edited_time_child_hash,
|
192
|
+
]
|
193
|
+
end
|
194
|
+
request_body = build_payload(operations, request_ids)
|
195
|
+
response = HTTParty.post(
|
196
|
+
request_url,
|
197
|
+
body: request_body.to_json,
|
198
|
+
cookies: cookies,
|
199
|
+
headers: headers,
|
200
|
+
)
|
201
|
+
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}.
|
202
|
+
Please try again, and if issues persist open an issue in GitHub."; end
|
252
203
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
204
|
+
self
|
205
|
+
end
|
206
|
+
|
207
|
+
def create(block_type, block_title, target = nil, position = "after", options: {})
|
208
|
+
# ! create a new block
|
209
|
+
# ! block_type -> the type of block to create : ``cls``
|
210
|
+
# ! block_title -> the title of the new block : ``str``
|
211
|
+
# ! target -> the block_id that the new block should be placed after. ``str``
|
212
|
+
# ! position -> 'after' or 'before'
|
213
|
+
|
214
|
+
positions_hash = {
|
215
|
+
"after" => "listAfter",
|
216
|
+
"before" => "listBefore",
|
217
|
+
}
|
218
|
+
unless positions_hash.keys.include?(position); raise "Invalid position. You said: #{position}, valid options are: #{positions_hash.keys.join(", ")}"; end
|
219
|
+
|
220
|
+
position_command = positions_hash[position]
|
221
|
+
|
222
|
+
new_block_id = extract_id(SecureRandom.hex(16))
|
223
|
+
request_id = extract_id(SecureRandom.hex(16))
|
224
|
+
transaction_id = extract_id(SecureRandom.hex(16))
|
225
|
+
space_id = extract_id(SecureRandom.hex(16))
|
226
|
+
|
227
|
+
request_ids = {
|
228
|
+
request_id: request_id,
|
229
|
+
transaction_id: transaction_id,
|
230
|
+
space_id: space_id,
|
231
|
+
}
|
232
|
+
|
233
|
+
block_type.create(@id, new_block_id, block_title, target, position_command, request_ids, options)
|
234
|
+
end
|
235
|
+
|
236
|
+
private
|
237
|
+
|
238
|
+
def self.create(block_id, new_block_id, block_title, target, position_command, request_ids, options)
|
239
|
+
blocks_with_emojis = [NotionAPI::PageBlock, NotionAPI::CalloutBlock]
|
240
|
+
cookies = Core.options["cookies"]
|
241
|
+
headers = Core.options["headers"]
|
242
|
+
|
243
|
+
create_hash = Utils::BlockComponents.create(new_block_id, self.notion_type)
|
244
|
+
set_parent_alive_hash = Utils::BlockComponents.set_parent_to_alive(block_id, new_block_id)
|
245
|
+
block_location_hash = Utils::BlockComponents.block_location_add(block_id, block_id, new_block_id, target, position_command)
|
246
|
+
last_edited_time_parent_hash = Utils::BlockComponents.last_edited_time(block_id)
|
247
|
+
last_edited_time_child_hash = Utils::BlockComponents.last_edited_time(block_id)
|
248
|
+
title_hash = Utils::BlockComponents.title(new_block_id, block_title)
|
249
|
+
|
250
|
+
operations = [
|
251
|
+
create_hash,
|
252
|
+
set_parent_alive_hash,
|
253
|
+
block_location_hash,
|
254
|
+
last_edited_time_parent_hash,
|
255
|
+
last_edited_time_child_hash,
|
256
|
+
title_hash,
|
257
|
+
]
|
258
|
+
|
259
|
+
if blocks_with_emojis.include?(self)
|
260
|
+
emoji_choices = ["😀", "😃", "😄", "😁", "😆", "😅", "🤣", "😂", "🙂", "🙃", "😉", "😊", "😇", "🥰", "😍", "😀", "😃"]
|
261
|
+
emoji = emoji_choices[rand(0...emoji_choices.length)]
|
262
|
+
emoji_icon_hash = Utils::BlockComponents.add_emoji_icon(new_block_id, emoji)
|
263
|
+
operations.push(emoji_icon_hash)
|
273
264
|
end
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
265
|
+
|
266
|
+
request_url = URLS[:UPDATE_BLOCK]
|
267
|
+
request_body = Utils::BlockComponents.build_payload(operations, request_ids)
|
268
|
+
response = HTTParty.post(
|
269
|
+
request_url,
|
270
|
+
body: request_body.to_json,
|
271
|
+
cookies: cookies,
|
272
|
+
headers: headers,
|
273
|
+
)
|
274
|
+
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}.
|
275
|
+
Please try again, and if issues persist open an issue in GitHub."; end
|
276
|
+
|
277
|
+
self.new(new_block_id, block_title, block_id)
|
278
|
+
end
|
279
|
+
|
280
|
+
def get(url_or_id)
|
281
|
+
# ! retrieve a Notion Block and return its instantiated class object.
|
282
|
+
# ! url_or_id -> the block ID or URL : ``str``
|
283
|
+
clean_id = extract_id(url_or_id)
|
284
|
+
|
285
|
+
request_body = {
|
286
|
+
pageId: clean_id,
|
287
|
+
chunkNumber: 0,
|
288
|
+
limit: 100,
|
289
|
+
verticalColumns: false,
|
290
|
+
}
|
291
|
+
jsonified_record_response = get_all_block_info(request_body)
|
292
|
+
|
293
|
+
block_type = extract_type(clean_id, jsonified_record_response)
|
294
|
+
block_parent_id = extract_parent_id(clean_id, jsonified_record_response)
|
295
|
+
|
296
|
+
if block_type.nil?
|
297
|
+
{}
|
298
|
+
else
|
299
|
+
block_class = NotionAPI.const_get(BLOCK_TYPES[block_type].to_s)
|
300
|
+
if [NotionAPI::CollectionView, NotionAPI::CollectionViewPage].include?(block_class)
|
301
|
+
block_collection_id = extract_collection_id(clean_id, jsonified_record_response)
|
302
|
+
block_view_id = extract_view_ids(clean_id, jsonified_record_response)
|
303
|
+
collection_title = extract_collection_title(clean_id, block_collection_id, jsonified_record_response)
|
304
|
+
|
305
|
+
block = block_class.new(clean_id, collection_title, block_parent_id, block_collection_id, block_view_id.join)
|
306
|
+
schema = extract_collection_schema(block_collection_id, block_view_id[0])
|
307
|
+
column_mappings = schema.keys
|
308
|
+
column_names = column_mappings.map { |mapping| schema[mapping]["name"] }
|
309
|
+
block.instance_variable_set(:@column_names, column_names)
|
310
|
+
CollectionView.class_eval { attr_reader :column_names }
|
311
|
+
|
312
|
+
block
|
301
313
|
else
|
302
|
-
|
303
|
-
|
304
|
-
block_collection_id = extract_collection_id(clean_id, jsonified_record_response)
|
305
|
-
block_view_id = extract_view_ids(clean_id, jsonified_record_response)
|
306
|
-
collection_title = extract_collection_title(clean_id, block_collection_id, jsonified_record_response)
|
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
|
316
|
-
else
|
317
|
-
block_title = extract_title(clean_id, jsonified_record_response)
|
318
|
-
block_class.new(clean_id, block_title, block_parent_id)
|
319
|
-
end
|
314
|
+
block_title = extract_title(clean_id, jsonified_record_response)
|
315
|
+
block_class.new(clean_id, block_title, block_parent_id)
|
320
316
|
end
|
321
317
|
end
|
322
|
-
|
323
|
-
def update_title(new_title, request_id, transaction_id, space_id)
|
324
|
-
# ! Helper method for sending POST request to change title of block.
|
325
|
-
# ! new_title -> new title for the block : ``str``
|
326
|
-
# ! request_id -> the unique ID for the request key. Generated using SecureRandom : ``str``
|
327
|
-
# ! transaction_id -> the unique ID for the transaction key. Generated using SecureRandom: ``str``
|
328
|
-
# ! transaction_id -> the unique ID for the space key. Generated using SecureRandom: ``str``
|
329
|
-
# setup cookies, headers, and grab/create static vars for request
|
330
|
-
cookies = Core.options['cookies']
|
331
|
-
headers = Core.options['headers']
|
332
|
-
request_url = URLS[:UPDATE_BLOCK]
|
333
|
-
|
334
|
-
# set unique IDs for request
|
335
|
-
request_ids = {
|
336
|
-
request_id: request_id,
|
337
|
-
transaction_id: transaction_id,
|
338
|
-
space_id: space_id
|
339
|
-
}
|
340
|
-
|
341
|
-
# build and set operations to send to Notion
|
342
|
-
title_hash = Utils::BlockComponents.title(@id, new_title)
|
343
|
-
last_edited_time_child_hash = Utils::BlockComponents.last_edited_time(@id)
|
344
|
-
operations = [
|
345
|
-
title_hash,
|
346
|
-
last_edited_time_child_hash
|
347
|
-
]
|
348
|
-
|
349
|
-
request_body = build_payload(operations, request_ids) # defined in utils.rb
|
350
|
-
|
351
|
-
response = HTTParty.post(
|
352
|
-
request_url,
|
353
|
-
body: request_body.to_json,
|
354
|
-
cookies: cookies,
|
355
|
-
headers: headers
|
356
|
-
)
|
357
|
-
response.body
|
358
|
-
end
|
359
318
|
end
|
360
|
-
|
319
|
+
|
320
|
+
def update_title(new_title, request_id, transaction_id, space_id)
|
321
|
+
# ! Helper method for sending POST request to change title of block.
|
322
|
+
# ! new_title -> new title for the block : ``str``
|
323
|
+
# ! request_id -> the unique ID for the request key. Generated using SecureRandom : ``str``
|
324
|
+
# ! transaction_id -> the unique ID for the transaction key. Generated using SecureRandom: ``str``
|
325
|
+
# ! transaction_id -> the unique ID for the space key. Generated using SecureRandom: ``str``
|
326
|
+
# setup cookies, headers, and grab/create static vars for request
|
327
|
+
cookies = Core.options["cookies"]
|
328
|
+
headers = Core.options["headers"]
|
329
|
+
request_url = URLS[:UPDATE_BLOCK]
|
330
|
+
|
331
|
+
# set unique IDs for request
|
332
|
+
request_ids = {
|
333
|
+
request_id: request_id,
|
334
|
+
transaction_id: transaction_id,
|
335
|
+
space_id: space_id,
|
336
|
+
}
|
337
|
+
|
338
|
+
# build and set operations to send to Notion
|
339
|
+
title_hash = Utils::BlockComponents.title(@id, new_title)
|
340
|
+
last_edited_time_child_hash = Utils::BlockComponents.last_edited_time(@id)
|
341
|
+
operations = [
|
342
|
+
title_hash,
|
343
|
+
last_edited_time_child_hash,
|
344
|
+
]
|
345
|
+
|
346
|
+
request_body = build_payload(operations, request_ids) # defined in utils.rb
|
347
|
+
|
348
|
+
response = HTTParty.post(
|
349
|
+
request_url,
|
350
|
+
body: request_body.to_json,
|
351
|
+
cookies: cookies,
|
352
|
+
headers: headers,
|
353
|
+
)
|
354
|
+
response.body
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|