bod / klibnotion Goto Github PK
View Code? Open in Web Editor NEWA Notion API client library for Kotlin, Java and more.
License: Apache License 2.0
A Notion API client library for Kotlin, Java and more.
License: Apache License 2.0
Hi,
Is the implementation of the latest version of the Notion api planned?
I would like to access the emoji of the page.
Also is it possible to group filter ? I haven't found the solution yet...
DatabaseQuery().all()/any() can't contain another implementation of them selve from what i see
Thanks
Denis
getAllBlockListRecursively does not fetch the children of UnknownBlockType blocks,
Resulting in some page content not being read.
This is unclear and should be changed or better documented.
The Query a database endpoint accepts an array of sort objects in the sorts
body parameter.
The sort object can contain a timestamp
property with possible values "created_time"
and "last_edited_time"
.
Currently, the library only provides PropertySort
.
See https://developers.notion.com/reference/post-database-query
Looks like a request for page creation by page ref is wrong.
Following code
RichTextList richTextList = new RichTextList();
richTextList.text("Name", Annotations.DEFAULT);
return pages.createPage(new PageReference(parentPage), richTextList, content)
produce request
{
"parent": {
"type": "page_id",
"page_id": "6bd77e46-914a-44dd-98a4-bd5f85d163a4"
},
"properties": {
"title": {
"rich_text": [
{
"text": {
"content": "Name"
}
}
]
}
},
"children": [
{
"object": "block",
"type": "paragraph",
"paragraph": {
"text": [
{
"text": {
"content": "Test paragrgaph"
}
}
]
}
}
]
}
it fails with errors
{"object":"error","status":400,"code":"validation_error","message":"body failed validation. Fix one: body.parent.database_id should be defined, instead was `undefined`. body.properties.title should be an array or `undefined`, instead was `{\"rich_text\":[{\"text\":{\"content\":\"Name\"}}]}`."}
The correct request should look like this:
{
"parent": {
"page_id": "6bd77e46-914a-44dd-98a4-bd5f85d163a4"
},
"properties": {
"title": [
{
"type": "text",
"text": {
"content": "Name"
}
}
]
},
"children": [
{
"object": "block",
"type": "paragraph",
"paragraph": {
"text": [
{
"type": "text",
"text": {
"content": "Test paragrgaph"
}
}
]
}
}
]
}
Building filters, and properties with the current DateOrDateRange
is a bit cumbersome, it would be much nicer if it would be compatible with the kotlinx DateTime library, usage of LocalDate
, or LocalDateTime
would be much more accessible.
This is just a "nice to have", I'll try and follow up with a PR with some extensions, or changes to data classes when I have time.
Again, nice lib folks <3
Hi BoD and first of all thank you for your work.
I can query a simple database like a charm using:
List<Page> pages =
client.getDatabases().queryDatabase(NOTION_DATABASE_ID, null,null, new Pagination()).get().results;
but when i try working with my database with fancy attributes, i got a NullPointerException on ApiPropertyValueFormulaConverter.apiToModel
here is the attributes of my database:
When i try to debug, it's seems to throw null pointer exception when trying to convert Next Do Date formula column.
Here is the attributes in cause i think:
5 = {SelectPropertySpecImpl@3300} "SelectPropertySpecImpl(name=Récurrence?, id=ZIie, options=[SelectOptionImpl(name=Quotidien, id=71b3542e-6374-4ec3-80ad-f3f4e6c89a27, color=GRAY), SelectOptionImpl(name=Hebdomadaire, id=766db0a8-6e2c-4d25-a950-58601bb5726f, color=BLUE), SelectOptionImpl(name=Mensuel, id=cdddcdd4-8252-4f65-902b-9047625024d8, color=RED), SelectOptionImpl(name=Trimestriel, id=7bbeeca8-c0e6-4b7c-abda-c3acb783a91e, color=BROWN), SelectOptionImpl(name=6 Mois, id=ce73c619-ee0d-4f51-a1a4-afc3e63ef8e9, color=YELLOW), SelectOptionImpl(name=Annuel, id=46db212d-fa98-4e53-929a-1e4a0883e28c, color=GREEN)])"
9 = FormulaPropertySpecImpl(name=Recurrence en jours, id=zudh, expression=if(prop("Récurrence?") == "6 Mois", 180, if(prop("Récurrence?") == "Quotidien", 1, if(prop("Récurrence?") == "Hebdomadaire", 7, if(prop("Récurrence?") == "Mensuel", 30, if(prop("Récurrence?") == "Trimestriel", 90, if(prop("Récurrence?") == "Annuel", 365, 0)))))))
11 = {FormulaPropertySpecImpl@3306} "FormulaPropertySpecImpl(name=Next Do Date, id={vAO, expression=dateAdd(prop("Do Date"), prop("Recurrence en jours"), "days"))"
12 = {DatePropertySpecImpl@3307} "DatePropertySpecImpl(name=Do Date, id=~CiJ)"
Récurrence? column can be null, maybe it's that.
Exception:
java.util.concurrent.ExecutionException: java.lang.NullPointerException
at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1908)
at NotionGoogleTaskSynchronizer.main(NotionGoogleTaskSynchronizer.java:64)
Caused by: java.lang.NullPointerException
at org.jraf.klibnotion.internal.api.model.property.value.formula.ApiPropertyValueFormulaConverter.apiToModel(ApiPropertyValueFormulaConverter.kt:64)
at org.jraf.klibnotion.internal.api.model.property.value.ApiPropertyValueConverter.apiToModel(ApiPropertyValueConverter.kt:90)
at org.jraf.klibnotion.internal.api.model.property.value.ApiPropertyValueConverter.apiToModel(ApiPropertyValueConverter.kt:59)
at org.jraf.klibnotion.internal.api.model.ApiConverter.apiToModel(ApiConverter.kt:31)
at org.jraf.klibnotion.internal.api.model.page.ApiPageConverter.apiToModel(ApiPageConverter.kt:39)
at org.jraf.klibnotion.internal.api.model.page.ApiPageConverter.apiToModel(ApiPageConverter.kt:35)
at org.jraf.klibnotion.internal.api.model.ApiConverter.apiToModel(ApiConverter.kt:31)
I try to update a date-property of a notion database with this line of code:
propertyList.date("todoist_update_time", DateOrDateRange(DateTime(Timestamp(System.currentTimeMillis())), null))
The date is updated, but unfortunatelly in the wrong timezone (2 hours to early. My Timezone is GMT+02)
In the TimestampFormatter-Class the Timezone is forced to be GMT.
private val simpleDateFormat = SimpleDateFormat(format).apply {
// Set the default timezone to GMT for the case where it's not present in the date to parse
// which is the case when it's a date without a time.
timeZone = TimeZone.getTimeZone("GMT")
}
The DateTime-Constructor consumes a Timestamp, which is not bound to a timezone, so i can't control the timezone from outside.
My proposal would be to use two different SimpleDateFormat-objects. One for parsing and one for formatting.
private val formatFormatter = SimpleDateFormat(format)
private val parseFormatter = SimpleDateFormat(format).apply {
// Set the default timezone to GMT for the case where it's not present in the date to parse
// which is the case when it's a date without a time.
timeZone = TimeZone.getTimeZone("GMT")
}
actual fun parse(formattedDate: String): Timestamp {
return parseFormatter.parse(formattedDate)
}
actual fun format(timestampToFormat: Timestamp): String {
return formatFormatter.format(timestampToFormat)
}
AFAIK there is no possibility to delete/archive a page with your api.
The notion dev documentation points out that an update-request should be performed
Possibilities how this could be implemented in my opinion:
Could you look into it?
I woud like to enable as detailed logging as possible, but I don't want to leak my notion secret in logs. It would be nice if there will be a possibility to hide Authorization header from the logs.
Currently synced blocks are read-only, but the API also allows creation.
Note that there are 2 possible types of creating a synced block:
It's all explained here: https://developers.notion.com/changelog/synced-block-link-to-page-and-template-block-types-are-now-supported-in-the-api
The Notion documentation shows that START_CURSOR
is encoded in the request body, but here it's added as a URL parameter, which as of the API version 2021-08-16
responds with a validation error.
https://api.notion.com/v1/databases/{DATABASE_ID}/query?start_cursor={PAGE_ID}
{
"object": "error",
"status": 400,
"code": "validation_error",
"message": "query failed validation: query.start_cursor should be not present, instead was `\"e8635964-722c-4aed-a33d-ac3709280c99\"`."
}
This behaviour can be reproduced by setting up the request in manually (cUrl/Postman/Insomnia), and then changing this to a JSON body request.
It looks as though the START_CURSOR
should be removed from NotionService.kt
, and encoded with a @SerialName
annotation in the ApiDatabaseQuery
data class. There may also be other request body classes that need updating as well.
When the user workspace doesn't have an icon the response from Notion API is following:
{"access_token":"xxxx","token_type":"bearer","workspace_name":"Vitaliy","bot_id":"xxxx"}
and parsing is failing because workspace_icon in ApiOAuthGetAccessTokenResult in mandatory
Hey!
I really like the API of your project and since I want to use it for my own ktor server project (where my server should act as a middleware between other clients and multiple services, including notion).
I sadly am not able to get it to start. When I try to make calls with your client I get always ClassNotFoundExceptions like the one above or before I got ClassNotFound io.ktor.client.features.HttpClientFeature. It switched over to the JSON-Feature when I added one by one those additional dependencies:
//debugging
implementation("io.ktor", "ktor-client-okhttp", ktor_version)
implementation("io.ktor:ktor-client-core:$ktor_version")
implementation("io.ktor:ktor-client-cio:$ktor_version")
implementation("io.ktor:ktor-client-logging:$ktor_version")
implementation("io.ktor:ktor-client-content-negotiation:$ktor_version")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version")
implementation("io.ktor:ktor-serialization-kotlinx-xml:$ktor_version")
implementation("io.ktor:ktor-serialization-kotlinx-cbor:$ktor_version")
implementation("io.ktor:ktor-client-auth:$ktor_version")
implementation("io.ktor", "ktor-client-json", ktor_version)
implementation("io.ktor", "ktor-client-serialization", ktor_version)
implementation("io.ktor", "ktor-client-logging", ktor_version)
implementation("org.apache.httpcomponents:httpclient:4.5.13")
I myself am using the Version 2.0.0 of ktor server and 1.6.20 of kotlin.
I very much hope you can help, there are 1-2 other options out there but like I said your api is great, especially your Content DSL.
Best Regards,
Björn
Importing Date from org.jraf.klibnotion.model.date
can cause conflicts with DateTime libs or locally defined libraries, especially when defined with aliases, we should try to coalesce with the kotlinx and java.ltime library, with respect to multiplatform
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.