Chamadas GET/POST com o ScadaBR 1.2


#1

Neste tutorial veremos como fazer chamadas HTTP GET ou POST utilizando os recursos de script do ScadaBR 1.2 (scripting, data point meta, etc). Este tipo de chamada pode ser utilizado para, por exemplo, enviar mensagens através da API do Telegram e de outros softwares.

Ainda não está usando o ScadaBR 1.2? Está esperando o que? Baixe já!

Funcionamento dos scripts no ScadaBR

O ScadaBR é um software construído, em seu núcleo, utilizando a linguagem Java. Entretanto, alguns recursos como o data point meta e a página de Scripting utilizam-se de um sistema de programação via scripts Javascript.

Sim, até os nomes Java e Javascript são parecidos, mas trata-se de duas linguagens diferentes. Então, como é que um programa escrito em Java pode executar código escrito em outra linguagem (Javascript)? É aí que entra uma biblioteca chamada Rhino, que é responsável por interpretar o código Javascript e converter para instruções que possam ser executadas pela Máquina Java.

Assim, os scripts do ScadaBR utilizam a sintaxe definida pela Rhino, que é uma espécie de híbrido entre Javascript e Java. Você pode escrever a maioria das instruções utilizando uma sintaxe normal de Javascript, mas existe a possibilidade de acessar e instanciar classes Java como se fossem objetos Javascript. Essa é uma parte mais técnica e complexa, então, não entrarei em detalhes aqui para não perder o foco do tutorial.

O mais importante a entender agora é que, como a Rhino é executada no lado do servidor (server side), você não terá acesso a algumas coisas que são implementadas apenas no lado do cliente, pelo DOM do navegador. Entre elas estão os objetos XMLHttpRequest, o que nos obriga a realizar chamadas GET/POST por outros métodos.

Chamadas GET e POST

Uma vez que não temos como utilizar XMLHttpRequest, utilizaremos a biblioteca Apache HttpClient, que já vem incluída no ScadaBR 1.2. Para facilitar, eu já criei duas funções que fazem esse processo automaticamente. Então, para implementar chamadas GET ou POST no ScadaBR 1.2, basta copiar no seu script a função simpleGet(URL, parameters) ou simplePost(URL, parameters). O código de ambas está logo abaixo.

Para invocar essas funções no seu script, a sintaxe é bastante simples. Você deve fornecer um parâmetro URL com uma string contendo a URL do site a ser requisitado. Além disso, para especificar quais parâmetros serão incluídos na requisição, você pode criar um array contendo objetos. Cada objeto desse array representa um parâmetro da sua requisição GET/POST e deve incluir uma entrada key, contendo o parâmetro requisitado, e uma entrada value, contendo seu respectivo valor.

Por exemplo, se quiséssemos fazer uma chamada GET para o site httbin.org/get passando como parâmetros name=ScadaBR e tutorial=GET, poderíamos escrever o código assim:

   // Definindo os parâmetros da requisição
   var params = [ { key: "name", value: "ScadaBR" }, { key: "tutorial", value: "GET" } ];

   // Salvar resposta num objeto
   var obj = simpleGet("httbin.org/get", params);

Como você pode ter observado, as funções simpleGet() e simplePost() retornam um objeto. Este objeto pode ser utilizado para recuperar dados no seu código e possui as seguintes propriedades:

   // Salvar resposta num objeto
   var obj = simpleGet("httbin.org/get", params);

   // Para acessar o código da requisição HTTP, use .status
   obj.status; // Valor numérico

   // Para acessar a resposta do servidor, use .response
   obj.response; // String. Cuidado: pode conter null!

   // Para acessar mensagens de erro (se houver), use .errors
   obj.errors; // String. Cuidado: pode conter null!

Uma lógica simples para testar se a requisição deu certo poderia ser assim:

    // Salvar resposta num objeto
    var obj = simpleGet("httbin.org/get", params);

    // Verificar se o status é OK (200)
    if (obj.status == 200) {
        // Pegar resposta
        return obj.response;
    } else {
        // Pegar mensagens de erro
        return obj.errors;
    }
Código da função simpleGet()

Copie o seguinte código para implementar a função simpleGet() e fazer chamadas GET nos seus scripts:

