### Setup: Create a Test Page for Rich Text Examples Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/notebooks/05-rich-text-dsl.ipynb Creates a new Notion page using the initialized Notion client to serve as a testbed for rich text formatting examples. This function requires the `parentPageId` obtained from environment variables and returns the newly created page's ID and URL. ```kotlin val testPage = runBlocking { notion.pages.create { parent.page(parentPageId) title("Rich Text DSL Examples") icon.emoji("✨") } } val testPageId = testPage.id println("✅ Test page created successfully!") println(" Page ID: $testPageId") println(" URL: ${testPage.url}") // Wait for page to be fully created runBlocking { delay(1000) } ``` -------------------------------- ### Initialize Kotlin Notion Client and Get Current User Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/QUICKSTART.md Demonstrates how to initialize the NotionClient with an API token and verify the connection by fetching the current user's details. This is a basic setup for subsequent API interactions. ```kotlin import it.saabel.kotlinnotionclient.NotionClient import kotlinx.coroutines.runBlocking fun main() = runBlocking { // Initialize the client val notion = NotionClient("your-api-token") // Get current user (verifies token works) val user = notion.users.getCurrentUser() println("Connected as: ${user.name}") // Don't forget to close when done notion.close() } ``` -------------------------------- ### Install Kotlin Notion Client Dependency Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/QUICKSTART.md Add the Kotlin Notion Client library to your project's build.gradle.kts file. This makes the client's functionality available for use in your Kotlin code. ```kotlin dependencies { implementation("it.saabel:kotlin-notion-client:0.2.0") } ``` -------------------------------- ### Quick Start: Initializing Notion Client and Basic Operations Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/README.md A concise example demonstrating how to initialize the NotionClient, retrieve an existing page, create a new page with properties, and query a data source using the client's DSL. ```kotlin import it.saabel.kotlinnotionclient.NotionClient // Initialize the client (constructor - recommended) val notion = NotionClient("your-notion-api-token") // Alternative: factory method (also supported) // val notion = NotionClient.create("your-notion-api-token") // Retrieve a page val page = notion.pages.retrieve("page-id") // Create a page in a data source val newPage = notion.pages.create { parent { dataSourceId("data-source-id") } properties { title("Name") { text("My Project") } select("Status") { name("In Progress") } } } // Query a data source (table) val results = notion.dataSources.query("data-source-id") { filter { property("Status") { select { equals("In Progress") } } } } ``` -------------------------------- ### Initialize Kotlin Notion Client with Custom Configuration Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/QUICKSTART.md Shows different ways to initialize the NotionClient, including using a direct constructor, a factory method, and with custom configurations like setting the log level. ```kotlin // 1. Direct constructor (recommended - idiomatic Kotlin) val notion = NotionClient("your-api-token") // 2. Factory method (also supported) val notion = NotionClient.create("your-api-token") // With custom configuration import it.saabel.kotlinnotionclient.NotionConfig import it.saabel.kotlinnotionclient.LogLevel val notion = NotionClient( NotionConfig( apiToken = "your-api-token", logLevel = LogLevel.INFO ) ) ``` -------------------------------- ### Running Example Validations (Bash) Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/journal/2025_10_05_03_Documentation_Strategy.md Commands to execute the validation tests for documentation examples using Gradle. These commands allow for running all example validations or targeting specific validation files based on their class names. ```bash # Run all example validations export NOTION_RUN_INTEGRATION_TESTS=true ./gradlew test --tests "*Examples" # Run specific doc validation ./gradlew test --tests "*DataSourcesExamples" ``` -------------------------------- ### Kotlin Notion Client Cleanup Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/QUICKSTART.md Demonstrates how to properly close the Notion client to release resources. It shows both manual closing and the use of the `.use` extension function for automatic cleanup. ```kotlin notion.close() ``` ```kotlin NotionClient("token").use { // Your code here } ``` -------------------------------- ### Handle Notion API Errors with Kotlin Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/notebooks/01-getting-started.ipynb Demonstrates how to catch and handle specific Notion API errors, such as 'Page not found' (404) and authentication failures, using try-catch blocks. It also includes handling generic Notion exceptions. This example requires the Kotlin Notion client library. ```kotlin import it.saabel.kotlinnotionclient.exceptions.NotionException // Try to retrieve a non-existent page val fakePageId = "00000000-0000-0000-0000-000000000000" try { runBlocking { notion.pages.retrieve(fakePageId) } println("This shouldn't happen!") } catch (e: NotionException.ApiError) { if (e.status == 404) { println("✅ Caught expected error: Page not found") println(" Message: ${e.message}") println(" Status: ${e.status}") println(" Code: ${e.code}") } else { println("❌ Unexpected API Error: ${e.message}") throw e } } catch (e: NotionException.AuthenticationError) { println("❌ Authentication failed: ${e.message}") println(" Check your NOTION_API_TOKEN is valid") throw e } catch (e: NotionException) { println("❌ Unexpected error: ${e.message}") throw e } ``` -------------------------------- ### Build Notion Pages Using DSL Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/docs/notebooks.md Demonstrates how to create Notion pages programmatically using the Kotlin Notion Client's Domain Specific Language (DSL). This example shows setting the parent database, defining properties like title and rich text, and applying formatting such as bold text and colors. It utilizes `runBlocking` to execute the asynchronous creation operation. ```kotlin val page = runBlocking { notion.pages.create { parent { databaseId(dbId) } properties { title("Name") { text("Demo Page") } richText("Description") { text("This is ") { bold = true } text("awesome!", TextColor.BLUE) } } } } ``` -------------------------------- ### Initialize Kotlin Notion Client with Authentication Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/notebooks/01-getting-started.ipynb Sets up the Kotlin Notion Client by loading the library from Maven Central and initializing it with a Notion API token. It requires the NOTION_API_TOKEN environment variable to be set. ```kotlin // Load the Kotlin Notion Client library from Maven Central @file:DependsOn("it.saabel:kotlin-notion-client:0.2.0") // Import necessary classes import it.saabel.kotlinnotionclient.NotionClient import it.saabel.kotlinnotionclient.exceptions.NotionException import kotlinx.coroutines.runBlocking // Initialize the client with your API token val apiToken = System.getenv("NOTION_API_TOKEN") ?: error("❌ NOTION_API_TOKEN environment variable not set") val notion = NotionClient(apiToken) println("✅ NotionClient initialized successfully!") println(" Token: ${apiToken.take(10)}...") ``` -------------------------------- ### Example: Notion Database URL Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/reference/notion-api/documentation/objects/03_Database_General.md Provides an example of the 'url' property for a Notion database. This is a string representing the direct web address of the database in Notion. ```string "https://www.notion.so/668d797c76fa49349b05ad288df2d136" ``` -------------------------------- ### Initialize Kotlin Notion Client and Setup Environment Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/docs/notebooks.md This snippet shows how to set up the environment for using the Kotlin Notion Client within a Jupyter notebook. It includes loading the library as a dependency using `@file:DependsOn` and initializing the `NotionClient` with an API token retrieved from environment variables. An error is thrown if the token is not found, ensuring proper configuration. ```kotlin // Load dependencies @file:DependsOn("it.saabel:kotlin-notion-client:0.2.0") // Imports import it.saabel.kotlinnotionclient.NotionClient import kotlinx.coroutines.runBlocking // Initialize client val apiToken = System.getenv("NOTION_API_TOKEN") ?: error("NOTION_API_TOKEN environment variable not set") val notion = NotionClient(apiToken) ``` -------------------------------- ### Create a New Page in a Data Source Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/QUICKSTART.md Creates a new page within a specified data source (table). It allows setting properties such as title, select options, and dates for the new page. ```kotlin val newPage = notion.pages.create { // Parent is the data source (table), not the database parent { dataSourceId("data-source-id") } properties { title("Name") { text("My New Task") } select("Status") { name("In Progress") } date("Due Date") { start("2025-10-15") } } } println("Created page: ${newPage.url}") ``` -------------------------------- ### Run Specific Integration Tests with Gradle (Bash) Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/docs/testing.md This bash command demonstrates how to run specific integration tests using Gradle after setting the required environment variables. It allows targeting tests, for example, by specifying a test class name like '*PagesIntegrationTest'. ```bash # Set up once per session export NOTION_RUN_INTEGRATION_TESTS=true export NOTION_API_TOKEN="secret_your_token" export NOTION_TEST_PAGE_ID="your-page-id" # Run one integration test ./gradlew test --tests "*PagesIntegrationTest" ``` -------------------------------- ### Example 1: Basic Text Formatting in Kotlin Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/notebooks/05-rich-text-dsl.ipynb Demonstrates basic text formatting including bold, italic, bold-italic, code, strikethrough, and underline using the Kotlin Notion Client's DSL. This function appends formatted paragraphs to a specified test page. ```kotlin runBlocking { notion.blocks.appendChildren(testPageId) { heading1("Example 1: Basic Text Formatting") paragraph { text("This text is ") bold("bold") text(", this is ") italic("italic") text(", and this is ") boldItalic("both") text(".") } paragraph { text("You can also use ") code("inline code") text(" for technical terms or ") strikethrough("strikethrough") text(" and ") underline("underline") text(".") } } delay(1000) } println("✅ Basic text formatting examples created!") ``` -------------------------------- ### Demonstrating Type-Safe Page Icon Handling in Notebook Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/journal/2025_10_16_03_Type_Safe_Icons_And_Covers.md Example from the 'Getting Started' notebook showcasing how to interact with the new type-safe PageIcon sealed class hierarchy using a `when` expression. This ensures all icon types are handled exhaustively and safely. ```kotlin println("🎨 Page Icon:") when (val icon = page.icon) { is PageIcon.Emoji -> println(" Emoji: ${icon.emoji}") is PageIcon.CustomEmoji -> println(" Custom emoji: ${icon.customEmoji.name}") is PageIcon.External -> println(" External URL: ${icon.external.url}") is PageIcon.File -> println(" File URL: ${icon.file.url}") is PageIcon.FileUpload -> println(" Upload ID: ${icon.fileUpload.id}") null -> println(" No icon set") } ``` -------------------------------- ### Retrieve Current User Information with Kotlin Notion Client Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/notebooks/01-getting-started.ipynb Fetches and displays information about the authenticated Notion integration user. This verifies the client's authentication setup and provides user details like ID, name, type, and avatar URL. ```kotlin val user = runBlocking { notion.users.getCurrentUser() } println("✅ User information retrieved:") println(" ID: ${user.id}") println(" Name: ${user.name}") println(" Type: ${user.type}") println(" Avatar: ${user.avatarUrl ?: "No avatar"}") ``` -------------------------------- ### Setup: Create Test Database with Sample Data using Kotlin Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/notebooks/06-advanced-queries.ipynb Creates a test database with various property types (title, select, checkbox, number) and populates it with initial data. It retrieves the database ID, URL, and data source ID for subsequent query operations. ```kotlin // Create a test database with multiple property types val database = runBlocking { notion.databases.create { parent.page(parentPageId) title("Advanced Query Examples - Task Tracker") properties { title("Name") select("Status") select("Priority") checkbox("Completed") number("Score") select("Category") } } } println("✅ Database created: ${database.id}") // Wait for database to be ready runBlocking { delay(1000) } // Get the data source ID (for 2025-09-03 API) val retrievedDb = runBlocking { notion.databases.retrieve(database.id) } val databaseUrl = retrievedDb.url val dataSourceId = retrievedDb.dataSources.first().id println("✅ Data source ID: $dataSourceId") println("✅ URL for database: $databaseUrl") ``` -------------------------------- ### Running Specific Example Tests Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/journal/2025_10_09_Users_API_Implementation.md This command runs Gradle tests specifically for the 'examples.UsersExamples' class, useful for isolating and testing example functionalities. ```bash ./gradlew test --tests "examples.UsersExamples" ``` -------------------------------- ### Retrieve Page Icon and Cover Details in Kotlin Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/notebooks/01-getting-started.ipynb This example shows how to retrieve and display the icon and cover image information for a given Notion page. It handles various icon types (Emoji, CustomEmoji, External, File, FileUpload) and cover types (External, File, FileUpload). This requires a 'page' object obtained from the Notion client. ```kotlin import it.saabel.kotlinnotionclient.models.pages.PageIcon import it.saabel.kotlinnotionclient.models.pages.PageCover println("🎨 Page Icon:") when (val icon = page.icon) { is PageIcon.Emoji -> println(" Emoji: ${icon.emoji}") is PageIcon.CustomEmoji -> println(" Custom emoji: ${icon.customEmoji.name} (${icon.customEmoji.id})") is PageIcon.External -> println(" External URL: ${icon.external.url}") is PageIcon.File -> println(" File URL: ${icon.file.url} (expires: ${icon.file.expiryTime})") is PageIcon.FileUpload -> println(" Upload ID: ${icon.fileUpload.id}") null -> println(" No icon set") } println("\n🖼️ Page Cover:") when (val cover = page.cover) { is PageCover.External -> println(" External URL: ${cover.external.url}") is PageCover.File -> println(" File URL: ${cover.file.url} (expires: ${cover.file.expiryTime})") is PageCover.FileUpload -> println(" Upload ID: ${cover.fileUpload.id}") null -> println(" No cover image set") } ``` -------------------------------- ### Notion Client Initialization Options Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/README.md Illustrates two primary ways to initialize the NotionClient: using the direct constructor (recommended) or a factory method. It also shows how to provide custom configuration like log level and rate limiting. ```kotlin // 1. Direct constructor (idiomatic Kotlin - recommended) val client = NotionClient("your-api-token") // 2. Factory method (also fully supported) val client = NotionClient.create("your-api-token") // With custom configuration val client = NotionClient( NotionConfig( apiToken = "your-api-token", logLevel = LogLevel.INFO, enableRateLimit = true ) ) ``` -------------------------------- ### Notion Rich Text: Date Mention Object Example Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/reference/notion-api/documentation/objects/01_Block_RichText.md An example of a rich text object with the 'mention' type, specifically a 'date' mention. It includes the start and end dates for the mentioned period. ```json { "type": "mention", "mention": { "type": "date", "date": { "start": "2022-12-16", "end": null } }, "plain_text": "2022-12-16" } ``` -------------------------------- ### Unique ID Property Management Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/reference/notion-api/documentation/objects/02_Page_PageProperties.md Information on the 'unique_id' property in Notion. It explains how unique IDs are structured, their read-only nature, and provides an example of how they are returned in a GET request. ```APIDOC ## Unique ID Property Management ### Description This section describes the 'unique_id' property in Notion, which provides an auto-incrementing identifier for pages. It details the structure of the unique ID and notes that it can only be read via the API, not updated. ### Method GET ### Endpoint `/pages/{page_id}` ### Parameters (No specific parameters for requesting unique ID, it's part of the page object in GET requests) ### Response Example (GET) ```json { "test-ID": { "id": "tqqd", "type": "unique_id", "unique_id": { "number": 3, "prefix": "RL" } } } ``` > **Note**: Unique IDs are auto-incrementing and cannot be updated via the API. They are returned as part of a GET page request. ``` -------------------------------- ### Notion Last Edited By Example (JSON) Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/reference/notion-api/documentation/objects/02_Page_PageProperties.md Shows the structure of the 'last_edited_by' property as returned in a GET page request. This field is read-only and contains information about the user who last updated the page. ```json { "Last edited by column name": { "id": "uGNN", "type": "last_edited_by", "last_edited_by": { "object": "user", "id": "9188c6a5-7381-452f-b3dc-d4865aa89bdf", "name": "Test Integration", "avatar_url": "https://s3-us-west-2.amazonaws.com/public.notion-static.com/3db373fe-18f6-4a3c-a536-0f061cb9627f/leplane.jpeg", "type": "bot", "bot": {} } } } ``` -------------------------------- ### Retrieve Formula Property Value (JSON) Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/reference/notion-api/documentation/objects/02_Page_PageProperties.md This JSON example illustrates the structure of a formula property value as returned in a GET page request. It includes the result type (e.g., 'number') and the calculated value. ```json { "Days until launch": { "id": "CSoE", "type": "formula", "formula": { "type": "number", "number": 56 } } } ``` -------------------------------- ### Setup: Initialize Kotlin Notion Client Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/notebooks/04-working-with-blocks.ipynb Initializes the Kotlin Notion Client by loading the library from Maven Central and setting up API credentials. Requires NOTION_API_TOKEN and NOTION_TEST_PAGE_ID environment variables. ```kotlin // Load the Kotlin Notion Client library from Maven Central @file:DependsOn("it.saabel:kotlin-notion-client:0.2.0") // Import necessary classes import it.saabel.kotlinnotionclient.NotionClient import it.saabel.kotlinnotionclient.models.blocks.Block import kotlinx.coroutines.runBlocking import kotlinx.coroutines.delay // Initialize the client val apiToken = System.getenv("NOTION_API_TOKEN") ?: error("❌ NOTION_API_TOKEN environment variable not set") val parentPageId = System.getenv("NOTION_TEST_PAGE_ID") ?: error("❌ NOTION_TEST_PAGE_ID environment variable not set") val notion = NotionClient(apiToken) println("✅ NotionClient initialized successfully!") ``` -------------------------------- ### Build and Test Kotlin Project Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/README.md Instructions for cloning the repository, building the project, and running unit and integration tests using Gradle. Integration tests require specific environment variables to be set. ```bash # Clone the repository git clone https://github.com/jsaabel/kotlin-notion-client.git cd kotlin-notion-client # Build the project ./gradlew build # Run all tests (unit tests run, integration tests skip without env vars) ./gradlew test # Run integration tests (requires environment variables) export NOTION_RUN_INTEGRATION_TESTS=true export NOTION_API_TOKEN="secret_..." export NOTION_TEST_PAGE_ID="page-id" ./gradlew test # Run specific integration tests (recommended) ./gradlew test --tests "*SearchIntegrationTest" ``` -------------------------------- ### Retrieve Files Property Value (JSON) Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/reference/notion-api/documentation/objects/02_Page_PageProperties.md This JSON example shows the structure of the 'files' property as returned in a GET page request. It includes the file name, type (e.g., 'external'), and the external URL. ```json { "Blueprint": { "id": "tJPS", "type": "files", "files": [ { "name": "Project blueprint", "type": "external", "external": { "url": "https://www.figma.com/file/g7eazMtXnqON4i280CcMhk/project-alpha-blueprint?node-id=0%3A1&t=nXseWIETQIgv31YH-1" } } ] } } ``` -------------------------------- ### Notion Phone Number Property - GET Response JSON Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/reference/notion-api/documentation/objects/02_Page_PageProperties.md Example JSON response for a 'phone_number' property retrieved from a Notion page. Note that the 'phone_number' field in the response is an empty object, indicating the property type. ```json { "Example phone number property": { "id": "%5DKhQ", "name": "Example phone number property", "type": "phone_number", "phone_number": {} } } ``` -------------------------------- ### Create Database Schema Example (JSON) Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/reference/notion-api/upgrading_to_2025_09_03/migration_summary.md This JSON example shows how to create a database in the new API version. The 'properties' are now nested under 'initial_data_source', distinguishing between database-level configurations (title, icon, parent) and data source-level configurations (properties). ```json { "initial_data_source": { "properties": { "Name": {"title": {}}, "Status": {"select": {...}} } }, "parent": {"type": "page_id", "page_id": "..."}, "title": [...], "icon": {}, "cover": {}, "parent": {"type": "page_id", "page_id": "..."} } ``` -------------------------------- ### Example: Create a Test Database for Page Creation Examples Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/notebooks/03-creating-pages.ipynb Creates a new Notion database with various property types (title, select, number, date, checkbox, richText) under a specified parent page. This database will be used to demonstrate creating pages with different properties. ```kotlin val database = runBlocking { notion.databases.create { parent.page(parentPageId) title("Project Tasks") properties { title("Task Name") select("Status") { option("To Do") option("In Progress") option("Completed") } select("Priority") { option("Low") option("Medium") option("High") } number("Estimate (hours)") date("Due Date") checkbox("Is Blocking") richText("Notes") } } } // Get the data source ID - we'll need this to create pages val dataSourceId = database.dataSources.firstOrNull()?.id ?: error("Database has no data sources") println("✅ Database created successfully!") println(" Database ID: ${database.id}") println(" Data Source ID: $dataSourceId") println(" Title: ${database.title.firstOrNull()?.plainText}) println(" URL: ${database.url}") ``` -------------------------------- ### Notion Relation Property - GET Response JSON Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/reference/notion-api/documentation/objects/02_Page_PageProperties.md Example JSON response for a 'relation' property retrieved from a Notion page. It includes an array of related page references and a 'has_more' boolean to indicate if more than 25 references exist. ```json { "Related tasks": { "id": "hgMz", "type": "relation", "relation": [ { "id": "dd456007-6c66-4bba-957e-ea501dcda3a6" }, { "id": "0c1f7cb2-8090-4f18-924e-d92965055e32" } ], "has_more": false } } ``` -------------------------------- ### Notion Last Edited Time Example (JSON) Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/reference/notion-api/documentation/objects/02_Page_PageProperties.md Illustrates the format of the 'last_edited_time' property as returned in a GET page request. This read-only field indicates the date and time when the page was last modified, formatted in ISO 8601. ```json { "Last edited time": { "id": "%3Defk", "type": "last_edited_time", "last_edited_time": "2023-02-24T21:06:00.000Z" } } ``` -------------------------------- ### Setup: Load Dependencies and Initialize Kotlin Notion Client Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/notebooks/02-reading-databases.ipynb Loads the Kotlin Notion Client library from Maven Central and initializes the client using environment variables for the Notion API token and a test page ID. It ensures that the necessary environment variables are set before proceeding. ```kotlin // Load the Kotlin Notion Client library from Maven Central @file:DependsOn("it.saabel:kotlin-notion-client:0.2.0") // Import necessary classes import it.saabel.kotlinnotionclient.NotionClient import it.saabel.kotlinnotionclient.models.base.SelectOptionColor import it.saabel.kotlinnotionclient.models.datasources.SortDirection import it.saabel.kotlinnotionclient.models.pages.PageProperty import kotlinx.coroutines.runBlocking import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll // Initialize the client val apiToken = System.getenv("NOTION_API_TOKEN") ?: error("❌ NOTION_API_TOKEN environment variable not set") val parentPageId = System.getenv("NOTION_TEST_PAGE_ID") ?: error("❌ NOTION_TEST_PAGE_ID environment variable not set") val notion = NotionClient(apiToken) println("✅ NotionClient initialized successfully!") ``` -------------------------------- ### Before vs. After Migration Guide for Date/DateTime Access (Kotlin) Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/journal/2025_10_06_typed_datetime_timezone_handling.md Illustrates the difference in accessing date/datetime properties before and after the API enhancement. The 'Before' example shows the ambiguous `localDateTimeValue`, while the 'After' examples provide clear alternatives for retrieving the exact moment in time (`toLocalDateTime`), naive date/time components (`localDateTimeNaive`), or the absolute instant (`instantValue`), promoting safer and more predictable code. ```kotlin // Before // val dateTime = property.localDateTimeValue // Unclear: does this handle timezone? What gets returned? // After // If you need the exact moment in time, converted to a specific timezone: // val utcTime = property.toLocalDateTime(TimeZone.UTC) // If you only care about the date/time components shown (rare): // val naive = property.localDateTimeNaive // If you need the absolute instant: // val instant = property.instantValue ``` -------------------------------- ### Run Kotlin Integration Tests for Rich Text Examples Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/journal/2025_10_09_Rich_Text_DSL_Documentation.md Demonstrates how to run integration tests specifically for the Rich Text examples within the kotlin-notion-client project. This requires setting specific environment variables and using a Gradle command to target the relevant test class. The tests verify various rich text features, including formatting, mentions, and complex content. ```bash export NOTION_RUN_INTEGRATION_TESTS=true export NOTION_API_TOKEN="secret_..." export NOTION_TEST_PAGE_ID="page-id" ./gradlew test --tests "*RichTextExamples" ``` -------------------------------- ### Notebook Setup: Client Initialization with Coroutines Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/journal/2025_10_16_02_Kotlin_Notebooks_Implementation.md Demonstrates the standard setup pattern for Kotlin Jupyter notebooks using the Kotlin Notion Client. It includes dependency declaration, importing necessary libraries, retrieving the Notion API token from environment variables, and initializing the NotionClient. `runBlocking` is used to wrap suspend functions as Jupyter cells are not suspend contexts. ```kotlin @file:DependsOn("it.saabel:kotlin-notion-client:0.1.0") import it.saabel.kotlinnotionclient.NotionClient import kotlinx.coroutines.runBlocking val apiToken = System.getenv("NOTION_API_TOKEN") ?: error("NOTION_API_TOKEN environment variable not set") val notion = NotionClient(apiToken) ``` -------------------------------- ### Kotlin Notion Client Property Value Setting Example Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/journal/2025_10_16_Developer_Experience_Exploration.md Demonstrates the concise and type-safe approach to setting property values in the Kotlin Notion client. Examples like `title("Name", "value")` and `select("Status", "Active")` illustrate the good developer experience provided by the DSL. ```kotlin // Works well: `title("Name", "value")`, `select("Status", "Active")` // Concise and type-safe // Good developer experience ``` -------------------------------- ### Handle Notion API Errors with Try-Catch Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/QUICKSTART.md Demonstrates robust error handling for common Notion API exceptions, such as ObjectNotFound, Unauthorized, and RateLimited errors, providing specific messages or actions for each. ```kotlin import it.saabel.kotlinnotionclient.NotionError try { val page = notion.pages.retrieve("page-id") } catch (e: NotionError.ObjectNotFound) { println("Page not found") } catch (e: NotionError.Unauthorized) { println("Invalid API token") } catch (e: NotionError.RateLimited) { println("Rate limited, retry after: ${e.retryAfter}") } ``` -------------------------------- ### Query Data Source (Table) Rows Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/QUICKSTART.md Retrieves all rows (entries) from a specified data source (table) using its ID. It then iterates through the results to print a specific property, typically 'Name'. ```kotlin // Get all rows from a table val pages = notion.dataSources.query("data-source-id") pages.results.forEach { page -> println(page.properties["Name"]) } ``` -------------------------------- ### Retrieve a Notion Page by ID Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/QUICKSTART.md Fetches details of a specific Notion page using its unique ID. It demonstrates accessing page properties like title, creation time, and URL. ```kotlin val page = notion.pages.retrieve("page-id") println("Page title: ${page.properties["title"]}") println("Created: ${page.createdTime}") println("URL: ${page.url}") ``` -------------------------------- ### Fluent API Examples in Kotlin Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/journal/2025_07_14_05_ApiIntegrationOverloads.md Demonstrates the usage of the new fluent API overloads for creating pages, databases, and appending blocks. This approach simplifies multi-step operations into a single, readable line of code, leveraging Kotlin's DSL capabilities. It contrasts the 'before' (multi-step) and 'after' (fluent one-line) methods for page creation. ```kotlin // Before: Multi-step approach val pageRequest = pageRequest { parent.page(id); title("Test") } val page = client.pages.create(pageRequest) // After: Fluent one-line API val page = client.pages.create { parent.page(id); title("Test") } // Database creation val database = client.databases.create { parent.page(pageId) title("Task Database") properties { title("Name"); checkbox("Done") } } // Block appending val blocks = client.blocks.appendChildren(blockId) { paragraph("New content") heading1("Section title") } ``` -------------------------------- ### Notion People Property - GET Response JSON Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/reference/notion-api/documentation/objects/02_Page_PageProperties.md Example JSON response for a 'people' property retrieved from a Notion page. It details user information including 'object', 'id', 'name', 'avatar_url', 'type', and nested 'person' details like 'email'. ```json { "Stakeholders": { "id": "%7BLUX", "type": "people", "people": [ { "object": "user", "id": "c2f20311-9e54-4d11-8c79-7398424ae41e", "name": "Kimberlee Johnson", "avatar_url": null, "type": "person", "person": { "email": "hello@kimberlee.dev" } } ] } } ``` -------------------------------- ### Query Data Source with Filters and Sorting Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/QUICKSTART.md Fetches entries from a data source that match specific filter criteria (e.g., status and priority) and sorts the results by due date in ascending order. ```kotlin import it.saabel.kotlinnotionclient.SortDirection val urgentTasks = notion.dataSources.query("data-source-id") { filter { and { property("Status") { select { equals("In Progress") } } property("Priority") { select { equals("High") } } } } sorts { property("Due Date") { direction = SortDirection.ASCENDING } } } ``` -------------------------------- ### Copying Notebooks with Bash Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/journal/2025_10_17_Kotlin_Notebooks_Progress.md Demonstrates the command-line usage for copying an existing Jupyter notebook to serve as a template for a new one. This follows a 'copy-first' strategy for notebook development. ```bash cp notebooks/05-rich-text-dsl.ipynb notebooks/06-advanced-queries.ipynb ``` -------------------------------- ### Example of CreateDatabaseRequest with InitialDataSource (Kotlin) Source: https://github.com/jsaabel/kotlin-notion-client/blob/main/journal/2025_10_05_Unit_Test_Migration_Complete.md Provides a concrete example of the `CreateDatabaseRequest` builder method, demonstrating how the `initialDataSource` object is constructed with properties. This snippet highlights that the DSL for building database requests was already aligned with the new `initialDataSource` structure, simplifying the migration process for tests that used this DSL. ```kotlin fun build(): CreateDatabaseRequest { return CreateDatabaseRequest( parent = parentValue!!, title = titleValue!!, initialDataSource = InitialDataSource(properties = properties), icon = iconValue, cover = coverValue, description = descriptionValue, ) } ```