Script to convert Readwise highlights into a single note!

Hi Guys,

I would like to pick someones brain for writing a script, unfortunately I can’t. :sweat_smile:

I have a readwise integration. In this readwise integration I have a database called Resources and a database called Highlights.

In the case of a book a Resource contains many highlights (sometimes over 250). For this I want to create 1 note to which all Text (= a Rich text field) from the Highlights will be added. This way I basicly create a Summary.

What I need is a button which triggers a script in the Resource database. I want to accomplisch this in 1 script, but for a clear explanation I have explained it in two parts.

Part 1

  • After clicking the button, a new entity in the database Notitie needs to be created.
  • The following fields should be filled in with information from the source
    • Resource = Linked resource
    • Name = Resource name
    • Bron - persoon = Resource Bron - persoon
    • Tag = Resource tag
    • URL = Resource URL

Part 2

  • A Resource is linked to many Highlights entities and these highlights contains a Richt text field called Text
  • Notitie also has a Rich text field, called Omschrijving
  • I want to add Text from Hightlight to Omschrijving in the created Notitie

Important in this is the order in which Text from Highlight should be placed in Omschrijving of Notitie. This should be based on creation date. Otherwise, the order of my text makes no sense.

I hope there is someone who can help me with this.

Thanks in advance!

Marloes

You’ll need an automation like this (in the Resource DB):

In the first action, I have set the name of the new Notitie based on the Resource name. You 'll need to add extra field settings to take care of what you have listed in Part 1.

The script in the second action is as follows:

const fibery = context.getService('fibery');

for (const entity of args.currentEntities) {
    const notitie = await fibery.getEntityById('Readwise/Notitie', entity['Notitie']['Id'], ['Omschrijving']);
    const entityWithExtraFields = await fibery.getEntityById(entity.type, entity.id, ['Highlights']);
    let highlights = await fibery.getEntitiesByIds("Readwise/Highlight", entityWithExtraFields['Highlights'].map((h) => h.Id), ['Text']);
    const sortedHighlights = highlights.sort((h1, h2) => (h1['Creation Date'] > h2['Creation Date']) ? 1 : (h1['Creation Date'] < h2['Creation Date']) ? -1 : 0);
    for (const highlight of sortedHighlights) {
        const text = await fibery.getDocumentContent(highlight['Text']['Secret']);
        await fibery.appendDocumentContent(notitie['Omschrijving']['Secret'], text);
    }
}

It assumes that the Notitie db is in the Readwise space.

Hi @ChrisG ,

Thank you so much for responding!

I believe there is a small error in the script. I have changed the space where Notitie is in (DB second brain). But I get the following message in Fibery.

Failed to execute Action “Script”: Cannot read property ‘Id’ of undefined

const fibery = context.getService('fibery');

for (const entity of args.currentEntities) {
    const notitie = await fibery.getEntityById('DB second brain/Notitie', entity['Notitie']['Id'], ['Omschrijving']);
    const entityWithExtraFields = await fibery.getEntityById(entity.type, entity.id, ['Highlights']);
    let highlights = await fibery.getEntitiesByIds("Readwise/Highlight", entityWithExtraFields['Highlights'].map((h) => h.Id), ['Text']);
    const sortedHighlights = highlights.sort((h1, h2) => (h1['Creation Date'] > h2['Creation Date']) ? 1 : (h1['Creation Date'] < h2['Creation Date']) ? -1 : 0);
    for (const highlight of sortedHighlights) {
        const text = await fibery.getDocumentContent(highlight['Text']['Secret']);
        await fibery.appendDocumentContent(notitie['Omschrijving']['Secret'], text);
    }
}

To make shure the mistake wasn’t on my hand, I added a Notitie database in the Readwise space. But unfortunately that didn’t solved the problem.

I see one difference in our setup. Your Resource can have one Notitie. Ours can have many. Don’t know if this is a problem or not.

Yep, that will break it.
I just assumed that you could only create one entity that summarised the Highlights related to a single Resource.

If there’s the possibility of multiple Notitie then I’ll need to change the strategy a little. I’ll get back to you tomorrow.

So here’s Plan B:

Part 1
Create a basic button automation (in Resource DB) to create a Notitie from a Resource:


(add in the necessary field settings to populate Notitie with the correct info)

Part 2
Add an automation in the Notitie db, which triggers on a Notitie being created, with a filter for ‘Resource is not empty’.

The script is as follows:

const fibery = context.getService('fibery');

for (const entity of args.currentEntities) {
    const resource = await fibery.getEntityById('Readwise/Resource', entity['Resource']['Id'], ['Highlights']);
    let highlights = await fibery.getEntitiesByIds("Readwise/Highlight", resource['Highlights'].map((h) => h.Id), ['Text']);
    const sortedHighlights = highlights.sort((h1, h2) => (h1['Creation Date'] > h2['Creation Date']) ? 1 : (h1['Creation Date'] < h2['Creation Date']) ? -1 : 0);
    for (const highlight of sortedHighlights) {
        const text = await fibery.getDocumentContent(highlight['Text']['Secret']);
        await fibery.appendDocumentContent(entity['Omschrijving']['Secret'], text);
    }
}

Hi @Chr1sG , thank you so much!!

We have adjusted your script slightly. We found out that creation date is not the correct field to determine the order of the highlights, but Location is!

Location is the place of the highlight in your book. Due to location, the order of the highlights always remains correct. Even if you go back to the beginning and create new highlights!

So here is the updated script for everyone who is looking for the same solution.

const fibery = context.getService('fibery');

for (const entity of args.currentEntities) {
    const resource = await fibery.getEntityById('Readwise/Resource', entity['Resource']['Id'], ['Highlights']);
    let highlights = await fibery.getEntitiesByIds("Readwise/Highlight", resource['Highlights'].map((h) => h.Id), ['Text', 'Location']);
    const sortedHighlights = highlights.sort((h1, h2) => (h1['Location'] > h2['Location']) ? 1 : (h1['Location'] < h2['Location']) ? -1 : 0);
    for (const highlight of sortedHighlights) {
        const text = await fibery.getDocumentContent(highlight['Text']['Secret']);
        await fibery.appendDocumentContent(entity['Omschrijving']['Secret'], text);
    }
}
1 Like