notionrb 1.3.0

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.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/.devcontainer/Dockerfile +5 -0
  3. data/.devcontainer/boot.sh +1 -0
  4. data/.devcontainer/devcontainer.json +30 -0
  5. data/.github/workflows/ci.yml +15 -0
  6. data/.github/workflows/rubocop.yml +17 -0
  7. data/.gitignore +7 -0
  8. data/.rspec +2 -0
  9. data/.rubocop.yml +55 -0
  10. data/.rubocop_todo.yml +86 -0
  11. data/CHANGELOG.md +144 -0
  12. data/CODE_OF_CONDUCT.md +128 -0
  13. data/CONTRIBUTING.md +51 -0
  14. data/Gemfile +4 -0
  15. data/Gemfile.lock +95 -0
  16. data/LICENSE.md +21 -0
  17. data/README.md +677 -0
  18. data/Rakefile +18 -0
  19. data/bin/console +31 -0
  20. data/lib/notion/api/endpoints/blocks.rb +100 -0
  21. data/lib/notion/api/endpoints/comments.rb +61 -0
  22. data/lib/notion/api/endpoints/data_sources.rb +102 -0
  23. data/lib/notion/api/endpoints/databases.rb +134 -0
  24. data/lib/notion/api/endpoints/pages.rb +95 -0
  25. data/lib/notion/api/endpoints/search.rb +41 -0
  26. data/lib/notion/api/endpoints/users.rb +48 -0
  27. data/lib/notion/api/endpoints.rb +23 -0
  28. data/lib/notion/api/error.rb +6 -0
  29. data/lib/notion/api/errors/internal_error.rb +12 -0
  30. data/lib/notion/api/errors/notion_error.rb +15 -0
  31. data/lib/notion/api/errors/too_many_requests.rb +15 -0
  32. data/lib/notion/api/errors.rb +23 -0
  33. data/lib/notion/client.rb +28 -0
  34. data/lib/notion/config.rb +54 -0
  35. data/lib/notion/faraday/connection.rb +37 -0
  36. data/lib/notion/faraday/request.rb +45 -0
  37. data/lib/notion/faraday/response/raise_error.rb +31 -0
  38. data/lib/notion/faraday/response/wrap_error.rb +22 -0
  39. data/lib/notion/logger.rb +14 -0
  40. data/lib/notion/messages/message.rb +17 -0
  41. data/lib/notion/pagination/cursor.rb +53 -0
  42. data/lib/notion/version.rb +5 -0
  43. data/lib/notion-ruby-client.rb +28 -0
  44. data/lib/notion.rb +2 -0
  45. data/lib/notion_ruby_client.rb +2 -0
  46. data/notionrb.gemspec +31 -0
  47. data/spec/fixtures/notion/block.yml +146 -0
  48. data/spec/fixtures/notion/block_append_children.yml +149 -0
  49. data/spec/fixtures/notion/block_children.yml +152 -0
  50. data/spec/fixtures/notion/create_data_source.yml +29 -0
  51. data/spec/fixtures/notion/create_database.yml +149 -0
  52. data/spec/fixtures/notion/create_discussion_comment.yml +110 -0
  53. data/spec/fixtures/notion/create_page.yml +152 -0
  54. data/spec/fixtures/notion/create_page_comment.yml +110 -0
  55. data/spec/fixtures/notion/create_page_with_data_source.yml +29 -0
  56. data/spec/fixtures/notion/create_page_with_parent_page.yml +128 -0
  57. data/spec/fixtures/notion/data_source.yml +27 -0
  58. data/spec/fixtures/notion/data_source_query.yml +29 -0
  59. data/spec/fixtures/notion/database.yml +150 -0
  60. data/spec/fixtures/notion/database_query.yml +154 -0
  61. data/spec/fixtures/notion/delete_block.yml +145 -0
  62. data/spec/fixtures/notion/page.yml +150 -0
  63. data/spec/fixtures/notion/page_property_item.yml +143 -0
  64. data/spec/fixtures/notion/paginated_block_children.yml +575 -0
  65. data/spec/fixtures/notion/paginated_data_source_query.yml +29 -0
  66. data/spec/fixtures/notion/paginated_database_query.yml +152 -0
  67. data/spec/fixtures/notion/paginated_databases_list.yml +150 -0
  68. data/spec/fixtures/notion/paginated_search.yml +301 -0
  69. data/spec/fixtures/notion/paginated_users_list.yml +146 -0
  70. data/spec/fixtures/notion/retrieve_comments.yml +106 -0
  71. data/spec/fixtures/notion/search.yml +160 -0
  72. data/spec/fixtures/notion/search_with_query.yml +152 -0
  73. data/spec/fixtures/notion/update_block.yml +148 -0
  74. data/spec/fixtures/notion/update_data_source.yml +29 -0
  75. data/spec/fixtures/notion/update_database.yml +152 -0
  76. data/spec/fixtures/notion/update_page.yml +152 -0
  77. data/spec/fixtures/notion/users.yml +145 -0
  78. data/spec/fixtures/notion/users_list.yml +146 -0
  79. data/spec/fixtures/notion/users_me.yml +144 -0
  80. data/spec/notion/api/endpoints/blocks_spec.rb +72 -0
  81. data/spec/notion/api/endpoints/comments_spec.rb +49 -0
  82. data/spec/notion/api/endpoints/data_sources_spec.rb +61 -0
  83. data/spec/notion/api/endpoints/databases_spec.rb +70 -0
  84. data/spec/notion/api/endpoints/pages_spec.rb +127 -0
  85. data/spec/notion/api/endpoints/search_spec.rb +26 -0
  86. data/spec/notion/api/endpoints/users_spec.rb +31 -0
  87. data/spec/notion/config_spec.rb +16 -0
  88. data/spec/notion/pagination/cursor_spec.rb +126 -0
  89. data/spec/notion/version_spec.rb +8 -0
  90. data/spec/spec_helper.rb +22 -0
  91. data/spec/support/token.rb +10 -0
  92. data/spec/support/vcr.rb +16 -0
  93. metadata +358 -0
