Rule/Formula Involving Rich-Text Fields

Is this possible?

#1 (Rule): If a rich-text field is not empty, then a checkbox’s value becomes ‘True’

#2 (Rule): If a rich-text field is not empty, copy the first few words to a text field


Use-case: I just want to know if any of the rich-text fields are populated without having to click on the entity

Currently you cannot trigger an Action on a RichText field being changed/updated.
And no Formula field functions can use a RichText field.
I don’t see a way…
:thinking:

@Polina_Zenevich - perhaps we could get a new Formula function to get a RichText field’s contents as HTML/Markdown/PlainText?

1 Like

I was just playing around with the email integration, which I was hoping could be used for processing emails we get in a shared inbox some of our content team have to manage. However, since there doesn’t appear to be labels sync’d and you can’t create rules that operate on the body of the email, the use case is limited.

Triggering off of rich text field changes would require more work-arounds, but there is at least a work-around for an initial processing of the rich text. You could leverage a script to execute on entity creation or update that could search the contents for keywords or whatever, then apply relations based on the contents, copy text into other fields, etc. However, this would be a lot easier if you could just create rules directly on raw, HTML, or markdown as you suggest.

It also would be nice, even if you couldn’t directly apply rules to the rich text, but to at least have a trigger of when it is updated. You could then trigger a script to run and apply whatever changes to the entity.

1 Like

Entity Creation, yes - but I don’t think you can currently trigger off “update” of a RichText field. It would have to be a different field type.

1 Like

Right, I agreed with that in my response. What I’m saying is that if the rich text field exists at entity creation time (as with the email integration), then you can at least process the contents via a script when the entity is created. There are two limiting aspects here. 1) Missing ability to trigger off of rich text change and 2) Inability to use formulas on rich text fields

What I’m clarifying to @v3j is that issue 2 can at least be worked around somewhat within fibery by leveraging scripts in the rules/buttons.

The only temporary option I could think of for the events, besides using something external, is to create a field called “Trigger Date” or something, and use a formula set to today. Then, you have an event to trigger off of “Trigger Date” changing in value. This will happen once per day, so the script would be triggered for each entity once a day.

1 Like

Thanks for the insights @rothnic and @Matt_Blais while I’m still trying to process them.

But what caught my attention is using a “daily trigger” as a temporary workaround :slight_smile: I already have a Rule which makes use of that, triggered once a day.

Hmmm now, how do I make Fibery tell me that a rich-text field is not empty… something that I can easily see in any view as long as I make that field visible.

Hi, @rothnic

Thanks for feedback. We are going to add the ability to select mail folders to be synchronised, so looks like it will solve the issue.

Could you please explain what kind of operations are required to be performed on the email body?

We will investigate the possibility to provide triggers related to changes in documents.

Thanks,
Oleg

2 Likes

Hi, @v3j

We will investigate the possibility to provide formulas on calculating document content. By the way your idea to use daily trigger sounds cool.

Thanks,
Oleg

2 Likes

It would be useful to have new Formula functions to convert a RichText field to plain-text (removing all formatting), or Markup or HTML.
As well as having some way to trigger on RichText updates (maybe rate-limited).

Here is a script that I tested to work for that specific use case. It could also give you a starter example for how to extract other information.

// Developer reference is at api.fibery.io/#action-buttons

// Fibery API is used to retrieve and update entities
const fibery = context.getService('fibery');

// affected entities are stored in args.currentEntities;
// to support batch actions they always come in an array
for (const entity of args.currentEntities) {

    // the rich text field is a document, which requires a special id to get access to
    // In this case, the rich text field is "Description", so we request that field be included
    const entityWithExtraFields = await fibery.getEntityById(entity.type, entity.id, ['Description']);

    // as long as we have the rich text field looking valid, let's do something with it
    if (entityWithExtraFields['Description']) {
        // just saving a shorter reference to it
        const dsc = entityWithExtraFields['Description'];

        // get the rich text field contents as markdown (supports md, html, and json)
        const doc = await fibery.getDocumentContent(dsc.secret, 'md');

        // now we can search the rich text for whatever we are looking for
        // In this case, lets just see if the doc is non-null, then update a checkbox
        const docExists = doc !== null;
        await fibery.updateEntity(entity.type, entity.id, {
            'Description Exists': docExists
        });
    }
}
3 Likes

Use Case for Processing Incoming Leads/Offers

We work as affiliates for many different companies (Amazon, Walmart, etc), which means working directly with them or through affiliate managers (Commission Junction, Sharasale, Linkshare, etc). While we work with the companies directly if they have APIs, many often don’t, and/or they might move from direct relationships to working through something like CJ.

So, we have leads that come in from various sources that could be talking about the same vendor. The first thing we’d do is try to assign the correct company(s) to the email, which often would require inspecting the body of the email. This could be leveraged to better sort the messages in the order they should be worked because we have different commission rates per vendor.

