- Introdução
- Melhores práticas
- Tenant
- Contexto de Pastas
- Automações
- Processos
- Trabalhos
- Gatilhos
- Logs
- Monitoramento
- Filas
- Ativos
- Armazenar Buckets
- Test Suite - Orchestrator
- Outras configurações
- Integrações
- Robôs Clássicos
- Administração do host
- Sobre o nível do host
- Gerenciamento dos administradores do sistema
- Gerenciando Tenants
- Configurando notificações de e-mail do sistema
- Logs de auditoria para o portal do host
- Modo de Manutenção
- Administração da organização
- Solução de problemas
Webhooks
Webhooks permitem a você integrar melhor sua automação da UiPath com todo o seu ecossistema do aplicativo. Você pode inscrever-se em eventos do Orchestrator e enviá-los para qualquer solução externa DCM, BMP ou CRM e informar diferentes usuários, por exemplo, que há um novo item enfileirado que pode ser processado, que um disparador falhou ou que um processo foi atualizado.
Webhooks permitem que sistemas externos se inscrevam e escutem a diferentes tipos de eventos do Orchestrator. A página Webhooks permite que você os configure com facilidade e veja os que foram criados anteriormente. Você também pode desabilitar webhooks, pesquisar um webhook específico, editá-los ou excluí-los.
Os eventos estão disponíveis para trabalhos, robôs, filas, itens de fila, processos e gatilhos.
Cada evento envia uma carga para uma URL especificada que contém informações. Algumas propriedades são comuns para todos, enquanto outras são específicas para cada tipo de evento.
Os eventos do Webhook são criados por pasta, portanto, se você tiver um evento de webhook associado a um recurso compartilhado entre pastas, como uma fila, é gerado um evento de webhook separado para cada uma dessas pastas.
Se a solicitação para encaminhar um evento falhar, o disjuntor para esse webhook específico é acionado, desabilitando o webhook por uma hora.
- Quaisquer eventos de webhook que deveriam ter sido enviados enquanto o disjuntor está aberto são ignorados e não repetidos quando o disjuntor fecha.
- Os eventos do Webhook não são armazenados e não podem ser repetidos ou exportados. Além disso, se a chamada para a plataforma externa falhar, o evento se perde. Os webhooks são projetados para processamento em tempo real.
Nome da Propriedade |
Tipo de propriedade |
Descrição e exemplo |
---|---|---|
Tipo |
String |
O tipo de evento que disparou a notificação. Esta propriedade é exibida para todos os tipos de eventos. Exemplo:
|
ID do Evento |
String |
Um identificador gerado exclusivamente para cada evento quando ele ocorreu. Esta propriedade é exibida para todos os tipos de eventos. Exemplo:
|
Carimbo de data/hora |
Data RFC 8601 |
A data e hora em que o evento foi gerado. Esta propriedade é exibida para todos os tipos de eventos. Exemplo:
|
TenantId |
Número inteiro |
A ID do tenant no qual o evento foi gerado. O tenant padrão é 1. Esta propriedade é exibida para todos os tipos de eventos. Exemplo:
|
ID do Usuário |
Número inteiro |
A ID do usuário cuja ação disparou o evento. Este parâmetro não é exibido se o evento for disparado por um Robô ou um gatilho. Esta propriedade é exibida para todos os tipos de eventos. Exemplo:
|
FolderID |
Número inteiro |
A ID da pasta na qual o evento foi gerado. Este parâmetro não é exibido para eventos disparados por robôs modernos. Exemplo:
|
Para executar várias operações na página Webhooks, você precisa receber as permissões correspondentes em webhooks:
- Exibição — Permite que você visualize os webhooks e seus detalhes, bem como os recupere usando a API, envie uma solicitação de ping, ou obtenha a lista de todos os eventos aos quais um webhook pode se inscrever.
- Criar - esta permissão permite que você adicione novos webhooks. Observe que você também precisa de permissões de Exibir.
- Editar — concede o direito de editar webhooks a partir da interface gráfica ou usando a API. Observe que você também precisa de permissões de Exibir.
- Excluir - uma permissão que permite que você exclua webhooks. Observe que você também precisa de permissões de Exibir.
X-UiPath-Signature
.
Os aplicativos clientes que recebem solicitações do Orchestrator devem verificar a autenticidade das solicitações. A assinatura da solicitação segue o seguinte padrão:
- O aplicativo cliente recebe uma solicitação de webhook do Orchestrator;
- O aplicativo cliente processa uma assinatura com base na solicitação;
-
O aplicativo cliente tenta combinar a assinatura processada com a assinatura da solicitação:
- Se as assinaturas não corresponderem, o aplicativo cliente não deverá processar a solicitação.
- Se as assinaturas corresponderem, o aplicativo cliente deverá processar a solicitação.
O processamento da assinatura deve ser feito da seguinte forma:
- Recupere o cabeçalho HTTP
X-UiPath-Signature
. - Para obter os bytes de assinatura bruta, decodifique o valor do cabeçalho da Base64.
-
Recupere o corpo da solicitação bruta.
Observação: As solicitações no Orchestrator são sempre codificadas usando UTF-8. - Processe o hash usando SHA256 e a chave de assinatura (com codificação UTF-8).
-
Compare a assinatura calculada com o valor do cabeçalho HTTP
X-UiPath-Signature
:- Se não houver correspondência entre as assinaturas, não processar a solicitação.
- Se as assinaturas corresponderem, o aplicativo cliente deverá processar a solicitação.
using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
public async Task<bool> IsValidRequestAsync(HttpRequestMessage request, string secret)
{
if (!request.Headers.TryGetValues("X-UiPath-Signature", out var headerValues))
return false;
var orchestratorSignature = Convert.FromBase64String(headerValues.First());
using (var sha = new HMACSHA256(key: Encoding.UTF8.GetBytes(secret)))
{
var computedSignature = sha.ComputeHash(await request.Content.ReadAsByteArrayAsync());
return ByteArrayEquals(orchestratorSignature, computedSignature);
}
}
using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
public async Task<bool> IsValidRequestAsync(HttpRequestMessage request, string secret)
{
if (!request.Headers.TryGetValues("X-UiPath-Signature", out var headerValues))
return false;
var orchestratorSignature = Convert.FromBase64String(headerValues.First());
using (var sha = new HMACSHA256(key: Encoding.UTF8.GetBytes(secret)))
{
var computedSignature = sha.ComputeHash(await request.Content.ReadAsByteArrayAsync());
return ByteArrayEquals(orchestratorSignature, computedSignature);
}
}
const { createServer } = require('http');
const { createHmac } = require('crypto');
const PORT = 9090
const WEBHOOK_SECRET = '<same secret as configured in Orchestrator>'
const isValidRequest = (body /* Buffer */, secret /* string */, expectedSignature /* string */) =>
expectedSignature == null || createHmac('sha256', secret)
.update(body)
.digest('base64') === expectedSignature
const server = createServer((req, resp) => {
let body = new Buffer([])
req.on('data', chunk => body = Buffer.concat([body, chunk]))
req.on('end', () => {
if (!isValidRequest(body, WEBHOOK_SECRET, req.headers['x-uipath-signature'])) {
console.error('Invalid signature')
resp.statusCode = 401 // Unauthorized
} else {
let payload = JSON.parse(body.toString('utf8'))
// Process request
console.log(payload)
resp.statusCode = 202 // Accepted
}
resp.end()
})
})
server.listen(PORT)
const { createServer } = require('http');
const { createHmac } = require('crypto');
const PORT = 9090
const WEBHOOK_SECRET = '<same secret as configured in Orchestrator>'
const isValidRequest = (body /* Buffer */, secret /* string */, expectedSignature /* string */) =>
expectedSignature == null || createHmac('sha256', secret)
.update(body)
.digest('base64') === expectedSignature
const server = createServer((req, resp) => {
let body = new Buffer([])
req.on('data', chunk => body = Buffer.concat([body, chunk]))
req.on('end', () => {
if (!isValidRequest(body, WEBHOOK_SECRET, req.headers['x-uipath-signature'])) {
console.error('Invalid signature')
resp.statusCode = 401 // Unauthorized
} else {
let payload = JSON.parse(body.toString('utf8'))
// Process request
console.log(payload)
resp.statusCode = 202 // Accepted
}
resp.end()
})
})
server.listen(PORT)