ask-notion 0.1.0 → 0.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f2b7ca05f8f6271299178580e3660f4b5a014977845d79a21a442ba0dad5d33
4
- data.tar.gz: 1fd261c3a9184fba6e88e372771a35f71aa33954b0dda99cbada5addd1a80d20
3
+ metadata.gz: 10fd8189426e5d6f0b2a48dceab879344e8875d6edd4d8e40a0c2b8926129047
4
+ data.tar.gz: dc4a9867f46503da940d6f1572c6b17a012478165ff373ef13b8c08d36425632
5
5
  SHA512:
6
- metadata.gz: 8d3c5718162b896aed53f44118403c2d470372ce2e305eb7e88315d52885a8c7a1f324c09dfe9d72ad783e8e20957feeab91dfb96d534ba728a5a4cc48534c9a
7
- data.tar.gz: b2ae58df4217e6658378a3d3f6ba3d52b9002950b7c1df664a3bdf177022f02c45582e34462543616de77ae31c412cd46310b72e0c0f6ba60f2026d4250fd26d
6
+ metadata.gz: 045c832fa42bc8b2e9e905210a8a50949458541343f192fd66f674c41d75f3621c1aae255ded8953afe4f06e6faa1b4008cc4ba15e534e8a8f6fe62da623253d
7
+ data.tar.gz: 9fd11d103a3267320d4f731bf180bfda4e0bb5b8cb7c03871634061ad83bc6e867e2685249af60672112a3dbd05ddfd26511fa42ef849a352baf53657ea16266
@@ -5,16 +5,22 @@ require "ask/auth"
5
5
 
6
6
  module Ask
7
7
  module Notion
8
+ # Default number of retries for transient failures.
9
+ DEFAULT_RETRIES = 3
10
+
8
11
  # Returns an authenticated Notion API client configured for an AI agent.
9
12
  #
10
13
  # Resolves the Notion token via +Ask::Auth.resolve(:notion_token)+ and
11
- # wraps the client in a proxy that converts +Notion::Api::Errors::Unauthorized+
12
- # into +Ask::Auth::InvalidCredential+.
14
+ # wraps the client in a proxy that converts authentication, timeout, and
15
+ # network errors into ask-rb equivalents.
13
16
  #
14
17
  # The client inherits default configuration from +Notion::Config+:
15
18
  # - +token+: resolved via Ask::Auth
16
19
  # - +logger+: default logger
17
20
  #
21
+ # Retries transient failures (rate limits, server errors) up to
22
+ # {DEFAULT_RETRIES} times with exponential backoff.
23
+ #
18
24
  # @example
19
25
  # client = Ask::Notion.client
20
26
  # client.database_query(database_id: "abc123")
@@ -28,17 +34,33 @@ module Ask
28
34
  ClientProxy.new(::Notion::Client.new(token: token))
29
35
  end
30
36
 
31
- # Proxies method calls to a +::Notion::Client+, converting authentication
32
- # errors into +Ask::Auth::InvalidCredential+.
37
+ # Proxies method calls to a +::Notion::Client+, converting authentication,
38
+ # timeout, and network errors into ask-rb exceptions with automatic retry
39
+ # for transient failures.
33
40
  class ClientProxy < BasicObject
34
41
  def initialize(client)
35
42
  @client = client
36
43
  end
37
44
 
38
45
  def method_missing(name, ...)
39
- @client.public_send(name, ...)
40
- rescue ::Notion::Api::Errors::Unauthorized
41
- ::Kernel.raise ::Ask::Auth::InvalidCredential, :notion_token
46
+ retries = 0
47
+ begin
48
+ @client.public_send(name, ...)
49
+ rescue ::Notion::Api::Errors::Unauthorized
50
+ ::Kernel.raise ::Ask::Auth::InvalidCredential, :notion_token
51
+ rescue ::Notion::Api::Errors::TooManyRequests,
52
+ ::Notion::Api::Errors::UnavailableError,
53
+ ::Notion::Api::Errors::ServerError,
54
+ ::Timeout::Error,
55
+ ::Errno::ECONNREFUSED,
56
+ ::Errno::ECONNRESET
57
+ retries += 1
58
+ if retries <= ::Ask::Notion::DEFAULT_RETRIES
59
+ ::Kernel.sleep(2 ** retries * 0.1)
60
+ retry
61
+ end
62
+ ::Kernel.raise
63
+ end
42
64
  end
43
65
 
44
66
  def respond_to_missing?(name, include_private = false)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ask
4
4
  module Notion
5
- VERSION = '0.1.0'
5
+ VERSION = '0.1.1'
6
6
  end
7
7
  end
