- Introdução
- Melhores práticas
- Tenant
- Ações
- Contexto de Pastas
- Automações
- Processos
- Trabalhos
- Gatilhos
- Logs
- Monitoramento
- Filas
- Ativos
- Armazenar Buckets
- Teste do Orquestrador
- Catálogos de Ações
- Perfil
- Administrador do Sistema
- Servidor de Identidade
- Autenticação
- Outras configurações
- Integrações
- Robôs Clássicos
- Solução de problemas
Webhooks permitem a você integrar melhor sua automação do UiPath com todo o seu ecossistema do aplicativo. É possível se inscrever em eventos do Orchestrator e enviá-los para qualquer solução externa de CRM, BPM ou DCM e informar diferentes usuários, por exemplo, que há um novo item enfileirado que pode ser processado, que um gatilho falhou ou que um processo foi atualizado.
Webhooks allow external systems to subscribe and listen to different types of Orchestrator events. The Webhooks page enables you to easily set them up, as well as view the ones that have been previously created. You can also disable webhooks, search for a specific one, edit or delete them.
Events are available for jobs, robots, queues, queue items, processes, and triggers. For the full list of event types and a few examples, please check this page.
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.
Propriedades comuns de carga útil
| 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: "Type": "job.created""Type":"process.updated" |
| ID do Evento | String | Um identificador gerado exclusivamente para cada evento quando ele ocorreu. Esta propriedade é exibida para todos os tipos de eventos. Exemplo: "EventId":"3e5af0113e674ae597c579cb35ed8630" |
| 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: "Timestamp":"2018-11-02T11:47:48.5790797Z" |
| 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: "TenantId":3 |
| 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: "UserId": 4947 |
| 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: "FolderId": 26 |
Permissões
Para executar várias operações na página Webhooks, você precisa receber as permissões correspondentes em webhooks:
- View - Enables you to view webhooks and their details, as well as retrieve them using the API, send a ping request, or get the list of all the events to which a webhook can subscribe.
- Criar - esta permissão permite que você adicione novos webhooks. Observe que você também precisa de permissões de Exibir.
- Edit - Grants you the right to edit webhooks from the UI or by using the API. Please note that you also require View permissions.
- Excluir - uma permissão que permite que você exclua webhooks. Observe que você também precisa de permissões de Exibir.
Autenticação
Todas as solicitações HTTP de webhook usam o segredo que você adiciona ao criar um webhook para autenticar. Ele é combinado com o corpo de solicitação usando um hash chaveado HMAC-SHA256. Isso resulta em uma assinatura protegida que não contém qualquer informação secreta, é exclusiva de cada solicitação e é enviada por meio do cabeçalho X-UiPath-Signature HTTP.
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 do 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.
Exemplos de validação de assinatura
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)