Edward - 2024-07-25

Hi everyone,
With the request: Create a trigger template to track tickets with the status "resolved" after a specified time, it will automatically send reminder emails to relevant parties in the Notification -> Trigger configuration.
I want to create a notification about sending reminder email in Notification.
- I tried adding a TriggerOnRemind class in /core/trigger.class.inc.php file

class TriggerOnRemind extends TriggerOnObject
{
    public static function Init()
    {
        $aParams = array
        (
            "category" => "grant_by_profile,core/cmdb,application",
            "key_type" => "autoincrement",
            "name_attcode" => "description",
            "state_attcode" => "",
            "reconc_keys" => array('description'),
            "db_table" => "priv_monitor_trigger",
            "db_key_field" => "id",
            "db_finalclass_field" => "",
        );
        MetaModel::Init_Params($aParams);
        MetaModel::Init_InheritAttributes();
        MetaModel::Init_AddAttribute(new AttributeDuration("date_remind", array("allowed_values"=>null, "sql"=>"date_remind", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));

        MetaModel::Init_SetZListItems('details', array('description', 'date_remind','context', 'target_class', 'filter', 'action_list'));
        MetaModel::Init_SetZListItems('list', array('target_class', 'date_remind'));
        MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class'));

    }
}
  • With field: date_remind is the time entered to send reminder email with condition: resolution_date + date_remind >= NOW()
  • I also added a real time check function in /core/ormstopwatch.class.inc.php
class CheckRemindTrigger implements iBackgroundProcess
{
    public function GetPeriodicity()
    {
        return 600; // 10 minutes in seconds
    }

    public function Process($iTimeLimit)
    {
        $aList = array();
        foreach (MetaModel::GetClasses() as $sClass)
        {
            $sNow = date(AttributeDateTime::GetSQLFormat());

            // Fetch triggers that are due for reminder
            $oTriggerSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnRemind WHERE date_remind != 'NULL'"), array(),array('date_remind' => true));
            $oTriggerSet->OptimizeColumnLoad(array('TriggerOnRemind' => array('date_remind')));
            while ((time() < $iTimeLimit) && ($oTrigger = $oTriggerSet->Fetch()))
            {
                $dateRemindDuration = $oTrigger->Get('date_remind'); 
                $iDateRemindInterval = $this->parseDuration($dateRemindDuration); 
                $sExpression = "SELECT $sClass WHERE status = 'resolved' AND DATE_ADD(resolution_date, INTERVAL :date_remind SECOND) <= :now AND check_remind != 'yes'";
                $oFilter = DBObjectSearch::FromOQL($sExpression);
                $oSet = new DBObjectSet($oFilter, array(), array('date_remind' => $iDateRemindInterval, 'now' => $sNow));
                $oSet->OptimizeColumnLoad(array($sClass => array('status', 'resolution_date')));

                while ((time() < $iTimeLimit) && ($oObj = $oSet->Fetch()))
                {
                    $sClass = get_class($oObj);

                    $aList[] = $sClass.'::'.$oObj->GetKey();

                    // Execute remind actions
                    $this->ExecuteRemindActions($oTrigger, $oObj);

                    // Update last_remind_sent to current time in trigger
                    $oObj->Set('check_remind', 'yes');

                    if ($oTrigger->IsModified())
                    {
                        CMDBObject::SetTrackInfo("Automatic - reminder sent");
                        $oTrigger->DBUpdate();
                    }
                }
            }
        }

        $iProcessed = count($aList);
        return "Processed $iProcessed reminder(s):".implode(", ", $aList);
    }

    // Helper function to parse duration format like 'P3D' to seconds
    private function parseDuration($duration)
    {
        $interval = new DateInterval($duration);
        return ($interval->days * 86400) + ($interval->h * 3600) + ($interval->i * 60) + $interval->s;
    }

    private function ExecuteRemindActions($oTrigger, $oObj)
    {
        $aActions = $oTrigger->Get('actions');
        foreach ($aActions as $aActionData)
        {
            $sVerb = $aActionData['verb'];
            $aParams = $aActionData['params'];
            $aValues = array();
            foreach ($aParams as $def)
            {
                if (is_string($def))
                {
                    $aValues[] = $def;
                }
                else 
                {
                    $sParamType = array_key_exists('type', $def) ? $def['type'] : 'string';
                    switch ($sParamType)
                    {
                        case 'int':
                            $value = (int)$def['value'];
                            break;

                        case 'float':
                            $value = (float)$def['value'];
                            break;

                        case 'bool':
                            $value = (bool)$def['value'];
                            break;

                        case 'reference':
                            $value = ${$def['value']};
                            break;

                        case 'string':
                        default:
                            $value = (string)$def['value'];
                    }
                    $aValues[] = $value;
                }
            }
            $aCallSpec = array($oObj, $sVerb);
            call_user_func_array($aCallSpec, $aValues);
        }
    }
}

I saw the CheckRemindTrigger running under the hood but it didn't send the email with the notification config I set up.
Please help me check and fix this! Thanks a lot.

 

Last edit: Edward 2024-07-25