notion-ruby-client 0.0.8 → 0.1.0.pre.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +1 -0
- data/.gitignore +7 -0
- data/.rubocop.yml +9 -0
- data/CHANGELOG.md +19 -0
- data/Gemfile.lock +29 -7
- data/README.md +245 -55
- data/bin/console +31 -0
- data/lib/notion/api/endpoints/blocks.rb +35 -7
- data/lib/notion/api/endpoints/databases.rb +65 -37
- data/lib/notion/api/endpoints/pages.rb +6 -6
- data/lib/notion/api/endpoints/search.rb +41 -0
- data/lib/notion/api/endpoints/users.rb +6 -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 +3 -1
- 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 +67 -58
- data/spec/fixtures/notion/create_page.yml +68 -59
- data/spec/fixtures/notion/database.yml +78 -61
- data/spec/fixtures/notion/database_query.yml +81 -62
- data/spec/fixtures/notion/databases_list.yml +77 -60
- data/spec/fixtures/notion/page.yml +70 -57
- 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 +71 -59
- data/spec/fixtures/notion/users.yml +69 -56
- data/spec/fixtures/notion/users_list.yml +143 -130
- data/spec/notion/api/endpoints/blocks_spec.rb +37 -11
- data/spec/notion/api/endpoints/databases_spec.rb +25 -17
- data/spec/notion/api/endpoints/pages_spec.rb +7 -16
- data/spec/notion/api/endpoints/search_spec.rb +26 -0
- data/spec/notion/api/endpoints/users_spec.rb +4 -4
- data/spec/notion/pagination/cursor_spec.rb +126 -0
- metadata +52 -8
- data/.rspec_status +0 -19
- data/notion-ruby-client-0.0.4.gem +0 -0
- data/scratchpad.rb +0 -22
- data/screenshots/create_notion_bot.png +0 -0
data/bin/console
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "dotenv/load"
|
6
|
+
require "notion-ruby-client"
|
7
|
+
|
8
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
9
|
+
# with your gem easier. You can also use a different console, if you like.
|
10
|
+
|
11
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
12
|
+
# require "pry"
|
13
|
+
# Pry.start
|
14
|
+
|
15
|
+
require "irb"
|
16
|
+
|
17
|
+
def reload!(print = true)
|
18
|
+
puts 'Reloading ...' if print
|
19
|
+
# Main project directory.
|
20
|
+
root_dir = File.expand_path('..', __dir__)
|
21
|
+
# Directories within the project that should be reloaded.
|
22
|
+
reload_dirs = %w{lib}
|
23
|
+
# Loop through and reload every file in all relevant project directories.
|
24
|
+
reload_dirs.each do |dir|
|
25
|
+
Dir.glob("#{root_dir}/#{dir}/**/*.rb").each { |f| load(f) }
|
26
|
+
end
|
27
|
+
# Return true when complete.
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
IRB.start(__FILE__)
|
@@ -4,6 +4,34 @@ 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
|
+
|
7
35
|
#
|
8
36
|
# Returns a paginated array of Block objects contained in the
|
9
37
|
# block of the requested path using the ID specified.
|
@@ -14,16 +42,16 @@ module Notion
|
|
14
42
|
#
|
15
43
|
# Returns a 400 or 429 HTTP response if the request exceeds Notion's Request limits.
|
16
44
|
#
|
17
|
-
# @option options [id] :
|
45
|
+
# @option options [id] :block_id
|
18
46
|
# Block to get children info on.
|
19
47
|
def block_children(options = {})
|
20
|
-
throw ArgumentError.new('Required arguments :
|
48
|
+
throw ArgumentError.new('Required arguments :block_id missing') if options[:block_id].nil?
|
21
49
|
if block_given?
|
22
50
|
Pagination::Cursor.new(self, :block_children, options).each do |page|
|
23
51
|
yield page
|
24
52
|
end
|
25
53
|
else
|
26
|
-
get("blocks/#{options[:
|
54
|
+
get("blocks/#{options[:block_id]}/children", options.except(:block_id))
|
27
55
|
end
|
28
56
|
end
|
29
57
|
|
@@ -38,14 +66,14 @@ module Notion
|
|
38
66
|
#
|
39
67
|
# Returns a 400 or 429 HTTP response if the request exceeds Notion's Request limits.
|
40
68
|
#
|
41
|
-
# @option options [id] :
|
42
|
-
# Block to
|
69
|
+
# @option options [id] :block_id
|
70
|
+
# Block to append children to.
|
43
71
|
#
|
44
72
|
# @option options [[Object]] :children
|
45
73
|
# Children blocks to append
|
46
74
|
def block_append_children(options = {})
|
47
|
-
throw ArgumentError.new('Required arguments :
|
48
|
-
patch("blocks/#{options[:
|
75
|
+
throw ArgumentError.new('Required arguments :block_id missing') if options[:block_id].nil?
|
76
|
+
patch("blocks/#{options[:block_id]}/children", options.except(:block_id))
|
49
77
|
end
|
50
78
|
end
|
51
79
|
end
|
@@ -5,17 +5,43 @@ module Notion
|
|
5
5
|
module Endpoints
|
6
6
|
module Databases
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# Gets a paginated array of Page object s contained in the requested database,
|
9
|
+
# filtered and ordered according to the filter and sort objects provided in the request.
|
9
10
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
11
|
+
# Filters are similar to the filters provided in the Notion UI. Filters operate
|
12
|
+
# on database properties and can be combined. If no filter is provided, all the
|
13
|
+
# pages in the database will be returned with pagination.
|
13
14
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
# Sorts are similar to the sorts provided in the Notion UI. Sorts operate on
|
16
|
+
# database properties and can be combined. The order of the sorts in the request
|
17
|
+
# matter, with earlier sorts taking precedence over later ones.
|
18
|
+
#
|
19
|
+
# @option options [id] :database_id
|
20
|
+
# Database to query.
|
21
|
+
#
|
22
|
+
# @option options [Object] :filter
|
23
|
+
# When supplied, limits which pages are returned based on the provided criteria.
|
24
|
+
#
|
25
|
+
# @option options [[Object]] :sorts
|
26
|
+
# When supplied, sorts the results based on the provided criteria.
|
27
|
+
#
|
28
|
+
# @option options [UUID] :start_cursor
|
29
|
+
# Paginate through collections of data by setting the cursor parameter
|
30
|
+
# to a start_cursor attribute returned by a previous request's next_cursor.
|
31
|
+
# Default value fetches the first "page" of the collection.
|
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
|
36
|
+
def database_query(options = {})
|
37
|
+
throw ArgumentError.new('Required arguments :database_id missing') if options[:database_id].nil?
|
38
|
+
if block_given?
|
39
|
+
Pagination::Cursor.new(self, :database_query, options).each do |page|
|
40
|
+
yield page
|
41
|
+
end
|
42
|
+
else
|
43
|
+
post("databases/#{options[:database_id]}/query", options.except(:database_id))
|
44
|
+
end
|
19
45
|
end
|
20
46
|
|
21
47
|
#
|
@@ -41,40 +67,39 @@ module Notion
|
|
41
67
|
end
|
42
68
|
|
43
69
|
#
|
44
|
-
#
|
45
|
-
# filtered and ordered according to the filter and sort objects provided in the request.
|
70
|
+
# Updates an existing database as specified by the parameters.
|
46
71
|
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
# pages in the database will be returned with pagination.
|
72
|
+
# @option options [id] :database_id
|
73
|
+
# Database to update.
|
50
74
|
#
|
51
|
-
#
|
52
|
-
# database
|
53
|
-
#
|
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.
|
54
78
|
#
|
55
|
-
# @option options [
|
56
|
-
#
|
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
|
+
|
57
91
|
#
|
58
|
-
#
|
59
|
-
# When supplied, limits which pages are returned based on the provided criteria.
|
92
|
+
# Retrieves a Database object using the ID specified in the request.
|
60
93
|
#
|
61
|
-
#
|
62
|
-
#
|
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.
|
63
97
|
#
|
64
|
-
# @option options [
|
65
|
-
#
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
def database_query(options = {})
|
70
|
-
throw ArgumentError.new('Required arguments :id missing') if options[:id].nil?
|
71
|
-
if block_given?
|
72
|
-
Pagination::Cursor.new(self, :database_query, options).each do |page|
|
73
|
-
yield page
|
74
|
-
end
|
75
|
-
else
|
76
|
-
post("databases/#{options[:id]}/query", options)
|
77
|
-
end
|
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]}")
|
78
103
|
end
|
79
104
|
|
80
105
|
#
|
@@ -85,6 +110,9 @@ module Notion
|
|
85
110
|
# to a start_cursor attribute returned by a previous request's next_cursor.
|
86
111
|
# Default value fetches the first "page" of the collection.
|
87
112
|
# See pagination for more detail.
|
113
|
+
#
|
114
|
+
# @option options [integer] :page_size
|
115
|
+
# The number of items from the full list desired in the response. Maximum: 100
|
88
116
|
def databases_list(options = {})
|
89
117
|
if block_given?
|
90
118
|
Pagination::Cursor.new(self, :databases_list, options).each do |page|
|
@@ -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 arguments :
|
19
|
-
get("pages/#{options[:
|
18
|
+
throw ArgumentError.new('Required arguments :page_id missing') if options[:page_id].nil?
|
19
|
+
get("pages/#{options[:page_id]}")
|
20
20
|
end
|
21
21
|
|
22
22
|
#
|
@@ -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,8 @@ 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 arguments :
|
64
|
-
patch("pages/#{options[:
|
63
|
+
throw ArgumentError.new('Required arguments :page_id missing') if options[:page_id].nil?
|
64
|
+
patch("pages/#{options[:page_id]}", options.except(:page_id))
|
65
65
|
end
|
66
66
|
end
|
67
67
|
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
|
@@ -7,11 +7,11 @@ module Notion
|
|
7
7
|
#
|
8
8
|
# Retrieves a User object using the ID specified in the request.
|
9
9
|
#
|
10
|
-
# @option options [id] :
|
10
|
+
# @option options [id] :user_id
|
11
11
|
# User to get info on.
|
12
12
|
def user(options = {})
|
13
|
-
throw ArgumentError.new('Required arguments :
|
14
|
-
get("users/#{options[:
|
13
|
+
throw ArgumentError.new('Required arguments :user_id missing') if options[:user_id].nil?
|
14
|
+
get("users/#{options[:user_id]}")
|
15
15
|
end
|
16
16
|
|
17
17
|
#
|
@@ -22,6 +22,9 @@ module Notion
|
|
22
22
|
# to a start_cursor attribute returned by a previous request's next_cursor.
|
23
23
|
# Default value fetches the first "page" of the collection.
|
24
24
|
# See pagination for more detail.
|
25
|
+
#
|
26
|
+
# @option options [integer] :page_size
|
27
|
+
# The number of items from the full list desired in the response. Maximum: 100
|
25
28
|
def users_list(options = {})
|
26
29
|
if block_given?
|
27
30
|
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