- Introdução
- Melhores práticas
- Tenant
- Sobre o contexto do tenant
- Pesquisa de recursos em um tenant
- Gerenciamento de robôs
- Conectar Robôs ao Orchestrator
- Armazenamento de credenciais do robô no CyberArk
- Armazenamento de senhas do Unattended Robot no Azure Key Vault (somente leitura)
- Armazenamento de credenciais do Unattended Robot no HashiCorp Vault (somente leitura)
- Armazenando credenciais de Unattended Robots no AWS Secrets Manager (somente leitura)
- Exclusão de sessões não assistidas desconectadas e não responsivas
- Autenticação do robô
- Autenticação de robôs com credenciais de cliente
- Auditar
- Cloud Robots
- Contexto de Pastas
- Automações
- Processos
- Trabalhos
- Apps
- Gatilhos
- Logs
- Monitoramento
- Filas
- Ativos
- Armazenar Buckets
- Test Suite - Orchestrator
- Serviço Catálogo de recursos
- Autenticação
- Integrações
- Robôs Clássicos
- Solução de problemas
Explicação sobre modos de chamada
Os modos de chamada de gatilhos de API são projetados especificamente para criar e seguir execuções de trabalho no Orchestrator.
O desafio fundamental com a comunicação baseada em HTTP é que ela é inerentemente síncrona: normalmente, o cliente envia uma solicitação e aguarda a resposta do servidor. No entanto, no contexto de trabalhos de robôs, manter a conexão aberta até que o trabalho seja concluído não é compatível com o Orchestrator.
Para contornar o problema, usamos o protocolo HTTP para modelar vários modos de chamada. Esses modos dependem de métodos HTTP padrão, códigos de status e cabeçalhos para criar, monitorar e obter o resultado de trabalhos dentro do sistema, sem manter desnecessariamente a conexão aberta. Cada um dos modos de chamada propostos tem vantagens e desvantagens, permitindo que você escolha aquele que é mais adequado para suas necessidades de integração. Tenha em mente que, para garantir uma comunicação segura, cada chamada requer autenticação adequada por meio de tokens de portador.
Problema conhecido
502 Bad Gateway
, causado pela manutenção de um grande número de conexões ativas por intervalos de tempo longos. O trabalho subjacente de tal solicitação pode ter sido executado apesar do erro, então você pode verificar seu estado no Orchestrator.
Esse problema é intermitente e quaisquer solicitações subsequentes funcionarão conforme o esperado.
Esse modo de chamada envolve fazer uma chamada com o verbo HTTP pré-configurado para disparar um novo trabalho e receber um URI de status. O URI de status deve então ser consultado manualmente até que o trabalho seja concluído. Neste ponto, a chamada é redirecionada para outro ponto de extremidade, usado para recuperar o resultado do trabalho (saída ou erro).
Fluxo de trabalho de pesquisa assíncrona em que a conclusão do trabalho depende de chamadas manuais intermediárias para o local de resposta
A chamada inicial é feita usando o verbo HTTP configurado (GET, POST, PUT, DELETE), que cria o trabalho associado no Orchestrator. Após a criação bem-sucedida do trabalho, o sistema responde com um código de status HTTP 202 (Aceito) e um URI de status no cabeçalho Local.
Uma vez que o trabalho seja criado, você deverá consultar periodicamente seu status. Durante esse processo de pesquisa, enquanto o trabalho estiver em execução, cada solicitação GET para o URI de status retorna um código de status HTTP 200 (OK). Quando o trabalho é concluído, a próxima solicitação GET para o URI de status retorna um código de status HTTP 303 (Consulte Outros), redirecionando para o URI de saída (por meio do cabeçalho Local). Espera-se que você siga o URI de saída para recuperar o resultado do trabalho (saída ou erro).
Sempre certifique-se de incluir um token de portador válido no cabeçalho de cada chamada para autenticação bem-sucedida.
Esse exemplo ilustra como iniciar um trabalho por meio de um gatilho de API de um navegador, usando o modo de chamada de pesquisa assíncrona.
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const url = 'https://cloud.uipath.com/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>';
const token = '<PERSONAL_ACCESS_TOKEN>'; // could also be an access token retrieved via OAuth
const body = {
'argument1': 123,
'argument2': 'my string',
'$callMode': 'AsyncRequestReply' // optional argument to force call mode to AsyncRequestReply
}
// if invocation is done by GET, place the parameters in query string and remove the 'Content-Type' header
const invokeRequestOptions = {
method: 'POST',
headers: new Headers({ 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }),
body: JSON.stringify(body),
};
const redirectRequestOptions = {
method: "GET",
credentials: 'same-origin',
headers: new Headers({ Authorization: `Bearer ${token}` }),
redirect: "follow", // this option must be set to follow, otherwise an 'opaqueredirect' response is returned
};
const response = await fetch(url, invokeRequestOptions);
let newLocation = response.headers.get("Location");
// first response should be 202 and have a location header
console.log(`Got ${response.status}, with location: ${newLocation}`);
for (let i = 0; i < 20; i++) {
await sleep(SLEEP_DURATION);
// follow the location header to the new endpoint
const statusResponse = await fetch(newLocation, redirectRequestOptions);
// if the response was redirected (and automatically followed), then the output endpoint has been reached
// the output of the job can be found in the body of the response in JSON format
if (statusResponse.status != 200 || statusResponse.redirected)
{
// read the job output
const output = await statusResponse.json();
console.log(`Got ${statusResponse.status}, with body: ${JSON.stringify(output)}`);
break;
}
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const url = 'https://cloud.uipath.com/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>';
const token = '<PERSONAL_ACCESS_TOKEN>'; // could also be an access token retrieved via OAuth
const body = {
'argument1': 123,
'argument2': 'my string',
'$callMode': 'AsyncRequestReply' // optional argument to force call mode to AsyncRequestReply
}
// if invocation is done by GET, place the parameters in query string and remove the 'Content-Type' header
const invokeRequestOptions = {
method: 'POST',
headers: new Headers({ 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }),
body: JSON.stringify(body),
};
const redirectRequestOptions = {
method: "GET",
credentials: 'same-origin',
headers: new Headers({ Authorization: `Bearer ${token}` }),
redirect: "follow", // this option must be set to follow, otherwise an 'opaqueredirect' response is returned
};
const response = await fetch(url, invokeRequestOptions);
let newLocation = response.headers.get("Location");
// first response should be 202 and have a location header
console.log(`Got ${response.status}, with location: ${newLocation}`);
for (let i = 0; i < 20; i++) {
await sleep(SLEEP_DURATION);
// follow the location header to the new endpoint
const statusResponse = await fetch(newLocation, redirectRequestOptions);
// if the response was redirected (and automatically followed), then the output endpoint has been reached
// the output of the job can be found in the body of the response in JSON format
if (statusResponse.status != 200 || statusResponse.redirected)
{
// read the job output
const output = await statusResponse.json();
console.log(`Got ${statusResponse.status}, with body: ${JSON.stringify(output)}`);
break;
}
Esse exemplo ilustra como iniciar um trabalho por meio de um gatilho de API de um aplicativo baseado em C#, usando o modo de chamada de pesquisa assíncrona.
public async Task<string> AsyncPollingExample()
{
const string url = "https://cloud.uipath.com/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>";
const string token = "<PERSONAL_ACCESS_TOKEN>"; // could also be an access token retrieved via OAuth
// create an http client that does not follow redirects and adds a bearer token on each call
var httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var arguments = new Dictionary<string, object>
{
{ "argument1", 123 },
{ "argument2", "my string" },
{ "$callMode", "AsyncRequestReply" }, // optional argument to force call mode to AsyncRequestReply
};
var httpResponseStart = await httpClient.PostAsJsonAsync(url, arguments);
var redirectUri = httpResponseStart.Headers.Location;
if (httpResponseStart.StatusCode != HttpStatusCode.Accepted)
throw new Exception("Could not invoke workflow");
while (true)
{
var httpPollingResponse = await httpClient.GetAsync(redirectUri);
if (httpPollingResponse.StatusCode == HttpStatusCode.Redirect)
{
var outputLocation = httpPollingResponse.Headers.Location;
var outputResponse = await httpClient.GetAsync(outputLocation);
var jobOutput = await outputResponse.Content.ReadAsStringAsync();
return jobOutput;
}
await Task.Delay(1000);
}
}
public async Task<string> AsyncPollingExample()
{
const string url = "https://cloud.uipath.com/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>";
const string token = "<PERSONAL_ACCESS_TOKEN>"; // could also be an access token retrieved via OAuth
// create an http client that does not follow redirects and adds a bearer token on each call
var httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var arguments = new Dictionary<string, object>
{
{ "argument1", 123 },
{ "argument2", "my string" },
{ "$callMode", "AsyncRequestReply" }, // optional argument to force call mode to AsyncRequestReply
};
var httpResponseStart = await httpClient.PostAsJsonAsync(url, arguments);
var redirectUri = httpResponseStart.Headers.Location;
if (httpResponseStart.StatusCode != HttpStatusCode.Accepted)
throw new Exception("Could not invoke workflow");
while (true)
{
var httpPollingResponse = await httpClient.GetAsync(redirectUri);
if (httpPollingResponse.StatusCode == HttpStatusCode.Redirect)
{
var outputLocation = httpPollingResponse.Headers.Location;
var outputResponse = await httpClient.GetAsync(outputLocation);
var jobOutput = await outputResponse.Content.ReadAsStringAsync();
return jobOutput;
}
await Task.Delay(1000);
}
}
O modo de chamada automático retorna um status de 200 OK na criação bem-sucedida do trabalho, sem quaisquer outras informações sobre o trabalho.
O fluxo de trabalho automático assíncrono em que o trabalho é concluído sem chamadas intermediárias
Esse exemplo ilustra como iniciar um trabalho por meio de um gatilho de API de um navegador, usando o modo de chamada automático assíncrono.
const url = 'https://cloud.uipath.com/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>';
const token = '<PERSONAL_ACCESS_TOKEN>'; // could also be an access token retrieved via OAuth
const body = {
'argument1': 123,
'argument2': 'my string',
'$callMode': 'FireAndForget' // optional argument to force call mode to FireAndForget
}
const options = {
method: 'POST',
headers: new Headers({ 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }),
body: JSON.stringify(body),
};
let response = await fetch(url, options);
console.log(`Got ${response.status}`);
const url = 'https://cloud.uipath.com/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>';
const token = '<PERSONAL_ACCESS_TOKEN>'; // could also be an access token retrieved via OAuth
const body = {
'argument1': 123,
'argument2': 'my string',
'$callMode': 'FireAndForget' // optional argument to force call mode to FireAndForget
}
const options = {
method: 'POST',
headers: new Headers({ 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }),
body: JSON.stringify(body),
};
let response = await fetch(url, options);
console.log(`Got ${response.status}`);
Esse exemplo ilustra como iniciar um trabalho por meio de um gatilho de API de um aplicativo baseado em C#, usando o modo de chamada automático assíncrono.
public async Task FireAndForgetExample()
{
const string url = "https://cloud.uipath.com/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>";
const string token = "<PERSONAL_ACCESS_TOKEN>"; // could also be an access token retrieved via OAuth
// create an http client that does not follow redirects and adds Bearer <token> on each call
// if the follow redirects option is enabled, C# will not add a bearer token by default after the redirect
var httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var arguments = new Dictionary<string, object>
{
{ "argument1", 123 },
{ "argument2", "my string" },
{ "$callMode", "FireAndForget" }, // optional argument to force call mode to LongPolling
};
var response = await httpClient.PostAsJsonAsync(url, arguments);
Console.WriteLine(response.StatusCode);
}
public async Task FireAndForgetExample()
{
const string url = "https://cloud.uipath.com/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>";
const string token = "<PERSONAL_ACCESS_TOKEN>"; // could also be an access token retrieved via OAuth
// create an http client that does not follow redirects and adds Bearer <token> on each call
// if the follow redirects option is enabled, C# will not add a bearer token by default after the redirect
var httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var arguments = new Dictionary<string, object>
{
{ "argument1", 123 },
{ "argument2", "my string" },
{ "$callMode", "FireAndForget" }, // optional argument to force call mode to LongPolling
};
var response = await httpClient.PostAsJsonAsync(url, arguments);
Console.WriteLine(response.StatusCode);
}
Esse modo de chamada envolve uma chamada inicial que bloqueia e aguarda até que o trabalho seja concluído, seguido de várias chamadas de bloqueio e redirecionamentos. Por fim, após a conclusão do trabalho, o resultado do trabalho (saída ou erro) é recuperado.
Dependendo das configurações do tenant, a autenticação pode ser necessária para todas as chamadas ou apenas a chamada inicial.
Fluxo de trabalho síncrono (long-polling), em que o resultado, seja bem-sucedido ou mal-sucedido, é retornado com a chamada inicial
Fluxo de trabalho síncrono (long-polling), em que várias chamadas são feitas automaticamente para a conclusão do trabalho
A chamada inicial é feita usando o verbo HTTP configurado (GET, POST, PUT, DELETE), que cria o trabalho associado no Orchestrator. Após a criação bem-sucedida do trabalho, o sistema bloqueia a chamada atual enquanto aguarda a conclusão do trabalho. Quando o trabalho é concluído, a chamada bloqueada é liberada e uma resposta, incluindo os argumentos de saída do trabalho, é enviada de volta.
Se, após um intervalo de tempo limite, o trabalho ainda não tiver sido concluído, o sistema responderá com um código de status HTTP 303 (Consulte Outros), redirecionando para o URI de status (por meio do cabeçalho Local). Espera-se que você siga o URI de status, que é bloqueado até que o trabalho seja concluído. Se o trabalho não for concluído após um tempo limite, você será novamente redirecionado para o URI de status, criando assim um loop de redirecionamento. Após a conclusão bem-sucedida do trabalho, o resultado do trabalho (saída ou erro) é recuperado como parte da resposta HTTP.
Por padrão, todas as chamadas precisam incluir um token de portador válido para autorização. No entanto, se a opção de configuração do tenant Exigir cabeçalho de autenticação para sincronizar redirecionamentos de gatilhos de API não estiver selecionada, apenas a chamada inicial para o gatilho requer o cabeçalho de autenticação. As chamadas subsequentes para o ponto de extremidade de status podem ser feitas sem um cabeçalho de autorização.
A duração máxima do trabalho para esse modo de chamada é de 15 minutos.
Esse exemplo ilustra como iniciar um trabalho por meio de um gatilho de API de um navegador, usando o modo de chamada síncrono (long-polling).
const url = 'https://cloud.uipath.com/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>';
const token = '<PERSONAL_ACCESS_TOKEN>'; // could also be an access token retrieved via OAuth
const body = {
'argument1': 123,
'argument2': 'my string',
'$callMode': 'LongPolling' // optional argument to force call mode to LongPolling
}
const options = {
method: 'POST',
headers: new Headers({ 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }),
body: JSON.stringify(body),
redirect: "follow", // follow redirects automatically
};
let response = await fetch(url, options);
const output = await response.json();
console.log(`Got ${response.status} with body ${JSON.stringify(output)}`);
const url = 'https://cloud.uipath.com/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>';
const token = '<PERSONAL_ACCESS_TOKEN>'; // could also be an access token retrieved via OAuth
const body = {
'argument1': 123,
'argument2': 'my string',
'$callMode': 'LongPolling' // optional argument to force call mode to LongPolling
}
const options = {
method: 'POST',
headers: new Headers({ 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }),
body: JSON.stringify(body),
redirect: "follow", // follow redirects automatically
};
let response = await fetch(url, options);
const output = await response.json();
console.log(`Got ${response.status} with body ${JSON.stringify(output)}`);
Esse exemplo ilustra como iniciar um trabalho por meio de um gatilho de API de um aplicativo baseado em C#, usando o modo de chamada síncrono (long-polling).
public async Task SyncExample()
{
const string url = "https://cloud.uipath.com/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>";
const string token = "<PERSONAL_ACCESS_TOKEN>"; // could also be an access token retrieved via OAuth
// create an http client that does not follow redirects and adds Bearer <token> on each call
// if the follow redirects option is enabled, C# will not add a bearer token by default after the redirect
var httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var arguments = new Dictionary<string, object>
{
{ "argument1", 123 },
{ "argument2", "my string" },
{ "$callMode", "LongPolling" }, // optional argument to force call mode to LongPolling
};
var response = await httpClient.PostAsJsonAsync(url, arguments);
while(response.StatusCode == HttpStatusCode.Redirect)
{
// in case of redirection, keep following the latest location in the header
var location = response.Headers.Location;
response = await httpClient.GetAsync(location);
}
// read the job output/error from the last request
var jobOutput = response.Content.ReadAsStringAsync();
Console.WriteLine(jobOutput);
}
public async Task SyncExample()
{
const string url = "https://cloud.uipath.com/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>";
const string token = "<PERSONAL_ACCESS_TOKEN>"; // could also be an access token retrieved via OAuth
// create an http client that does not follow redirects and adds Bearer <token> on each call
// if the follow redirects option is enabled, C# will not add a bearer token by default after the redirect
var httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var arguments = new Dictionary<string, object>
{
{ "argument1", 123 },
{ "argument2", "my string" },
{ "$callMode", "LongPolling" }, // optional argument to force call mode to LongPolling
};
var response = await httpClient.PostAsJsonAsync(url, arguments);
while(response.StatusCode == HttpStatusCode.Redirect)
{
// in case of redirection, keep following the latest location in the header
var location = response.Headers.Location;
response = await httpClient.GetAsync(location);
}
// read the job output/error from the last request
var jobOutput = response.Content.ReadAsStringAsync();
Console.WriteLine(jobOutput);
}