@@ -0,0 +1,131 @@
1
+ ---
2
+ name: notion.use_notion
3
+ description: How to navigate the Notion API with notion-ruby-client — discover endpoints, handle auth, pagination, and errors
4
+ ---
5
+
6
+ Use this skill when you need to interact with Notion — reading/writing pages and
7
+ databases, managing blocks, searching, or updating properties.
8
+
9
+ ## Step 1: Get the Client
10
+
11
+ ```ruby
12
+ client = Ask::Notion.client
13
+ ```
14
+
15
+ This returns an authenticated `Notion::Client`. It expects a valid Notion
16
+ Internal Integration Token resolved via `Ask::Auth.resolve(:notion_token)`.
17
+
18
+ If you get an auth error, read `Ask::Notion::Context::AUTH_HOW` for token setup.
19
+
20
+ ## Step 2: Explore the Context
21
+
22
+ The gem ships with structured context you should reference:
23
+
24
+ ```ruby
25
+ Ask::Notion::Context::DOCS_URL # Notion developer docs
26
+ Ask::Notion::Context::API_REF_URL # Notion API reference
27
+ Ask::Notion::Context::GEM_DOCS # notion-ruby-client docs
28
+ Ask::Notion::Context::QUICK_START # Copy-paste examples
29
+ ```
30
+
31
+ The `QUICK_START` constant has examples for database queries, page CRUD, block
32
+ children, and search.
33
+
34
+ ## Step 3: Discover Available Methods
35
+
36
+ Use code tools to explore the available client methods:
37
+
38
+ ```ruby
39
+ Code.new.call(code: "
40
+ client = Ask::Notion.client
41
+ puts client.methods(false).sort.join(\"\\n\")
42
+ ")
43
+ ```
44
+
45
+ Common Notion API calls:
46
+ - `client.database_query(database_id:, filter:, sorts:)` — query a database
47
+ - `client.database_retrieve(database_id:)` — get database schema
48
+ - `client.page_retrieve(page_id:)` — read a page
49
+ - `client.page_create(parent:, properties:)` — create a page
50
+ - `client.page_update(page_id:, properties:)` — update page properties
51
+ - `client.block_children_list(block_id:)` — list page blocks
52
+ - `client.append_block_children(block_id:, children:)` — add blocks
53
+ - `client.search(query:)` — search across pages and databases
54
+
55
+ For method details, read the client source:
56
+ ```ruby
57
+ Grep.new.call(pattern: "def database_query", path: "$GEM_PATH/notion-ruby-client-*/lib")
58
+ ```
59
+
60
+ ## Step 4: Property Formatting (Most Common Pitfall)
61
+
62
+ Notion properties are complex. Before creating or updating, always check the
63
+ database schema first:
64
+
65
+ ```ruby
66
+ db = client.database_retrieve(database_id: "YOUR_DB_ID")
67
+ db.properties.each do |name, prop|
68
+ puts "#{name}: #{prop.type}"
69
+ end
70
+ ```
71
+
72
+ Property values follow this format pattern:
73
+ ```ruby
74
+ {
75
+ "Name": { title: [{ text: { content: "Page Title" } }] },
76
+ "Status": { status: { name: "Done" } },
77
+ "Date": { date: { start: "2026-01-01" } },
78
+ "Select": { select: { name: "Option" } },
79
+ "Multi-select": { multi_select: [{ name: "Tag1" }] },
80
+ "Number": { number: 42 },
81
+ "Checkbox": { checkbox: true },
82
+ "Email": { email: "user@example.com" },
83
+ "URL": { url: "https://example.com" },
84
+ "Relation": { relation: [{ id: "RELATED_PAGE_ID" }] }
85
+ }
86
+ ```
87
+
88
+ The `notion-ruby-client` gem does minimal conversion — you pass raw hashes.
89
+ For reference, see `Ask::Notion::Context::API_REF_URL`.
90
+
91
+ ## Step 5: Authentication & Common Errors
92
+
93
+ For detailed error guidance, use:
94
+
95
+ ```ruby
96
+ Ask::Notion::Errors.for("Notion::Api::Errors::Forbidden")
97
+ Ask::Notion::Errors.status_code_description(403)
98
+ Ask::Notion::Errors::PAGINATION
99
+ ```
100
+
101
+ Common scenarios:
102
+ - **403 Forbidden**: Integration hasn't been shared with the page/database →
103
+ click "Share" in Notion and add your integration by name
104
+ - **404 Not Found**: Wrong ID or not shared → verify the page ID and sharing
105
+ - **400 Bad Request**: Property values have wrong types → check the schema first
106
+ - **429 Too Many Requests**: Rate limited (3 req/s burst, 90 req/min)
107
+
108
+ ## Step 6: Pagination
109
+
110
+ Notion uses cursor-based pagination. The `notion-ruby-client` gem accepts
111
+ a block to auto-paginate:
112
+
113
+ ```ruby
114
+ client.database_query(database_id: "DB_ID") do |page|
115
+ puts page.results.map { |r| r.id }
116
+ end
117
+ ```
118
+
119
+ Or manual pagination:
120
+ ```ruby
121
+ response = client.database_query(database_id: "DB_ID", start_cursor: cursor, page_size: 100)
122
+ cursor = response.next_cursor
123
+ # Pass cursor as start_cursor in next request
124
+ ```
125
+
126
+ ## Step 7: Fallback Strategy
127
+
128
+ If the client doesn't have a method for what you need:
129
+ 1. Check `Ask::Notion::Context::DOCS_URL` for the API endpoint
130
+ 2. Notion's API is a REST API — you can use Faraday for any endpoint
131
+ 3. Use `client.request(method:, path:, body:)` for custom requests
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-notion
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto
@@ -95,6 +95,7 @@ files:
95
95
  - lib/ask/notion/context.rb
96
96
  - lib/ask/notion/error_guide.rb
97
97
  - lib/ask/notion/version.rb
98
+ - lib/ask/skills/notion.use_notion/SKILL.md
98
99
  homepage: https://github.com/ask-rb/ask-notion
99
100
  licenses:
100
101
  - MIT