function simpleGet(url, parameters) {
 
    var respStatus = null;
    var respString = null;
    var respErrors = null;

    // Add parameters to the GET Url
    var getUrl = url.replace(/\/$/, "") + "?";
    for (var i in parameters) {
        var paramKey = encodeURIComponent(parameters[i].key);
        var paramValue = encodeURIComponent(parameters[i].value);
        getUrl += paramKey + "=" + paramValue + "&";
    }

    // Java classes to import
    var imports =  JavaImporter(org.apache.commons.httpclient.HttpClient,
          org.apache.commons.httpclient.methods.GetMethod,
          org.apache.commons.httpclient.DefaultHttpMethodRetryHandler,
          org.apache.commons.httpclient.params.HttpMethodParams
        );

    // Use Rhino's "with" feature
    with (imports) {
        var client = new HttpClient();

        // Create a method instance.
        var method = new GetMethod(getUrl);

        // Provide custom retry handler is necessary
        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, 
        new DefaultHttpMethodRetryHandler(3, false));

        try {
            // Execute the method.
            var statusCode = client.executeMethod(method);
            // Save the HTTP status to the response
            respStatus = statusCode;

            if (statusCode != 200) {
                // Add error messages to the response
                respErrors = "Method failed: " + String(method.getStatusLine());
            } else {
                // Read the response body.
                var responseBody = method.getResponseBodyAsString();

                // Deal with the response.
                // Use caution: ensure correct character encoding and is not binary data
                respString = String(responseBody);
            }

        } catch (e) {
            // Add error messages to the response
            respErrors = "Error occurred: " + String(e);
        } finally {
            // Release the connection.
            method.releaseConnection();
        }
    }

    // Return a Javascript object with the response data
    return { status: respStatus, response: respString, errors: respErrors };
}

Código da função simplePost()

Copie o seguinte código para implementar a função simplePost() e fazer chamadas POST nos seus scripts:

function simplePost(url, parameters) {
 
    var respStatus = null;
    var respString = null;
    var respErrors = null;

    // Java classes to import
    var imports =  JavaImporter(org.apache.commons.httpclient.HttpClient,
          org.apache.commons.httpclient.methods.PostMethod,
          org.apache.commons.httpclient.NameValuePair,
          org.apache.commons.httpclient.DefaultHttpMethodRetryHandler,
          org.apache.commons.httpclient.params.HttpMethodParams
        );
 
    // Use Rhino's "with" feature
    with (imports) {
        var client = new HttpClient();

        // Create a method instance.
        var method = new PostMethod(url);
      
        // Add parameters to the POST request
        var getUrl = url + "?";
        for (var i in parameters) {
            var paramKey = parameters[i].key;
            var paramValue = parameters[i].value;
            method.addParameter(paramKey, paramValue);
        }
      
        // Provide custom retry handler is necessary
        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, 
            new DefaultHttpMethodRetryHandler(3, false));

        try {
            // Execute the method.
            var statusCode = client.executeMethod(method);
            // Save the HTTP status to the response
            respStatus = statusCode;
       
            if (statusCode != 200) {
                // Add error messages to the response
                respErrors = "Method failed: " + String(method.getStatusLine());
            } else {
                // Read the response body.
                var responseBody = method.getResponseBodyAsString();

                // Deal with the response.
                // Use caution: ensure correct character encoding and is not binary data
                respString = String(responseBody);
        }

        } catch (e) {
            // Add error messages to the response
            respErrors = "Error occurred: " + String(e);
        } finally {
            // Release the connection.
            method.releaseConnection();
        }
    }

    // Return a Javascript object with the response data
    return { status: respStatus, response: respString, errors: respErrors };
}

Tutorial em vídeo

Se dizem que uma imagem vale mais do que mil palavras, então um vídeo deve ter um valor ainda maior. Para finalizar deixarei aqui um excelente tutorial feito pelo Fernando José, da empresa Branqs, em que ele ensina como utilizar essas funções para integrar o ScadaBR ao Telegram. E de quebra você ainda pode aprender a criar uma instância do ScadaBR no Linux!


Puxar dados de uma api
#2

great work , working perfectly, god bless you Celsus and Fernando Jose.
Celsus could you be so kind and make an example for massaging to multi telegram users.
many thanks in advance.


#3

Unfortunately I don’t often use the Telegram API to show you how to do this. But I think it’s possible to add a bot to a group and configure the bot to send the messages to the group chat.

Greetings,
Celso.