Crie um gatilho personalizado (Exemplo 1)

O Pacote SDK fornece ferramentas para criar um gatilho personalizado que automatiza ações com base em condições predefinidas.

Nesta seção, você aprenderá a criar um gatilho de intervalo usando o Pacote SDK do Automation Anywhere. Uma classe de amostra chamada TriggerDemo é usada para explicar sua funcionalidade passo a passo. Ao final, você terá uma sólida compreensão de como criar seus próprios acionadores personalizados usando o Pacote SDK:

Procedimento

  1. Dependências e pacote: O exemplo de código utiliza várias importações e está organizado no pacote com.automationanywhere.botcommand.samples.trigger.
  2. Anotações: O código utiliza várias anotações fornecidas pelo Pacote SDK para definir e configurar o gatilho. Essas anotações incluem:
    1. @BotCommand: Especifica que essa classe representa um gatilho. É especificado com a linha @BotCommand(commandType = BotCommand.CommandType.Trigger) . Quando você especifica que se trata de um Trigger do tipo comando, ele fica visível na seção Gatilho no editor de bot.
    2. @CommandPkg: Fornece metadados sobre o gatilho, como rótulo, descrição, ícone e tipo de retorno. O tipo de retorno é sempre definido como REGISTRO, conforme mostrado no exemplo a seguir.
    3. @TriggerId: Indica o identificador exclusivo atribuído a cada instância do gatilho.
    4. @TriggerConsumer: Especifica a função do consumidor a ser invocada quando a condição do gatilho for atendida.
    5. @StartListen: Marca o método responsável por iniciar o gatilho.
      Dica: @StartListen é usado para executar um gatilho e é análogo a @Execute no caso de um bot.
    6. @StopAllTriggers: Identifica o método usado para cancelar todos os gatilhos.
    7. @StopListen: Identifica o método responsável pelo cancelamento de um gatilho específico.
  3. Execução do gatilho: A lógica de execução do gatilho é implementada no método startTrigger usando a anotação @StartListen. Neste exemplo, um TimerTask está programado para ser executado em intervalos regulares definidos pelo usuário. Quando o horário programado é atingido, o método run do TimerTask é executado, acionando o consumer.accept. O consumidor aceita o RecordValue retornado pelo método getRecordValue .
    Dica: RecordValue também está disponível para uso na lógica de bot.
  4. Método getRecordValue : O método getRecordValue cria um objeto RecordValue e o preenche com uma lista de esquemas e valores. Nesse exemplo, o esquema triggerType é adicionado com o valor correspondente Gatilho de intervalo.
  5. Métodos StopListen e StopAllTriggers : Esses métodos são anotados com @StopListen e @StopAllTriggers, respectivamente. Eles são responsáveis por cancelar a(s) tarefa(s) de acionamento e removê-la(s) do mapa de tarefas.
  6. Métodos auxiliares adicionais: O código também inclui métodos getter e setter para as variáveis triggerUid e consumer .
package com.automationanywhere.botcommand.samples.trigger;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

import javax.sql.DataSource;

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.botcommand.samples.exceptions.DemoException;
import com.automationanywhere.commandsdk.annotations.*;
import org.apache.commons.dbcp2.BasicDataSource;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.automationanywhere.botcommand.exception.BotCommandException;
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 com.automationanywhere.core.security.SecureString;

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

/**
 * This example is an extension of the timer based trigger {@link TriggerDemo} and demonstrates the
 * pull mechanism.
 * Trigger will check the DB at regular interval and if the records returned by
 * user provided SQL is more than 0 then it will get triggered.
 * NOTE 1: This class is for illustrative purpose only not safe for use in production.
 * NOTE 2: Please add the valid DB driver in build gradle to run this example.
 * 
 */
@BotCommand(commandType = BotCommand.CommandType.Trigger)
@CommandPkg(label = "JDBC Query Trigger", description = "JDBC Query Trigger", icon = "jdbc.svg", name = "jdbcQueryTrigger",
		return_type = RECORD, return_name = "TriggerData", return_description = "Available keys: triggerType")
public class DBStatus {
	
	private static Logger logger = LogManager.getLogger(DBStatus.class);
	
	
	// 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.TEXT)
			@Pkg(label = "Please provide the database driver class")
			@NotEmpty
			String driverClassName,
			
			@Idx(index="2", type = AttributeType.TEXT)
			@Pkg(label = "Please provide the Jdbc connection string")
			@NotEmpty
			String jdbcUrl,
			
			@Idx(index="3", type = AttributeType.TEXT)
			@Pkg(label = "Please provide the user Name")
			@NotEmpty
			String userName,
			
			@Idx(index="4", type = AttributeType.CREDENTIAL)
			@Pkg(label = "Please provide the password")
			@NotEmpty
			SecureString password,
			
			@Idx(index="5", type = AttributeType.TEXT)
			@Pkg(label = "Please provide the SQL to check the records")
			@NotEmpty
			String sqlQuery,
			
			@Idx(index = "6", type = AttributeType.NUMBER)
			@Pkg(label = "Please provide the interval to query in seconds", default_value = "300", default_value_type = DataType.NUMBER)
			@GreaterThan("0")
			@NumberInteger
			@NotEmpty
			Double interval) {
		
		DataSource dataSource = getDataSource(driverClassName, jdbcUrl, userName, password);
		
		TimerTask timerTask = new TimerTask() {

			@Override
			public void run() {
				logger.debug("checking DB");
				try {
					if(checkRecordsExist(dataSource.getConnection(), sqlQuery)){
						consumer.accept(getRecordValue());
						return;
					}
				} catch (SQLException e) {
					logger.warn(e.getMessage(),e);
					logger.warn("Trigger is still running.");
				}
				logger.debug("no records found");

			}
		};

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

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

		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 static DataSource getDataSource(String driverClassName, String url, String userName,SecureString password) {
    	BasicDataSource ds = new BasicDataSource();
    	ds.setDriverClassName(driverClassName);
    	ds.setUrl(url);
    	ds.setUsername(userName);
    	ds.setPassword(password.getInsecureString());
        return ds;
    }
	
    public static boolean checkRecordsExist(Connection con, String query)
    	    throws SQLException {
			
    	    Statement stmt = null;
    	    try {
    	        stmt = con.createStatement();
    	        ResultSet rs = stmt.executeQuery(query);
    	        rs.last();
    	        if(rs.getRow() > 0)
    	        	return true;
    	    } catch (SQLException e ) {
    	        throw new DemoException("Problem running statemnt", e);
    	    } finally {
    	        if (stmt != null) { stmt.close(); }
    	    }
    	    
    	    return false;
    	}
    
	public String getTriggerUid() {
		return triggerUid;
	}

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

	public Consumer getConsumer() {
		return consumer;
	}

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

Próximas etapas

O exemplo de código acima descreve os vários métodos e anotações usados para criar e gerenciar o gatilho. Ao compreender o código e sua funcionalidade, você agora está preparado para criar seus próprios gatilhos de intervalo usando o Pacote SDK. Faça experiências com diferentes intervalos e acione ações para automatizar os processos de negócios de forma eficaz.

O artigo acima é apenas um exemplo. Você precisa refiná-lo e personalizá-lo ainda mais com base em seus requisitos específicos e no público-alvo.