Integration with Notion - remotely read/retrieve data from your databases

Hey everyone,

I wanted to share an integration with Notion that I've been working on that some of you might find useful. Before diving into the details, I want to start by saying that this is way easier to accomplish using Data Blaze instead. But, if you're already using Notion and migrating to Data Blaze would be a real pain, this solution will work great.

Here's a Loom video that demonstrates the 3 use-cases described below:

notion integration with text blaze - Watch Video



1. Retrieve multiple entries from a database without searching, filtering based on a Status field: this is great for any project management you're doing in Notion. This snippet automatically retrieves any tasks with the status of Done or In Progress. It can be customized to any statuses, or combined with other filters (e.g. "retrieve all tasks in Complete status where the status changed this week")

2. Retrieve a single row of data from a database by searching: Let's say I have a big list of items in my database and I want to retrieve details about one of those rows. I can search for the match in my snippet, retrieve all the associated data for that specific row, and merge it into my snippet's text.

3. Retrieve multiple entries from a database by searching: kind of a combination of example 1 and 2. I can enter a search term and retrieve every matching result with all the details from my database, parsing the results into a nicely formatted list.

The final example in my video shows that I can also make a snippet that lets me navigate my Notion databases remotely. First choosing a database, then choosing what field I want to search by, and then finally searching by that field. This snippet supports searching by any field type (except formula) and can retrieve data about any field type (except formula).




If you want to set this up for your own use of Notion, reply here or message me directly. Notion does not charge for this functionality. We'll just need to generate an API token and then do some minor customization to the snippets so they're pointed at your database(s) and are retrieving the fields you want to retrieve.

While not demonstrated, this integration can also write new entries into your Notion databases.

These snippets won't work in our Community and you'll need to add your API token to them, but here are the contents so you can see what's happening:

{note: preview=no}{urlload: https://api.notion.com/v1/databases/replace_me_with_database_id/query; method=POST; headers=Authorization:Bearer {=token}, Content-Type:application/json, Notion-Version:2022-06-28; start=() -> ["loading":yes]; done=(res) -> ["loading":no,"filterresults": catch(fromJSON(res)["results"], "???")]; body={=body3}}{endnote: trim=yes}
{note: preview=no}
{token="replace_me"}
{body3={
"filter": {
"or": [
{
"property": "Status",
"status": {
"equals": "Done"
}
},
{
"property": "Status",
"status": {
"equals": "In Progress"
}
}
]
}}}
{today={time: YYYY-MM-DD}}
{endnote}{if: loading}Loading data from Notion...{else}
In progress tasks
{repeat: for x in filterresults if x["properties"]["Status"]["status"]["name"]=="In progress"}{y=x["properties"]}Task Name: {=y["Task Name"]["title"][1]["text"]["content"]}
Due Date: {time: MMMM, Do, YYYY; at={=y["Due Date"]["date"]["start"]}} -- {remaining=datetimediff(today, {time: YYYY-MM-DD; at={=y["Due Date"]["date"]["start"]}}, "D")} {=remaining} {if: remaining==1}day remains{else}days remain{endif} to due-date
Assigned Owner: {=y["Owner"]["rich_text"][1]["text"]["content"]}
Details: {=y["Details"]["rich_text"][1]["text"]["content"]}
Last status update: {time: MMMM, Do, YYYY; at={=y["Date of last update"]["date"]["start"]}}

{endrepeat}

Complete tasks
{repeat: for x in filterresults if x["properties"]["Status"]["status"]["name"]=="Done"}{y=x["properties"]}Task Name: {=y["Task Name"]["title"][1]["text"]["content"]}
Assigned Owner: {=y["Owner"]["rich_text"][1]["text"]["content"]}
Details: {=y["Details"]["rich_text"][1]["text"]["content"]}
Completion date: {time: MMMM, Do, YYYY; at={=y["Date of last update"]["date"]["start"]}}

{endrepeat}{endif}


{note}Part name: {formtext: name=filterparam}{formtoggle: name=ready?}
{urlload: https://api.notion.com/v1/databases/replace_me_with_database_id/query; method=POST; headers=Authorization:Bearer {=token}, Content-Type:application/json, Notion-Version:2022-06-28; start=() -> ["loading":yes]; done=(res) -> ["loading":no,"filterresults": catch(fromJSON(res)["results"][1]["properties"], "???")]; body={=body2}}{endformtoggle}{endnote: trim=yes}
{note: preview=no}
{token="replace_me_with_your_api_token"}
{body2={
"filter": {
"property": "Product Name",
"title": {
"contains": "{=filterparam}"
}
}
}}
{endnote}{if: not `ready?`}Enter search term to proceed{elseif: `ready?` AND loading==yes}Loading results...{else}Hi {formtext: name=customer name},

I understand you're interested in the {=filterresults["Product Name"]["title"][1]["text"]["content"]} as the {=filterresults["Product Type"]["rich_text"][1]["text"]["content"]} for your PC build (model number {=filterresults["Model Number"]["rich_text"][1]["text"]["content"]}). Those are currently {=filterresults["Availability"]["select"]["name"]} and cost ${=filterresults["Cost per unit"]["number"]} per unit. {if: {=filterresults["Availability"]["select"]["name"]}=="back ordered"}Since those are backordered, I can put together an order for you, but it might be a few weeks before it's available to ship.{else}If you're set on that, I can get an order together for you.{endif}{endif}


{note}Enter which Genre you want to search for: {formtext: name=filterparam}{formtoggle: name=ready?}
{urlload: https://api.notion.com/v1/databases/add_database_id_here/query; method=POST; headers=Authorization:Bearer {=token}, Content-Type:application/json, Notion-Version:2022-06-28; start=() -> ["loading":yes]; done=(res) -> ["loading":no,"filterresults": catch(fromJSON(res)["results"], "???")]; body={=body2}}{endformtoggle}{endnote: trim=yes}
{note: preview=no}
{token="replace_me_with_your_api_token"}
{body2={
"filter": {
"property": "Genre",
"select": {
"equals": "{=filterparam}"
}
}
}}
{endnote}
{if: not `ready?`; trim=left}Enter search term to proceed{elseif: `ready?` AND loading==yes}Loading results...{else}{repeat: for x in filterresults}{y=x["properties"]}Book Title: {=y["Title"]["title"][1]["text"]["content"]}
Author: {=y["Author"]["rich_text"][1]["text"]["content"]}
My Rating: {=y["Rating"]["select"]["name"]}
When I finished reading it: {time: MMMM, Do, YYYY; at={=y["Finished Date"]["date"]["start"]}}
Favorite thing about it: {=y["Favorite things"]["rich_text"][1]["text"]["content"]}

{endrepeat}{endif}

9 Likes

Hello mate !
Just wanted a minute to show appreciation for those really complex snippet you're sharing, here.
Been using this amazing tool of textBlaze for 2years now so I got quite deep down the rabbit hole of commands, URLload, APIs call and stuff.
Recently fallen in love with Notion so the possible synergy between the two was OBVIOUS to me.

But I find the Notion API to be very messy and stuffy (compared to how clean and ordered their app is).
And the very idea of having to struggle/contend with it just to match Blaze/Notion was off-putting to say the least.
But thanks to your sharing, not only do I know it's achievable but also have a leg start ! <3
Thanks again !

2 Likes