@@ -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
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Notion
4
+ module Api
5
+ module Errors
6
+ class BadRequest < NotionError; end
7
+ class Forbidden < NotionError; end
8
+ class InternalError < NotionError; end
9
+ class InvalidRequest < NotionError; end
10
+ class ObjectNotFound < NotionError; end
11
+ class Unauthorized < NotionError; end
12
+
13
+ ERROR_CLASSES = {
14
+ 'bad_request' => BadRequest,
15
+ 'forbidden' => Forbidden,
16
+ 'internal_error' => InternalError,
17
+ 'invalid_request' => InvalidRequest,
18
+ 'object_not_found' => ObjectNotFound,
19
+ 'unauthorized' => Unauthorized
20
+ }.freeze
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ module Notion
3
+ class Client
4
+ include Faraday::Connection
5
+ include Faraday::Request
6
+ include Api::Endpoints
7
+
8
+ attr_accessor(*Config::ATTRIBUTES)
9
+
10
+ def initialize(options = {})
11
+ Notion::Config::ATTRIBUTES.each do |key|
12
+ send("#{key}=", options.fetch(key, Notion.config.send(key)))
13
+ end
14
+ @logger ||= Notion::Config.logger || Notion::Logger.default
15
+ @token ||= Notion.config.token
16
+ end
17
+
18
+ class << self
19
+ def configure
20
+ block_given? ? yield(Config) : Config
21
+ end
22
+
23
+ def config
24
+ Config
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+ module Notion
3
+ module Config
4
+ extend self
5
+
6
+ ATTRIBUTES = %i[
7
+ proxy
8
+ user_agent
9
+ ca_path
10
+ ca_file
11
+ logger
12
+ endpoint
13
+ token
14
+ timeout
15
+ open_timeout
16
+ default_page_size
17
+ default_max_retries
18
+ default_retry_after
19
+ adapter
20
+ ].freeze
21
+
22
+ attr_accessor(*Config::ATTRIBUTES)
23
+
24
+ def reset
25
+ self.endpoint = 'https://api.notion.com/v1'
26
+ self.user_agent = "Notion Ruby Client/#{Notion::VERSION}"
27
+ self.ca_path = nil
28
+ self.ca_file = nil
29
+ self.token = nil
30
+ self.proxy = nil
31
+ self.logger = nil
32
+ self.timeout = nil
33
+ self.open_timeout = nil
34
+ self.default_page_size = 100
35
+ self.default_max_retries = 100
36
+ self.default_retry_after = 10
37
+ self.adapter = ::Faraday.default_adapter
38
+ end
39
+
40
+ reset
41
+ end
42
+
43
+ class << self
44
+ def configure
45
+ block_given? ? yield(Config) : Config
46
+ end
47
+
48
+ def config
49
+ Config
50
+ end
51
+ end
52
+ end
53
+
54
+ Notion::Config.reset
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+ module Notion
3
+ module Faraday
4
+ module Connection
5
+ private
6
+
7
+ def connection
8
+ @connection ||=
9
+ begin
10
+ options = {
11
+ headers: { 'Accept' => 'application/json; charset=utf-8' }
12
+ }
13
+
14
+ options[:headers]['User-Agent'] = user_agent if user_agent
15
+ options[:proxy] = proxy if proxy
16
+ options[:ssl] = { ca_path: ca_path, ca_file: ca_file } if ca_path || ca_file
17
+
18
+ request_options = {}
19
+ request_options[:timeout] = timeout if timeout
20
+ request_options[:open_timeout] = open_timeout if open_timeout
21
+ options[:request] = request_options if request_options.any?
22
+
23
+ ::Faraday::Connection.new(endpoint, options) do |connection|
24
+ connection.use ::Faraday::Multipart::Middleware
25
+ connection.use ::Faraday::Request::UrlEncoded
26
+ connection.use ::Notion::Faraday::Response::RaiseError
27
+ connection.use ::Faraday::Mashify::Middleware, mash_class: Notion::Messages::Message
28
+ connection.use ::Faraday::Response::Json
29
+ connection.use ::Notion::Faraday::Response::WrapError
30
+ connection.response :logger, logger if logger
31
+ connection.adapter adapter
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+ module Notion
3
+ module Faraday
4
+ module Request
5
+ def get(path, options = {})
6
+ request(:get, path, options)
7
+ end
8
+
9
+ def patch(path, options = {})
10
+ request(:patch, path, options)
11
+ end
12
+
13
+ def post(path, options = {})
14
+ request(:post, path, options)
15
+ end
16
+
17
+ def put(path, options = {})
18
+ request(:put, path, options)
19
+ end
20
+
21
+ def delete(path, options = {})
22
+ request(:delete, path, options)
23
+ end
24
+
25
+ private
26
+
27
+ def request(method, path, options)
28
+ response = connection.send(method) do |request|
29
+ request.headers['Authorization'] = "Bearer #{token}"
30
+ request.headers['Notion-Version'] = Notion::NOTION_REQUEST_VERSION
31
+ case method
32
+ when :get, :delete
33
+ request.url(path, options)
34
+ when :post, :put, :patch
35
+ request.headers['Content-Type'] = 'application/json'
36
+ request.path = path
37
+ request.body = options.to_json unless options.empty?
38
+ end
39
+ request.options.merge!(options.delete(:request)) if options.key?(:request)
40
+ end
41
+ response.body
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ module Notion
3
+ module Faraday
4
+ module Response
5
+ class RaiseError < ::Faraday::Response::Json
6
+ def on_complete(env)
7
+ raise Notion::Api::Errors::TooManyRequests, env.response if env.status == 429
8
+
9
+ return if env.success?
10
+
11
+ body = env.body
12
+ return unless body
13
+
14
+ error_code = body['code']
15
+ error_message = body['message']
16
+ error_details = body['details']
17
+
18
+ error_class = Notion::Api::Errors::ERROR_CLASSES[error_code]
19
+ error_class ||= Notion::Api::Errors::NotionError
20
+ raise error_class.new(error_message, error_details, env.response)
21
+ end
22
+
23
+ def call(env)
24
+ super
25
+ rescue ::Faraday::ParsingError
26
+ raise Notion::Api::Errors::ParsingError.new('parsing_error', env.response)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ module Notion
3
+ module Faraday
4
+ module Response
5
+ class WrapError < ::Faraday::Response::Json
6
+ UNAVAILABLE_ERROR_STATUSES = (500..599).freeze
7
+
8
+ def on_complete(env)
9
+ return unless UNAVAILABLE_ERROR_STATUSES.cover?(env.status)
10
+
11
+ raise Notion::Api::Errors::UnavailableError.new('unavailable_error', env.response)
12
+ end
13
+
14
+ def call(env)
15
+ super
16
+ rescue ::Faraday::TimeoutError, ::Faraday::ConnectionFailed
17
+ raise Notion::Api::Errors::TimeoutError.new('timeout_error', env.response)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ require 'logger'
3
+
4
+ module Notion
5
+ class Logger < ::Logger
6
+ def self.default
7
+ return @default if @default
8
+
9
+ logger = new STDOUT
10
+ logger.level = Logger::WARN
11
+ @default = logger
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ module Notion
3
+ module Messages
4
+ class Message < Hashie::Mash
5
+ def to_s
6
+ keys.sort_by(&:to_s).map do |key|
7
+ "#{key}=#{self[key]}"
8
+ end.join(', ')
9
+ end
10
+
11
+ private
12
+
13
+ # see https://github.com/intridea/hashie/issues/394
14
+ def log_built_in_message(*); end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+ module Notion
3
+ module Api
4
+ module Pagination
5
+ class Cursor
6
+ include Enumerable
7
+
8
+ attr_reader :client
9
+ attr_reader :verb
10
+ attr_reader :sleep_interval
11
+ attr_reader :max_retries
12
+ attr_reader :retry_after
13
+ attr_reader :params
14
+
15
+ def initialize(client, verb, params = {})
16
+ @client = client
17
+ @verb = verb
18
+ @params = params.dup
19
+ @sleep_interval = @params.delete(:sleep_interval)
20
+ @max_retries = @params.delete(:max_retries) || client.default_max_retries
21
+ @retry_after = @params.delete(:retry_after) || client.default_retry_after
22
+ end
23
+
24
+ def each
25
+ next_cursor = nil
26
+ retry_count = 0
27
+ loop do
28
+ query = { page_size: client.default_page_size }.merge(params)
29
+ query = query.merge(start_cursor: next_cursor) unless next_cursor.nil?
30
+ begin
31
+ response = client.send(verb, query)
32
+ rescue Notion::Api::Errors::TooManyRequests => e
33
+ raise e if retry_count >= max_retries
34
+
35
+ client.logger.debug("#{self.class}##{__method__}") { e.to_s }
36
+ retry_count += 1
37
+ sleep(retry_after)
38
+ next
39
+ end
40
+ yield response
41
+ break unless response.has_more
42
+
43
+ next_cursor = response.next_cursor
44
+ break if next_cursor.nil? || next_cursor == ''
45
+
46
+ retry_count = 0
47
+ sleep(sleep_interval) if sleep_interval
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+ module Notion
3
+ VERSION = '1.3.0'
4
+ NOTION_REQUEST_VERSION = '2025-09-03'
5
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ require 'faraday'
3
+ require 'faraday/mashify'
4
+ require 'faraday/multipart'
5
+ require 'json'
6
+ require 'logger'
7
+ require 'hashie'
8
+
9
+ require_relative 'notion/version'
10
+ require_relative 'notion/logger'
11
+ require_relative 'notion/config'
12
+
13
+ # Messages
14
+ require_relative 'notion/messages/message'
15
+
16
+ require_relative 'notion/config'
17
+ require_relative 'notion/api/errors/notion_error'
18
+ require_relative 'notion/api/error'
19
+ require_relative 'notion/api/errors'
20
+ require_relative 'notion/api/errors/internal_error'
21
+ require_relative 'notion/api/errors/too_many_requests'
22
+ require_relative 'notion/faraday/response/raise_error'
23
+ require_relative 'notion/faraday/response/wrap_error'
24
+ require_relative 'notion/faraday/connection'
25
+ require_relative 'notion/faraday/request'
26
+ require_relative 'notion/api/endpoints'
27
+ require_relative 'notion/pagination/cursor'
28
+ require_relative 'notion/client'
data/lib/notion.rb ADDED
@@ -0,0 +1,2 @@
1
+ # frozen_string_literal: true
2
+ require 'notion-ruby-client'
@@ -0,0 +1,2 @@
1
+ # frozen_string_literal: true
2
+ require 'notion-ruby-client'
data/notionrb.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
3
+ require 'notion/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'notionrb'
7
+ s.version = Notion::VERSION
8
+ s.authors = ['Nicolas Goutay', 'Ivan Lyubchenko']
9
+ s.email = 'lubchenko2044@gmail.com'
10
+ s.platform = Gem::Platform::RUBY
11
+ s.required_rubygems_version = '>= 1.3.6'
12
+ s.files = `git ls-files`.split("\n")
13
+ s.test_files = `git ls-files -- spec/*`.split("\n")
14
+ s.require_paths = ['lib']
15
+ s.homepage = 'https://github.com/lyubchenko-ivan/notion-ruby-client'
16
+ s.licenses = ['MIT']
17
+ s.summary = 'Notion API client for Ruby.'
18
+ s.add_dependency 'faraday', '>= 2.0'
19
+ s.add_dependency 'faraday-mashify', '>= 0.1.1'
20
+ s.add_dependency 'faraday-multipart', '>= 1.0.4'
21
+ s.add_dependency 'hashie', '~> 5'
22
+ s.add_development_dependency 'dotenv'
23
+ s.add_development_dependency 'rake', '~> 13'
24
+ s.add_development_dependency 'rspec'
25
+ s.add_development_dependency 'rubocop', '~> 0.82.0'
26
+ s.add_development_dependency 'rubocop-performance', '~> 1.5.2'
27
+ s.add_development_dependency 'rubocop-rspec', '~> 1.39.0'
28
+ s.add_development_dependency 'timecop'
29
+ s.add_development_dependency 'vcr'
30
+ s.add_development_dependency 'webmock'
31
+ end
@@ -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