Create a custom trigger (Example 2)

The example shows how to create a trigger in Automation 360 that allows you to create tasks that will be executed at specified intervals.

A trigger launches a bot when certain conditions are met and waits until conditions have changed or stopped. When the conditions of the trigger are matched, the run method is called to signal the trigger.

Required annotations

For creating a trigger, the following annotations are required:

Annotation Usage
BotCommand Use the BotCommand annotation with the trigger as commandType. This ensures that the plain old Java object (POJO) is suitable for creating the trigger with Automation 360.
CommandPkg These values are used when creating a package. Provide a name, label, and description to the annotation.
TriggerId A trigger ID, which is required for stopping the trigger.

TriggerConsumer

Specifies the consumer function to be invoked when the trigger condition is met.
StartListen Starts the trigger listener.
StopAllTriggers Identifies the method used to cancel all triggers.
StopListen Identifies the method responsible for canceling a specific trigger..

Use case - Timer Trigger

The following use case shows how to create a timer trigger that triggers a bot at regular intervals. The Demo Trigger command sample explained here is a trigger command that allows you to create and manage triggers based on user-specified intervals. This trigger can be used to execute tasks at regular intervals.

Command Information
@BotCommand(commandType = BotCommand.CommandType.Trigger)
@CommandPkg(label = "Demo Trigger", description = "Demo Trigger", icon = "email.svg", name = "demoTrigger",
      return_type = RECORD, return_name = "TriggerData", return_description = "Available keys: triggerType")
  • Command Type: Trigger
  • Label: Demo Trigger
  • Description: Demo Trigger
  • Icon: email.svg
  • Name: demoTrigger
  • Return Type: RECORD
  • Return Name: TriggerData
  • Return Description: Available keys: triggerType
Class Structure

The TriggerDemo class is a singleton class that manages the trigger tasks. It stores the tasks in a map using the triggerId as the key. Once the trigger condition is met, the run method of the associated Runnable is called to signal the trigger.

Class Variables
  • taskMap: A static ConcurrentHashMap that stores multiple trigger tasks.
  • TIMER: A static Timer used for scheduling the trigger tasks.
  • triggerUid: Annotated with @TriggerId, it represents the unique identifier for the trigger.
  • consumer: Annotated with @TriggerConsumer, it is the consumer that will accept the trigger data.
Methods
  • startTrigger: Annotated with @StartListen, this method starts the trigger. It takes an interval parameter (in seconds) to specify the trigger activation interval. It creates a new TimerTask> that calls the run method of the associated Runnable when executed. The TimerTask is added to the taskMap with the triggerUid as the key, and it is scheduled to run at the specified interval.
  • getRecordValue: A private method that creates and returns a RecordValue containing the trigger data. The trigger data includes a schema with a single key "triggerType" and its corresponding value "Interval Trigger".
  • stopAllTriggers: Annotated with @StopAllTriggers, this method cancels all trigger tasks and clears the taskMap.
  • stopListen: Annotated with @StopListen, this method cancels a specific trigger task identified by the triggerUid parameter and removes it from the taskMap.
  • Setter methods: setTriggerUid and setConsumer are setter methods for the triggerUid and consumer variables, respectively.
/*
 * Copyright (c) 2023 Automation Anywhere.
 * All rights reserved.
 *
 * This software is the proprietary information of Automation Anywhere.
 * You shall use it only in accordance with the terms of the license agreement
 * you entered into with Automation Anywhere.
 */

/**
 * 
 */
package com.automationanywhere.botcommand.samples.trigger;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

import com.automationanywhere.botcommand.data.Value;
import com.automationanywhere.botcommand.data.impl.RecordValue;
import com.automationanywhere.botcommand.data.impl.StringValue;
import com.automationanywhere.botcommand.data.model.Schema;
import com.automationanywhere.botcommand.data.model.record.Record;
import com.automationanywhere.commandsdk.annotations.*;
import com.automationanywhere.commandsdk.annotations.rules.GreaterThan;
import com.automationanywhere.commandsdk.annotations.rules.NotEmpty;
import com.automationanywhere.commandsdk.annotations.rules.NumberInteger;
import com.automationanywhere.commandsdk.model.AttributeType;
import com.automationanywhere.commandsdk.model.DataType;

import static com.automationanywhere.commandsdk.model.DataType.RECORD;

/**
 * There will be a singleton instance of this class. Whenever a new trigger is
 * created it comes with a triggerId. In this sample we create multiple tasks
 * and store them in a map with these triggerId as the key. Once the condition
 * of trigger matches we call the run method of the runnable to signal the
 * trigger.
 * In the following example we will create a trigger which triggers are user
 * specified intervals.
 *
 */
@BotCommand(commandType = BotCommand.CommandType.Trigger)
@CommandPkg(label = "Demo Trigger", description = "Demo Trigger", icon = "email.svg", name = "demoTrigger",
		return_type = RECORD, return_name = "TriggerData", return_description = "Available keys: triggerType")
public class TriggerDemo {

	// Map storing multiple tasks
	private static final Map<String, TimerTask> taskMap = new ConcurrentHashMap<>();
	private static final Timer TIMER = new Timer(true);

	@TriggerId
	private String triggerUid;
	@TriggerConsumer
	private Consumer consumer;

	/*
	 * Starts the trigger.
	 */
	@StartListen
	public void startTrigger(@Idx(index = "1", type = AttributeType.NUMBER)
	@Pkg(label = "Please provide the interval to trigger in seconds", default_value = "120", default_value_type = DataType.NUMBER)
	@GreaterThan("0")
	@NumberInteger
	@NotEmpty
	Double interval) {
		TimerTask timerTask = new TimerTask() {

			@Override
			public void run() {
				consumer.accept(getRecordValue());
			}
		};

		taskMap.put(this.triggerUid, timerTask);
		TIMER.schedule(timerTask, interval.longValue());
	}

	private RecordValue getRecordValue() {
		List<Schema> schemas = new LinkedList<>();
		List<Value> values = new LinkedList<>();
		schemas.add(new Schema("triggerType"));
		values.add(new StringValue("Interval Trigger"));

		RecordValue recordValue = new RecordValue();
		recordValue.set(new Record(schemas,values));
		return recordValue;
	}

	/*
	 * Cancel all the task and clear the map.
	 */
	@StopAllTriggers
	public void stopAllTriggers() {
		taskMap.forEach((k, v) ->  {
			if (v.cancel()) {
				taskMap.remove(k);
			}
		});
	}

	/*
	 * Cancel the task and remove from map
	 *
	 * @param triggerUid
	 */
	@StopListen
	public void stopListen(String triggerUid) {
		if (taskMap.get(triggerUid).cancel()) {
			taskMap.remove(triggerUid);
		}
	}

	public void setTriggerUid(String triggerUid) {
		this.triggerUid = triggerUid;
	}

	public void setConsumer(Consumer consumer) {
		this.consumer = consumer;
	}

}
Example
Here's an example of using the Demo Trigger
demoTrigger.startTrigger(60.0);

This will start a trigger that runs every 60 seconds and calls the associated consumer with the trigger data.

To stop the trigger, you can use the following methods:

  • demoTrigger.stopAllTriggers(): This method will stop all active triggers.
  • demoTrigger.stopListen(triggerUid): This method will stop a specific trigger identified by the triggerUid.
    Note: The triggerUid is a unique identifier for each trigger and is assigned automatically when a trigger is created.