notion-ruby-client 0.0.7 → 1.0.0.pre.beta1
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/.devcontainer/Dockerfile +5 -0
- data/.devcontainer/boot.sh +1 -0
- data/.devcontainer/devcontainer.json +30 -0
- data/.github/workflows/ci.yml +1 -0
- data/.gitignore +7 -0
- data/.rubocop.yml +9 -0
- data/CHANGELOG.md +42 -0
- data/CONTRIBUTING.md +51 -0
- data/Gemfile.lock +39 -12
- data/README.md +377 -79
- data/bin/console +31 -0
- data/lib/notion/api/endpoints/blocks.rb +51 -7
- data/lib/notion/api/endpoints/databases.rb +60 -31
- data/lib/notion/api/endpoints/pages.rb +25 -8
- data/lib/notion/api/endpoints/search.rb +41 -0
- data/lib/notion/api/endpoints/users.rb +14 -3
- data/lib/notion/api/endpoints.rb +3 -1
- data/lib/notion/api/errors/too_many_requests.rb +15 -0
- data/lib/notion/api/errors.rb +0 -2
- data/lib/notion/config.rb +2 -0
- data/lib/notion/pagination/cursor.rb +5 -2
- data/lib/notion/version.rb +2 -2
- data/lib/notion-ruby-client.rb +2 -0
- data/notion-ruby-client.gemspec +4 -2
- data/spec/fixtures/notion/block.yml +146 -0
- data/spec/fixtures/notion/block_append_children.yml +76 -62
- data/spec/fixtures/notion/block_children.yml +80 -65
- data/spec/fixtures/notion/create_database.yml +149 -0
- data/spec/fixtures/notion/create_page.yml +76 -61
- data/spec/fixtures/notion/database.yml +78 -61
- data/spec/fixtures/notion/database_query.yml +81 -62
- data/spec/fixtures/notion/delete_block.yml +145 -0
- data/spec/fixtures/notion/page.yml +78 -61
- data/spec/fixtures/notion/page_property_item.yml +143 -0
- data/spec/fixtures/notion/paginated_block_children.yml +296 -242
- data/spec/fixtures/notion/paginated_database_query.yml +79 -62
- data/spec/fixtures/notion/paginated_databases_list.yml +78 -61
- data/spec/fixtures/notion/paginated_search.yml +301 -0
- data/spec/fixtures/notion/paginated_users_list.yml +143 -130
- data/spec/fixtures/notion/search.yml +160 -0
- data/spec/fixtures/notion/search_with_query.yml +152 -0
- data/spec/fixtures/notion/update_block.yml +148 -0
- data/spec/fixtures/notion/update_database.yml +152 -0
- data/spec/fixtures/notion/update_page.yml +79 -63
- data/spec/fixtures/notion/users.yml +69 -56
- data/spec/fixtures/notion/users_list.yml +143 -130
- data/spec/fixtures/notion/users_me.yml +144 -0
- data/spec/notion/api/endpoints/blocks_spec.rb +44 -12
- data/spec/notion/api/endpoints/databases_spec.rb +38 -17
- data/spec/notion/api/endpoints/pages_spec.rb +21 -13
- data/spec/notion/api/endpoints/search_spec.rb +26 -0
- data/spec/notion/api/endpoints/users_spec.rb +9 -4
- data/spec/notion/pagination/cursor_spec.rb +126 -0
- metadata +73 -19
- data/.rspec_status +0 -18
- data/notion-ruby-client-0.0.4.gem +0 -0
- data/scratchpad.rb +0 -22
- data/screenshots/create_notion_bot.png +0 -0
- data/spec/fixtures/notion/databases_list.yml +0 -133
@@ -4,6 +4,50 @@ module Notion
|
|
4
4
|
module Api
|
5
5
|
module Endpoints
|
6
6
|
module Blocks
|
7
|
+
#
|
8
|
+
# Retrieves a Block object using the ID specified.
|
9
|
+
#
|
10
|
+
# @option options [id] :block_id
|
11
|
+
# Block to get children info on.
|
12
|
+
def block(options = {})
|
13
|
+
throw ArgumentError.new('Required arguments :block_id missing') if options[:block_id].nil?
|
14
|
+
get("blocks/#{options[:block_id]}")
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# Updates the content for the specified block_id based on
|
19
|
+
# the block type. Supported fields based on the block object
|
20
|
+
# type (see Block object for available fields and the
|
21
|
+
# expected input for each field).
|
22
|
+
#
|
23
|
+
# @option options [id] :block_id
|
24
|
+
# Block to get children info on.
|
25
|
+
#
|
26
|
+
# @option options [string] {type}
|
27
|
+
# The block object type value with the properties to be
|
28
|
+
# updated. Currently only text (for supported block types)
|
29
|
+
# and checked (for to_do blocks) fields can be updated.
|
30
|
+
def update_block(options = {})
|
31
|
+
throw ArgumentError.new('Required arguments :block_id missing') if options[:block_id].nil?
|
32
|
+
patch("blocks/#{options[:block_id]}", options.except(:block_id))
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# Sets a Block object, including page blocks, to archived: true
|
37
|
+
# using the ID specified. Note: in the Notion UI application, this
|
38
|
+
# moves the block to the "Trash" where it can still be accessed and
|
39
|
+
# restored.
|
40
|
+
#
|
41
|
+
# To restore the block with the API, use the Update a block or
|
42
|
+
# Update page respectively.
|
43
|
+
#
|
44
|
+
# @option options [id] :block_id
|
45
|
+
# Block to get children info on.
|
46
|
+
def delete_block(options = {})
|
47
|
+
throw ArgumentError.new('Required arguments :block_id missing') if options[:block_id].nil?
|
48
|
+
delete("blocks/#{options[:block_id]}")
|
49
|
+
end
|
50
|
+
|
7
51
|
#
|
8
52
|
# Returns a paginated array of Block objects contained in the
|
9
53
|
# block of the requested path using the ID specified.
|
@@ -14,16 +58,16 @@ module Notion
|
|
14
58
|
#
|
15
59
|
# Returns a 400 or 429 HTTP response if the request exceeds Notion's Request limits.
|
16
60
|
#
|
17
|
-
# @option options [id] :
|
61
|
+
# @option options [id] :block_id
|
18
62
|
# Block to get children info on.
|
19
63
|
def block_children(options = {})
|
20
|
-
throw ArgumentError.new('Required arguments :
|
64
|
+
throw ArgumentError.new('Required arguments :block_id missing') if options[:block_id].nil?
|
21
65
|
if block_given?
|
22
66
|
Pagination::Cursor.new(self, :block_children, options).each do |page|
|
23
67
|
yield page
|
24
68
|
end
|
25
69
|
else
|
26
|
-
get("blocks/#{options[:
|
70
|
+
get("blocks/#{options[:block_id]}/children", options.except(:block_id))
|
27
71
|
end
|
28
72
|
end
|
29
73
|
|
@@ -38,14 +82,14 @@ module Notion
|
|
38
82
|
#
|
39
83
|
# Returns a 400 or 429 HTTP response if the request exceeds Notion's Request limits.
|
40
84
|
#
|
41
|
-
# @option options [id] :
|
42
|
-
# Block to
|
85
|
+
# @option options [id] :block_id
|
86
|
+
# Block to append children to.
|
43
87
|
#
|
44
88
|
# @option options [[Object]] :children
|
45
89
|
# Children blocks to append
|
46
90
|
def block_append_children(options = {})
|
47
|
-
throw ArgumentError.new('Required arguments :
|
48
|
-
patch("blocks/#{options[:
|
91
|
+
throw ArgumentError.new('Required arguments :block_id missing') if options[:block_id].nil?
|
92
|
+
patch("blocks/#{options[:block_id]}/children", options.except(:block_id))
|
49
93
|
end
|
50
94
|
end
|
51
95
|
end
|
@@ -4,20 +4,6 @@ module Notion
|
|
4
4
|
module Api
|
5
5
|
module Endpoints
|
6
6
|
module Databases
|
7
|
-
#
|
8
|
-
# Retrieves a Database object using the ID specified in the request.
|
9
|
-
#
|
10
|
-
# Returns a 404 HTTP response if the database doesn't exist, or if the bot
|
11
|
-
# doesn't have access to the database. Returns a 429 HTTP response if the
|
12
|
-
# request exceeds Notion's Request limits.
|
13
|
-
#
|
14
|
-
# @option options [id] :id
|
15
|
-
# Database to get info on.
|
16
|
-
def database(options = {})
|
17
|
-
throw ArgumentError.new('Required arguments :id missing') if options[:id].nil?
|
18
|
-
get("databases/#{options[:id]}")
|
19
|
-
end
|
20
|
-
|
21
7
|
#
|
22
8
|
# Gets a paginated array of Page object s contained in the requested database,
|
23
9
|
# filtered and ordered according to the filter and sort objects provided in the request.
|
@@ -30,7 +16,7 @@ module Notion
|
|
30
16
|
# database properties and can be combined. The order of the sorts in the request
|
31
17
|
# matter, with earlier sorts taking precedence over later ones.
|
32
18
|
#
|
33
|
-
# @option options [id] :
|
19
|
+
# @option options [id] :database_id
|
34
20
|
# Database to query.
|
35
21
|
#
|
36
22
|
# @option options [Object] :filter
|
@@ -44,33 +30,76 @@ module Notion
|
|
44
30
|
# to a start_cursor attribute returned by a previous request's next_cursor.
|
45
31
|
# Default value fetches the first "page" of the collection.
|
46
32
|
# See pagination for more detail.
|
33
|
+
#
|
34
|
+
# @option options [integer] :page_size
|
35
|
+
# The number of items from the full list desired in the response. Maximum: 100
|
47
36
|
def database_query(options = {})
|
48
|
-
throw ArgumentError.new('Required arguments :
|
37
|
+
throw ArgumentError.new('Required arguments :database_id missing') if options[:database_id].nil?
|
49
38
|
if block_given?
|
50
39
|
Pagination::Cursor.new(self, :database_query, options).each do |page|
|
51
40
|
yield page
|
52
41
|
end
|
53
42
|
else
|
54
|
-
post("databases/#{options[:
|
43
|
+
post("databases/#{options[:database_id]}/query", options.except(:database_id))
|
55
44
|
end
|
56
45
|
end
|
57
46
|
|
58
47
|
#
|
59
|
-
#
|
48
|
+
# Creates a new database in the specified page.
|
60
49
|
#
|
61
|
-
# @option options [
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
50
|
+
# @option options [Object] :parent
|
51
|
+
# Parent of the database, which is always going to be a page.
|
52
|
+
#
|
53
|
+
# @option options [Object] :title
|
54
|
+
# Title of this database.
|
55
|
+
#
|
56
|
+
# @option options [Object] :properties
|
57
|
+
# Property schema of database.
|
58
|
+
# The keys are the names of properties as they appear in Notion and the values are
|
59
|
+
# property schema objects. Property Schema Object is a metadata that controls
|
60
|
+
# how a database property behaves, e.g. {"checkbox": {}}.
|
61
|
+
# Each database must have exactly one database property schema object of type "title".
|
62
|
+
def create_database(options = {})
|
63
|
+
throw ArgumentError.new('Required arguments :parent.page_id missing') if options.dig(:parent, :page_id).nil?
|
64
|
+
throw ArgumentError.new('Required arguments :title missing') if options.dig(:title).nil?
|
65
|
+
throw ArgumentError.new('Required arguments :properties missing') if options.dig(:properties).nil?
|
66
|
+
post('databases', options)
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Updates an existing database as specified by the parameters.
|
71
|
+
#
|
72
|
+
# @option options [id] :database_id
|
73
|
+
# Database to update.
|
74
|
+
#
|
75
|
+
# @option options [Object] :title
|
76
|
+
# Title of database as it appears in Notion. An array of rich text objects.
|
77
|
+
# If omitted, the database title will remain unchanged.
|
78
|
+
#
|
79
|
+
# @option options [Object] :properties
|
80
|
+
# Updates to the property schema of a database.
|
81
|
+
# If updating an existing property, the keys are the names or IDs
|
82
|
+
# of the properties as they appear in Notion and the values
|
83
|
+
# are property schema objects. If adding a new property, the key is
|
84
|
+
# the name of the database property and the value is a property schema object.
|
85
|
+
#
|
86
|
+
def update_database(options = {})
|
87
|
+
throw ArgumentError.new('Required arguments :database_id missing') if options.dig(:database_id).nil?
|
88
|
+
patch("databases/#{options[:database_id]}", options.except(:database_id))
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Retrieves a Database object using the ID specified in the request.
|
93
|
+
#
|
94
|
+
# Returns a 404 HTTP response if the database doesn't exist, or if the bot
|
95
|
+
# doesn't have access to the database. Returns a 429 HTTP response if the
|
96
|
+
# request exceeds Notion's Request limits.
|
97
|
+
#
|
98
|
+
# @option options [id] :database_id
|
99
|
+
# Database to get info on.
|
100
|
+
def database(options = {})
|
101
|
+
throw ArgumentError.new('Required arguments :database_id missing') if options[:database_id].nil?
|
102
|
+
get("databases/#{options[:database_id]}")
|
74
103
|
end
|
75
104
|
end
|
76
105
|
end
|
@@ -8,15 +8,15 @@ module Notion
|
|
8
8
|
# Retrieves a 📄Page object using the ID specified in the request path.
|
9
9
|
# Note that this version of the API only exposes page properties, not page content
|
10
10
|
#
|
11
|
-
# @option options [id] :
|
11
|
+
# @option options [id] :page_id
|
12
12
|
# Page to get info on.
|
13
13
|
#
|
14
14
|
# @option options [bool] :archived
|
15
15
|
# Set to true to retrieve an archived page; must be false or omitted to
|
16
16
|
# retrieve a page that has not been archived. Defaults to false.
|
17
17
|
def page(options = {})
|
18
|
-
throw ArgumentError.new('Required
|
19
|
-
get("pages/#{options[:
|
18
|
+
throw ArgumentError.new('Required argument :page_id missing') if options[:page_id].nil?
|
19
|
+
get("pages/#{options[:page_id]}")
|
20
20
|
end
|
21
21
|
|
22
22
|
#
|
@@ -36,9 +36,9 @@ module Notion
|
|
36
36
|
# specific to the property type, e.g. {"checkbox": true}.
|
37
37
|
#
|
38
38
|
# @option options [Object] :children
|
39
|
-
# An optional array of Block objects representing the Page’s
|
39
|
+
# An optional array of Block objects representing the Page’s content
|
40
40
|
def create_page(options = {})
|
41
|
-
throw ArgumentError.new('Required
|
41
|
+
throw ArgumentError.new('Required argument :parent.database_id missing') if options.dig(:parent, :database_id).nil?
|
42
42
|
post("pages", options)
|
43
43
|
end
|
44
44
|
|
@@ -50,7 +50,7 @@ module Notion
|
|
50
50
|
# Note that this iteration of the API will only expose page properties, not page
|
51
51
|
# content, as described in the data model.
|
52
52
|
#
|
53
|
-
# @option options [id] :
|
53
|
+
# @option options [id] :page_id
|
54
54
|
# Page to get info on.
|
55
55
|
#
|
56
56
|
# @option options [Object] :properties
|
@@ -60,8 +60,25 @@ module Notion
|
|
60
60
|
# appears in Notion, or property ID. value object Object containing a value
|
61
61
|
# specific to the property type, e.g. {"checkbox": true}.
|
62
62
|
def update_page(options = {})
|
63
|
-
throw ArgumentError.new('Required
|
64
|
-
patch("pages/#{options[:
|
63
|
+
throw ArgumentError.new('Required argument :page_id missing') if options[:page_id].nil?
|
64
|
+
patch("pages/#{options[:page_id]}", options.except(:page_id))
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Retrieves a `property_item` object for a given `page_id` and `property_id`.
|
69
|
+
# Depending on the property type, the object returned will either be a value
|
70
|
+
# or a paginated list of property item values.
|
71
|
+
#
|
72
|
+
# @option options [id] :page_id
|
73
|
+
# Page to get info on.
|
74
|
+
#
|
75
|
+
# @option options [id] :property_id
|
76
|
+
# Property to get info on.
|
77
|
+
#
|
78
|
+
def page_property_item(options = {})
|
79
|
+
throw ArgumentError.new('Required argument :page_id missing') if options[:page_id].nil?
|
80
|
+
throw ArgumentError.new('Required argument :property_id missing') if options[:property_id].nil?
|
81
|
+
get("pages/#{options[:page_id]}/properties/#{options[:property_id]}")
|
65
82
|
end
|
66
83
|
end
|
67
84
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Notion
|
4
|
+
module Api
|
5
|
+
module Endpoints
|
6
|
+
module Search
|
7
|
+
#
|
8
|
+
# Searches all pages and child pages that are shared with the integration.
|
9
|
+
# The results may include databases.
|
10
|
+
#
|
11
|
+
# @option options [string] :query
|
12
|
+
# When supplied, limits which pages are returned by comparing the query to the page title.
|
13
|
+
#
|
14
|
+
# @option options [Object] :filter
|
15
|
+
# When supplied, filters the results based on the provided criteria.
|
16
|
+
#
|
17
|
+
# @option options [[Object]] :sorts
|
18
|
+
# When supplied, sorts the results based on the provided criteria.
|
19
|
+
# Limitation: Currently only a single sort is allowed and is limited to last_edited_time.
|
20
|
+
#
|
21
|
+
# @option options [UUID] :start_cursor
|
22
|
+
# Paginate through collections of data by setting the cursor parameter
|
23
|
+
# to a start_cursor attribute returned by a previous request's next_cursor.
|
24
|
+
# Default value fetches the first "page" of the collection.
|
25
|
+
# See pagination for more detail.
|
26
|
+
#
|
27
|
+
# @option options [integer] :page_size
|
28
|
+
# The number of items from the full list desired in the response. Maximum: 100
|
29
|
+
def search(options = {})
|
30
|
+
if block_given?
|
31
|
+
Pagination::Cursor.new(self, :search, options).each do |page|
|
32
|
+
yield page
|
33
|
+
end
|
34
|
+
else
|
35
|
+
post('search', options)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -4,14 +4,22 @@ module Notion
|
|
4
4
|
module Api
|
5
5
|
module Endpoints
|
6
6
|
module Users
|
7
|
+
#
|
8
|
+
# Retrieves the bot User associated with the API token provided in
|
9
|
+
# the authorization header. The bot will have an `owner` field with
|
10
|
+
# information about the person who authorized the integration.
|
11
|
+
def me
|
12
|
+
get("users/me")
|
13
|
+
end
|
14
|
+
|
7
15
|
#
|
8
16
|
# Retrieves a User object using the ID specified in the request.
|
9
17
|
#
|
10
|
-
# @option options [id] :
|
18
|
+
# @option options [id] :user_id
|
11
19
|
# User to get info on.
|
12
20
|
def user(options = {})
|
13
|
-
throw ArgumentError.new('Required arguments :
|
14
|
-
get("users/#{options[:
|
21
|
+
throw ArgumentError.new('Required arguments :user_id missing') if options[:user_id].nil?
|
22
|
+
get("users/#{options[:user_id]}")
|
15
23
|
end
|
16
24
|
|
17
25
|
#
|
@@ -22,6 +30,9 @@ module Notion
|
|
22
30
|
# to a start_cursor attribute returned by a previous request's next_cursor.
|
23
31
|
# Default value fetches the first "page" of the collection.
|
24
32
|
# See pagination for more detail.
|
33
|
+
#
|
34
|
+
# @option options [integer] :page_size
|
35
|
+
# The number of items from the full list desired in the response. Maximum: 100
|
25
36
|
def users_list(options = {})
|
26
37
|
if block_given?
|
27
38
|
Pagination::Cursor.new(self, :users_list, options).each do |page|
|
data/lib/notion/api/endpoints.rb
CHANGED
@@ -4,6 +4,7 @@ require_relative 'endpoints/blocks'
|
|
4
4
|
require_relative 'endpoints/databases'
|
5
5
|
require_relative 'endpoints/pages'
|
6
6
|
require_relative 'endpoints/users'
|
7
|
+
require_relative 'endpoints/search'
|
7
8
|
|
8
9
|
module Notion
|
9
10
|
module Api
|
@@ -12,6 +13,7 @@ module Notion
|
|
12
13
|
include Databases
|
13
14
|
include Pages
|
14
15
|
include Users
|
16
|
+
include Search
|
15
17
|
end
|
16
18
|
end
|
17
|
-
end
|
19
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Notion
|
3
|
+
module Api
|
4
|
+
module Errors
|
5
|
+
class TooManyRequests < ::Faraday::Error
|
6
|
+
attr_reader :response
|
7
|
+
|
8
|
+
def initialize(response)
|
9
|
+
@response = response
|
10
|
+
super 'Too many requests'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/notion/api/errors.rb
CHANGED
@@ -8,7 +8,6 @@ module Notion
|
|
8
8
|
class InternalError < NotionError; end
|
9
9
|
class InvalidRequest < NotionError; end
|
10
10
|
class ObjectNotFound < NotionError; end
|
11
|
-
class TooManyRequests < NotionError; end
|
12
11
|
class Unauthorized < NotionError; end
|
13
12
|
|
14
13
|
ERROR_CLASSES = {
|
@@ -17,7 +16,6 @@ module Notion
|
|
17
16
|
'internal_error' => InternalError,
|
18
17
|
'invalid_request' => InvalidRequest,
|
19
18
|
'object_not_found' => ObjectNotFound,
|
20
|
-
'rate_limited' => TooManyRequests,
|
21
19
|
'unauthorized' => Unauthorized
|
22
20
|
}.freeze
|
23
21
|
end
|
data/lib/notion/config.rb
CHANGED
@@ -15,6 +15,7 @@ module Notion
|
|
15
15
|
open_timeout
|
16
16
|
default_page_size
|
17
17
|
default_max_retries
|
18
|
+
default_retry_after
|
18
19
|
adapter
|
19
20
|
].freeze
|
20
21
|
|
@@ -32,6 +33,7 @@ module Notion
|
|
32
33
|
self.open_timeout = nil
|
33
34
|
self.default_page_size = 100
|
34
35
|
self.default_max_retries = 100
|
36
|
+
self.default_retry_after = 10
|
35
37
|
self.adapter = ::Faraday.default_adapter
|
36
38
|
end
|
37
39
|
|
@@ -9,6 +9,7 @@ module Notion
|
|
9
9
|
attr_reader :verb
|
10
10
|
attr_reader :sleep_interval
|
11
11
|
attr_reader :max_retries
|
12
|
+
attr_reader :retry_after
|
12
13
|
attr_reader :params
|
13
14
|
|
14
15
|
def initialize(client, verb, params = {})
|
@@ -17,13 +18,15 @@ module Notion
|
|
17
18
|
@params = params.dup
|
18
19
|
@sleep_interval = @params.delete(:sleep_interval)
|
19
20
|
@max_retries = @params.delete(:max_retries) || client.default_max_retries
|
21
|
+
@retry_after = @params.delete(:retry_after) || client.default_retry_after
|
20
22
|
end
|
21
23
|
|
22
24
|
def each
|
23
25
|
next_cursor = nil
|
24
26
|
retry_count = 0
|
25
27
|
loop do
|
26
|
-
query =
|
28
|
+
query = { page_size: client.default_page_size }.merge(params)
|
29
|
+
query = query.merge(start_cursor: next_cursor) unless next_cursor.nil?
|
27
30
|
begin
|
28
31
|
response = client.send(verb, query)
|
29
32
|
rescue Notion::Api::Errors::TooManyRequests => e
|
@@ -31,7 +34,7 @@ module Notion
|
|
31
34
|
|
32
35
|
client.logger.debug("#{self.class}##{__method__}") { e.to_s }
|
33
36
|
retry_count += 1
|
34
|
-
sleep(
|
37
|
+
sleep(retry_after)
|
35
38
|
next
|
36
39
|
end
|
37
40
|
yield response
|
data/lib/notion/version.rb
CHANGED
data/lib/notion-ruby-client.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'active_support/core_ext/hash/except'
|
2
3
|
require 'faraday'
|
3
4
|
require 'faraday_middleware'
|
4
5
|
require 'json'
|
@@ -17,6 +18,7 @@ require_relative 'notion/api/errors/notion_error'
|
|
17
18
|
require_relative 'notion/api/error'
|
18
19
|
require_relative 'notion/api/errors'
|
19
20
|
require_relative 'notion/api/errors/internal_error'
|
21
|
+
require_relative 'notion/api/errors/too_many_requests'
|
20
22
|
require_relative 'notion/faraday/response/raise_error'
|
21
23
|
require_relative 'notion/faraday/response/wrap_error'
|
22
24
|
require_relative 'notion/faraday/connection'
|
data/notion-ruby-client.gemspec
CHANGED
@@ -15,10 +15,12 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.homepage = 'http://github.com/orbit-love/notion-ruby-client'
|
16
16
|
s.licenses = ['MIT']
|
17
17
|
s.summary = 'Notion API client for Ruby.'
|
18
|
+
s.add_dependency 'activesupport', '~> 6'
|
19
|
+
s.add_dependency 'dotenv'
|
18
20
|
s.add_dependency 'faraday', '>= 1.0'
|
19
21
|
s.add_dependency 'faraday_middleware'
|
20
|
-
s.add_dependency 'hashie'
|
21
|
-
s.add_development_dependency 'rake', '~>
|
22
|
+
s.add_dependency 'hashie', '~> 5'
|
23
|
+
s.add_development_dependency 'rake', '~> 13'
|
22
24
|
s.add_development_dependency 'rspec'
|
23
25
|
s.add_development_dependency 'rubocop', '~> 0.82.0'
|
24
26
|
s.add_development_dependency 'rubocop-performance', '~> 1.5.2'
|
@@ -0,0 +1,146 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://api.notion.com/v1/blocks/32af3324-ba02-4516-ae88-5728a4d569f4
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- application/json; charset=utf-8
|
12
|
+
User-Agent:
|
13
|
+
- Notion Ruby Client/0.0.8
|
14
|
+
Authorization:
|
15
|
+
- Bearer <NOTION_API_TOKEN>
|
16
|
+
Notion-Version:
|
17
|
+
- '2022-02-22'
|
18
|
+
Accept-Encoding:
|
19
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 200
|
23
|
+
message: OK
|
24
|
+
headers:
|
25
|
+
Date:
|
26
|
+
- Sun, 29 Aug 2021 17:45:01 GMT
|
27
|
+
Content-Type:
|
28
|
+
- application/json; charset=utf-8
|
29
|
+
Transfer-Encoding:
|
30
|
+
- chunked
|
31
|
+
Connection:
|
32
|
+
- keep-alive
|
33
|
+
X-Dns-Prefetch-Control:
|
34
|
+
- 'off'
|
35
|
+
X-Frame-Options:
|
36
|
+
- SAMEORIGIN
|
37
|
+
Strict-Transport-Security:
|
38
|
+
- max-age=5184000; includeSubDomains
|
39
|
+
X-Download-Options:
|
40
|
+
- noopen
|
41
|
+
X-Content-Type-Options:
|
42
|
+
- nosniff
|
43
|
+
X-Xss-Protection:
|
44
|
+
- 1; mode=block
|
45
|
+
Referrer-Policy:
|
46
|
+
- same-origin
|
47
|
+
Content-Security-Policy:
|
48
|
+
- 'script-src ''self'' ''unsafe-inline'' ''unsafe-eval'' https://gist.github.com
|
49
|
+
https://apis.google.com https://api.amplitude.com https://widget.intercom.io
|
50
|
+
https://js.intercomcdn.com https://logs-01.loggly.com https://cdn.segment.com
|
51
|
+
https://analytics.pgncs.notion.so https://o324374.ingest.sentry.io https://checkout.stripe.com
|
52
|
+
https://js.stripe.com https://embed.typeform.com https://admin.typeform.com
|
53
|
+
https://public.profitwell.com js.sentry-cdn.com https://js.chilipiper.com
|
54
|
+
https://platform.twitter.com https://cdn.syndication.twimg.com https://www.googletagmanager.com
|
55
|
+
https://x.clearbitjs.com https://client-registry.mutinycdn.com https://client.mutinycdn.com/
|
56
|
+
https://user-data.mutinycdn.com; connect-src ''self'' https://msgstore.www.notion.so
|
57
|
+
wss://msgstore.www.notion.so ws://localhost:* https://notion-emojis.s3-us-west-2.amazonaws.com
|
58
|
+
https://s3-us-west-2.amazonaws.com https://s3.us-west-2.amazonaws.com https://notion-production-snapshots-2.s3.us-west-2.amazonaws.com
|
59
|
+
https: http: https://api.amplitude.com https://api.embed.ly https://js.intercomcdn.com
|
60
|
+
https://api-iam.intercom.io wss://nexus-websocket-a.intercom.io https://logs-01.loggly.com
|
61
|
+
https://cdn.segment.com https://api.segment.io https://analytics.pgncs.notion.so
|
62
|
+
https://api.pgncs.notion.so https://o324374.ingest.sentry.io https://checkout.stripe.com
|
63
|
+
https://js.stripe.com https://cdn.contentful.com https://preview.contentful.com
|
64
|
+
https://images.ctfassets.net https://www2.profitwell.com https://tracking.chilipiper.com
|
65
|
+
https://api.chilipiper.com https://api.unsplash.com https://boards-api.greenhouse.io
|
66
|
+
https://user-data.mutinycdn.com https://api-v2.mutinyhq.io https://api.statuspage.io
|
67
|
+
https://pgncd.notion.so; font-src ''self'' data: https://cdnjs.cloudflare.com
|
68
|
+
https://js.intercomcdn.com; img-src ''self'' data: blob: https: https://platform.twitter.com
|
69
|
+
https://syndication.twitter.com https://pbs.twimg.com https://ton.twimg.com
|
70
|
+
www.googletagmanager.com; style-src ''self'' ''unsafe-inline'' https://cdnjs.cloudflare.com
|
71
|
+
https://github.githubassets.com https://js.chilipiper.com https://platform.twitter.com
|
72
|
+
https://ton.twimg.com; frame-src https: http:; media-src https: http:'
|
73
|
+
X-Content-Security-Policy:
|
74
|
+
- 'script-src ''self'' ''unsafe-inline'' ''unsafe-eval'' https://gist.github.com
|
75
|
+
https://apis.google.com https://api.amplitude.com https://widget.intercom.io
|
76
|
+
https://js.intercomcdn.com https://logs-01.loggly.com https://cdn.segment.com
|
77
|
+
https://analytics.pgncs.notion.so https://o324374.ingest.sentry.io https://checkout.stripe.com
|
78
|
+
https://js.stripe.com https://embed.typeform.com https://admin.typeform.com
|
79
|
+
https://public.profitwell.com js.sentry-cdn.com https://js.chilipiper.com
|
80
|
+
https://platform.twitter.com https://cdn.syndication.twimg.com https://www.googletagmanager.com
|
81
|
+
https://x.clearbitjs.com https://client-registry.mutinycdn.com https://client.mutinycdn.com/
|
82
|
+
https://user-data.mutinycdn.com; connect-src ''self'' https://msgstore.www.notion.so
|
83
|
+
wss://msgstore.www.notion.so ws://localhost:* https://notion-emojis.s3-us-west-2.amazonaws.com
|
84
|
+
https://s3-us-west-2.amazonaws.com https://s3.us-west-2.amazonaws.com https://notion-production-snapshots-2.s3.us-west-2.amazonaws.com
|
85
|
+
https: http: https://api.amplitude.com https://api.embed.ly https://js.intercomcdn.com
|
86
|
+
https://api-iam.intercom.io wss://nexus-websocket-a.intercom.io https://logs-01.loggly.com
|
87
|
+
https://cdn.segment.com https://api.segment.io https://analytics.pgncs.notion.so
|
88
|
+
https://api.pgncs.notion.so https://o324374.ingest.sentry.io https://checkout.stripe.com
|
89
|
+
https://js.stripe.com https://cdn.contentful.com https://preview.contentful.com
|
90
|
+
https://images.ctfassets.net https://www2.profitwell.com https://tracking.chilipiper.com
|
91
|
+
https://api.chilipiper.com https://api.unsplash.com https://boards-api.greenhouse.io
|
92
|
+
https://user-data.mutinycdn.com https://api-v2.mutinyhq.io https://api.statuspage.io
|
93
|
+
https://pgncd.notion.so; font-src ''self'' data: https://cdnjs.cloudflare.com
|
94
|
+
https://js.intercomcdn.com; img-src ''self'' data: blob: https: https://platform.twitter.com
|
95
|
+
https://syndication.twitter.com https://pbs.twimg.com https://ton.twimg.com
|
96
|
+
www.googletagmanager.com; style-src ''self'' ''unsafe-inline'' https://cdnjs.cloudflare.com
|
97
|
+
https://github.githubassets.com https://js.chilipiper.com https://platform.twitter.com
|
98
|
+
https://ton.twimg.com; frame-src https: http:; media-src https: http:'
|
99
|
+
X-Webkit-Csp:
|
100
|
+
- 'script-src ''self'' ''unsafe-inline'' ''unsafe-eval'' https://gist.github.com
|
101
|
+
https://apis.google.com https://api.amplitude.com https://widget.intercom.io
|
102
|
+
https://js.intercomcdn.com https://logs-01.loggly.com https://cdn.segment.com
|
103
|
+
https://analytics.pgncs.notion.so https://o324374.ingest.sentry.io https://checkout.stripe.com
|
104
|
+
https://js.stripe.com https://embed.typeform.com https://admin.typeform.com
|
105
|
+
https://public.profitwell.com js.sentry-cdn.com https://js.chilipiper.com
|
106
|
+
https://platform.twitter.com https://cdn.syndication.twimg.com https://www.googletagmanager.com
|
107
|
+
https://x.clearbitjs.com https://client-registry.mutinycdn.com https://client.mutinycdn.com/
|
108
|
+
https://user-data.mutinycdn.com; connect-src ''self'' https://msgstore.www.notion.so
|
109
|
+
wss://msgstore.www.notion.so ws://localhost:* https://notion-emojis.s3-us-west-2.amazonaws.com
|
110
|
+
https://s3-us-west-2.amazonaws.com https://s3.us-west-2.amazonaws.com https://notion-production-snapshots-2.s3.us-west-2.amazonaws.com
|
111
|
+
https: http: https://api.amplitude.com https://api.embed.ly https://js.intercomcdn.com
|
112
|
+
https://api-iam.intercom.io wss://nexus-websocket-a.intercom.io https://logs-01.loggly.com
|
113
|
+
https://cdn.segment.com https://api.segment.io https://analytics.pgncs.notion.so
|
114
|
+
https://api.pgncs.notion.so https://o324374.ingest.sentry.io https://checkout.stripe.com
|
115
|
+
https://js.stripe.com https://cdn.contentful.com https://preview.contentful.com
|
116
|
+
https://images.ctfassets.net https://www2.profitwell.com https://tracking.chilipiper.com
|
117
|
+
https://api.chilipiper.com https://api.unsplash.com https://boards-api.greenhouse.io
|
118
|
+
https://user-data.mutinycdn.com https://api-v2.mutinyhq.io https://api.statuspage.io
|
119
|
+
https://pgncd.notion.so; font-src ''self'' data: https://cdnjs.cloudflare.com
|
120
|
+
https://js.intercomcdn.com; img-src ''self'' data: blob: https: https://platform.twitter.com
|
121
|
+
https://syndication.twitter.com https://pbs.twimg.com https://ton.twimg.com
|
122
|
+
www.googletagmanager.com; style-src ''self'' ''unsafe-inline'' https://cdnjs.cloudflare.com
|
123
|
+
https://github.githubassets.com https://js.chilipiper.com https://platform.twitter.com
|
124
|
+
https://ton.twimg.com; frame-src https: http:; media-src https: http:'
|
125
|
+
Set-Cookie:
|
126
|
+
- notion_browser_id=5e3ae42a-9c10-4632-bbd6-f8635f637d51; Domain=www.notion.so;
|
127
|
+
Path=/; Expires=Wed, 07 May 2053 19:31:41 GMT; Secure
|
128
|
+
Etag:
|
129
|
+
- W/"1c9-RV2WR8+djapd2GV8p8VntQ5R7zI"
|
130
|
+
Vary:
|
131
|
+
- Accept-Encoding
|
132
|
+
Cf-Cache-Status:
|
133
|
+
- DYNAMIC
|
134
|
+
Expect-Ct:
|
135
|
+
- max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
|
136
|
+
Server:
|
137
|
+
- cloudflare
|
138
|
+
Cf-Ray:
|
139
|
+
- 68679732dfea3acb-CDG
|
140
|
+
body:
|
141
|
+
encoding: UTF-8
|
142
|
+
string: '{"object":"block","id":"32af3324-ba02-4516-ae88-5728a4d569f4","created_time":"2021-05-01T17:13:00.000Z","last_edited_time":"2021-08-29T17:18:00.000Z","has_children":true,"type":"paragraph","paragraph":{"rich_text":[{"type":"text","text":{"content":"A
|
143
|
+
paragraph with childrens","link":null},"annotations":{"bold":false,"italic":false,"strikethrough":false,"underline":false,"code":false,"color":"default"},"plain_text":"A
|
144
|
+
paragraph with childrens","href":null}]}}'
|
145
|
+
recorded_at: Sun, 29 Aug 2021 17:45:01 GMT
|
146
|
+
recorded_with: VCR 6.0.0
|