Overview

The field tag skill is written to display information using colored tags, on various fields in PrecisionLender. This skill template will help you write field tag skills in PrecisionLender. You can modify the code in the template or use it as a reference when writing your skill.  This article will walk through the field tag skill template.

 

In this Article

 

Run

This is the main execution of the skill which is called after the Andi skills platform determines whether or not the skill should run.

export async function run(skillContext: ISkillContext) : Promise<ISkillActivity> {

This uses the getSkillRunState power to get the loanAmount set in the shouldIRun.

const loanAmount: number = await skillContext.getSkillRunState("loanAmount");

Builds and sends a field tag with information for the user.

const fieldTag: FieldTag = {
        fields: ["amount"],
        text: skillContext.skillConfig.fieldTagMessage,
        tagType: FieldTagTypes.Info,
        key: "uniqueTemplateKey",

This states that Andi should only load this field tag if the amount hasn't changed.

loadWhen: [{
            query: { name: "getRawAmount", args: [] },
            comparator: "==",
            value: loanAmount,
            type: "number"
        }]
    };
    return TagPowers.sendTags([fieldTag]);
}

 

In total, the run code is as follows:

import { FieldTag, TagPowers } from "@andi/powers";
import { FieldTagTypes, ISkillContext, ISkillActivity } from "andiskills";

// this is main execution of the skill which is called after the andi
// skills platforms determines if it should run
export async function run(skillContext: ISkillContext) : Promise<ISkillActivity> {
    const loanAmount: number = await skillContext.getSkillRunState("loanAmount");

    const fieldTag: FieldTag = {
        fields: ["amount"],
        text: skillContext.skillConfig.fieldTagMessage,
        tagType: FieldTagTypes.Info,
        key: "uniqueTemplateKey",
        //Andi should only load this field tag if the amount hasn't changed 
        loadWhen: [{
            query: { name: "getRawAmount", args: [] },
            comparator: "==",
            value: loanAmount,
            type: "number"
        }]
    };

    return TagPowers.sendTags([fieldTag]);
}

 

Should I Run

The shouldIRun is used by the Andi skills platform to determine if the given skill's current context needs to be executed.

export async function shouldIRun(skillContext: ISkillContext): Promise<ShouldIRunResponseType> {

Uses the isLoanAccountChangeEvent to determine if the event type coming into the skill is a Loan Account Change Event.

const isLoanAccountChangeEvent: boolean = skillContext.powers.precisionLender.opportunity.isLoanAccountChangeEvent();
    if (!isLoanAccountChangeEvent) {
        return skillContext.powers.andi.shouldIRun.shouldIRunFalse();
    }
    validateConfiguration(skillContext);

Uses the getApplicationEvent power to get event data.

 const event = skillContext.powers.andi.event.getApplicationEvent(skillContext);
    const data = event.applicationEventData;

Iterates through the commercial loan accounts attached to the event data to find the one relevant to this skill.

const cla: CommercialLoanAccount = data.engineModel.commercialLoanAccounts.find((cla) => {
        return cla.id === data.contextId;
    });

Tells Andi not to send the field tag if the loan amount is less than the threshold.

if (cla.amount < skillContext.skillConfig.loanAmountThreshold) {
        return skillContext.powers.andi.shouldIRun.shouldIRunFalse();
    }

Uses the setSkillRunState power to add a new key/value pair to the skill run state that can be accessed later.

await skillContext.setSkillRunState("loanAmount", cla.amount);

Tells Andi to run the skill by returning the value from shouldIRunTrue power.

return skillContext.powers.andi.shouldIRun.shouldIRunTrue();
}
function validateConfiguration(skillContext: ISkillContext) {
    if (!skillContext.skillConfig) {
        throw new Error("Skill has not been configured.");
    }
    if (!skillContext.skillConfig.loanAmountThreshold) {
        throw new Error("Loan Amount Threshold is a required configuration value.");
    }
    if (!skillContext.skillConfig.fieldTagMessage) {
        throw new Error("Field Tag Message is a required configuration value.");
    }
}

 

In total, the shouldIRun code is as follows:

import { ISkillContext, ShouldIRunResponseType } from "andiskills";
import { CommercialLoanAccount } from "andiexternal";

// shouldIRun is used by the andi skills platform to determine if the given
// skill's current context needs to be executed. 
export async function shouldIRun(skillContext: ISkillContext): Promise<ShouldIRunResponseType> {
    const isLoanAccountChangeEvent: boolean = skillContext.powers.precisionLender.opportunity.isLoanAccountChangeEvent();

    if (!isLoanAccountChangeEvent) {
        return skillContext.powers.andi.shouldIRun.shouldIRunFalse();
    }

    validateConfiguration(skillContext);
    
    const event = skillContext.powers.andi.event.getApplicationEvent(skillContext);
    const data = event.applicationEventData;

    const cla: CommercialLoanAccount = data.engineModel.commercialLoanAccounts.find((cla) => {
        return cla.id === data.contextId;
    });

    // Do not send the field tag if the loan amount is less than the threshold
    if (cla.amount < skillContext.skillConfig.loanAmountThreshold) {
        return skillContext.powers.andi.shouldIRun.shouldIRunFalse();
    }

    await skillContext.setSkillRunState("loanAmount", cla.amount);
    
    return skillContext.powers.andi.shouldIRun.shouldIRunTrue();
}

function validateConfiguration(skillContext: ISkillContext) {
    if (!skillContext.skillConfig) {
        throw new Error("Skill has not been configured.");
    }

    if (!skillContext.skillConfig.loanAmountThreshold) {
        throw new Error("Loan Amount Threshold is a required configuration value.");
    }

    if (!skillContext.skillConfig.fieldTagMessage) {
        throw new Error("Field Tag Message is a required configuration value.");
    }
}

 

Was this article helpful?
0 out of 0 found this helpful