Automatic linking of inline Entities

Is there a way of automatically link entities from inside a rich text field to the corresponding entity?

for example: If i mention a “task” in a Description field of a meeting, can that be automatically added to the “task” list relation of that meeting?

That would require some scripting, but unfortunately there is no Automation trigger for “Entity Reference added in Rich Text” :confused:

You would either need to run it off a manually-clicked Button, or a timer-driven Rule (which can only run max once/hour).

A script could extract entity references from a Rich Text field and link the entities to a collection.

2 Likes

awesome. thats good news.

would that be something that is easily done or does it require some javascript magic? is there e reference somewhere in the docs?
thanks!

Definitely would require some javascript magic :man_mage:
Docs are here: . | Fibery

Here’s a Button script that scans through a Rich Text to find all references to Users.
Note that there is a bunch of additional code that’s not related to your specific needs.

// Create Call Log (and Call Log Entries) from Attendees info in entity Description

const CALL_LOG_TYPE = 'Users/Call Log'
const CALL_LOG_ENTRY_TYPE = 'Users/Call Log Entry'
const ENTRIES_FIELD = 'Call Log'
const CLIENTS_FIELD = 'Clients'

const fibery = context.getService('fibery')
const assert = (condition, msg) => { if(!condition) throw new Error(msg) }

for (const entity of args.currentEntities) {
    const client = entity['Client']
    const descriptionSecret = entity['Description'].Secret
    const content = await fibery.getDocumentContent(descriptionSecret, 'md')
    const text = find_H_content(2, content, 'ATTENDANCE')
    const users = text.match( /(?<=\[\[#@)[0-9a-f/-]{70,}.*/g )
    //console.log('UserIds: ' + users.join('\n'));
    const mtgDate = findTopH1MtgDate(content)

    // Create the Call Log
    const callLog = await fibery.createEntity(CALL_LOG_TYPE, {
        'Meeting Notes': entity.Id,
        'Date': mtgDate,
        'Name': client.Name + ' - ' + mtgDate
    })
    await fibery.addCollectionItem(CALL_LOG_TYPE, callLog.Id, CLIENTS_FIELD, client.Id)

    // Create and link a Call Log Entry for each attendee user
    for (const u of users) {
        const m = u.match( /^([0-9a-f/-]{70,})\s*(.*)/ )
        if( !m ) continue
        const uid = m[1].replace( /^.+?\//, '' )     // remove Type Id
        let status = null // default status
        if (m[2]) {
            status = m[2].match( /\by|[✅☑✔]/i ) ? 'Attended' :
                m[2].match( /\bn|[❌✖❎]/i ) ? 'No-Show' :
                m[2].match( /\bc/i ) ? 'Canceled' :
                null
        }
        const fields = { 'Call Log': callLog.Id, 'User': uid }
        if(status) fields['Status'] = status
        const entry = await fibery.createEntity(CALL_LOG_ENTRY_TYPE, fields)
    }
}

// Find and return the text content of the named H-section (level=2 means H2, etc)
function find_H_content(level, content, title) {
    const regex = new RegExp(`^#{${level}}[^#]\\s*\\W*\\s*${title}([\\s\\S]*?)\\n#{1,${level}}[^#]`, "ims")
    const m = content.match(regex)
    assert( m, `Did not find "${title}" H${level} section` )
    return m[1]
}

function findTopH1MtgDate(content) {
    try {
        const d = content.match(/^# (.*MEETING.*)/i)[1]
            .match(/(\d+[-\/.]\d+[-\/.]\d+)/)[1]
        return new Date(d).toISOString().substr(0,10)
    } catch (err) {
        throw new Error('Could not find Meeting H1 with Date in Meeting Notes')
    }
}

1 Like

wow, thanks - will look through this tomorrow.

Related, and probably the solution:

1 Like