Then, the next step is often to try to turn the offers into something closer to what we could list on our site. We would essentially be trying to extract as much product information as possible, which would be implemented as a separate Type. We need an affiliate link, the price, discount, brand, product name, etc. The nice thing of considering fibery for this use case is we could add more data externally via the API and/or by requesting more data during key events as more data is extracted from the emails. Finally, we have people that would process the inbox and fill in the missing pieces and publishing content to our site as needed (we’d trigger an API call when certain conditions are met).

Functions to Help Process Email Messages

So, in the end, I think the most powerful thing to enable would be just running regex on the rich text. More generally, any text field could potentially be useful here. I could see maybe auto-relating entities based on a URL or specific term or something that exists in the rich text as a more automated way of getting to what I’d be doing, but simply enabling regex would be a big help to avoid having to write custom scripts each time. I could also see maybe some output where it removes all the formatting except for basic text, to simplify any text searches. I haven’t looked to deeply into the recent rules changes, but what often makes it difficult to use is when looping. For example, you might have a regex that extracts all links from the body of an email. You would then have an array of links that you are looping over and potentially creating a new entity related to the email for each one of them.

Now, I could see the argument that if labels/folders came through in a separate type, you could manage the filters within the email client, but I’m not 100% sure that would solve all the needs (wouldn’t solve @v3j’s non-email use case for example) without getting into it more.

Summary

Operations/function to help process email messages:

  1. Regex (most important)
  2. Other string operations
  3. Cleaning
  4. Looping
  5. Auto-Relations
1 Like

Selecting folders to sync sounds like a great long-term solution!

If anyone would like a temporary stop-gap, here’s a script I put together to do stuff based on the body of an e-mail. In this case, it connects the e-mail to another entity based on the first line of the e-mail, but you could adapt it to do more elaborate text processing.

// Developer reference is at api.fibery.io/#action-buttons

// Fibery API is used to retrieve and update entities
const fibery = context.getService('fibery');

// Grab all entities of type idea so that we can choose the matching on later
const all_ideas = await fibery.executeSingleCommand({
    "command": "fibery.entity/query",
    "args": {
        "query": {
            "q/from": "Strategy and Planning/Idea",
            "q/select": {
                "id": "fibery/id",
                "Name": "Strategy and Planning/name",
                "slug": "Strategy and Planning/Slug"
            },
            "q/limit": "q/no-limit"
        }
    }
});

// affected entities are stored in args.currentEntities;
// to support batch actions they always come in an array
for (const entity of args.currentEntities) {
    const message = await fibery.getDocumentContent(entity["Message"]["Secret"]);

    // In my case, T=the first line of the message contains the "slug" to use to associate it with an idea
    // The entire contents of the email is in `message`, though, so you could do whatever you want 
    // with it here
    const slug = message.split("\n")[0].trim();

    // Find the idea with the matching slug
    const idea = all_ideas.find(function (element) { return element["slug"] == slug; });

    // If there is a matching idea, link it to this email.
    if (idea === undefined) { 
    } else {
        // to update an entity provide an object with the new values
        await fibery.updateEntity(entity.type, entity.id, {
            'Idea': idea["id"]
        });
    }
}

2 Likes

Thanks, @rothnic for the script and the comments made it easier for me to understand :slight_smile:

One thing though, if I remove the contents of the description field, it still says Description Exists. Did I miss anything?

Yeah, i realized afterwards that might be an issue. When you delete the contents it doesn’t actually delete the attached document that is now non-null but empty. Here is an updated script to handle that case.

// Developer reference is at api.fibery.io/#action-buttons

// Fibery API is used to retrieve and update entities
const fibery = context.getService('fibery');

// affected entities are stored in args.currentEntities;
// to support batch actions they always come in an array
for (const entity of args.currentEntities) {

    // the rich text field is a document, which requires a special id to get access to
    // In this case, the rich text field is "Description", so we request that field be included
    const entityWithExtraFields = await fibery.getEntityById(entity.type, entity.id, ['Description']);

    // as long as we have the rich text field looking valid, let's do something with it
    if (entityWithExtraFields['Description']) {
        // just saving a shorter reference to it
        const dsc = entityWithExtraFields['Description'];

        // get the rich text field contents as markdown (supports md, html, and json)
        const doc = await fibery.getDocumentContent(dsc.secret, 'md');

        // now we can search the rich text for whatever we are looking for
        // In this case, lets just see if the doc is non-null and non-empty, 
        // then update a checkbox
        const docExists = ((doc !== null) && (doc !== ''));
        await fibery.updateEntity(entity.type, entity.id, {
            'Description Exists': docExists
        });
    }
}

Edit: if you add a console.log(doc) in there just after you get the doc contents, you could see the output in your browser’s dev console, then adjust the logic to handle any special cases. For example, you could look at the length of the document, look for specific terms, etc.

2 Likes

Thank you so much for the updated script! Really appreciate it!!

Regarding the console.log, I’m really not that technical so I’ll study up on that one next :slight_smile: