Como funcionan los Webhooks
Language

Webhooks

Aprende como configurar webhooks para tu aplicacion.

Como funcionan los Webhooks

Los Webhooks de cside son una forma facil de recibir notificaciones sobre eventos importantes en tu cuenta de cside. Los webhooks se pueden usar para activar acciones en tu aplicacion, enviar mensajes a tus canales de Discord o Slack, y mas.

Cuando creas un endpoint de webhook, enviaremos una solicitud POST a la URL que hayas especificado. La solicitud contendra un payload JSON con informacion sobre el evento que activo el webhook.

La estructura de datos

Siempre te enviaremos un payload JSON estructurado con los siguientes campos:

Prop
Type
event
"alert.created"
The event code
sent_at
string
When the event was sent in ISO 8601 format
data
AlertCreatedObject
The data of the event
domain_id
string
The domain ID that the event is for
destination_id
string
The ID of the endpoint destination

Eventos

A continuacion se muestran los IDs de eventos y sus payloads que se enviaran con los webhooks.

IDs de eventos

IDNombreObjeto data
alert.createdAlerta creadaObjeto Alert

Objetos de eventos

Secreto HMAC (tambien conocido como x-cside-signature)

Calculamos un HMAC al vuelo, usando un hash SHA256 del payload y tu secreto de webhook que te fue proporcionado cuando creaste el endpoint de webhook por primera vez. Esta firma se incluye en la cabecera x-cside-signature de la solicitud.

TE RECOMENDAMOS ENCARECIDAMENTE QUE USES ESTO PARA VERIFICAR QUE LA SOLICITUD PROVIENE DE cside: No hacerlo podria dejarte vulnerable a ataques de repeticion.

Verificar el secreto HMAC

Si estas usando JavaScript, te sugerimos usar nuestro paquete JavaScript para ayudarte a verificar la firma. Hemos proporcionado ejemplos en esa pagina que te ayudaran a comenzar.

Si no estas usando JavaScript, puedes verificar la firma calculando el hash HMAC SHA256 del cuerpo de la solicitud usando tu secreto de webhook, y comparandolo con la cabecera (x-cside-signature) que enviamos con cada solicitud.

Aqui hay algunos ejemplos en diferentes lenguajes:

async function verifyHmac(body: string, signature: string, secret: string) {
	const encoder = new TextEncoder();
	const encodedBody = encoder.encode(body);

	const key = await crypto.subtle.importKey(
		"raw",
		encoder.encode(secret),
		{ name: "HMAC", hash: "SHA-256" },
		false,
		["sign"]
	);

	const signatureBuffer = await crypto.subtle.sign("HMAC", key, encodedBody);

	const finalSig = Array.from(new Uint8Array(signatureBuffer))
		.map((byte) => byte.toString(16).padStart(2, "0"))
		.join("");

	return signature.toLowerCase() === finalSig;
}
fn verify_hmac(body: &str, signature: &str, secret: &str) -> Result<(), &'static str> {
      let mut mac = HmacSha256::new_from_slice(secret.as_bytes()).map_err(|_| "Invalid secret")?;
      mac.update(body.as_bytes());
      let result = mac.finalize();
      let code_bytes = result.into_bytes();
      let final_sig = hex::encode(code_bytes);

      if signature.to_lowercase() == final_sig {
          Ok(())
      } else {
          Err("Invalid signature")
      }
  }

  // Add to Cargo.toml:
  // [dependencies]
  // hmac = "0.12"
  // sha2 = "0.10"
  // hex = "0.4"
package main

import (
  "crypto/hmac"
  "crypto/sha256"
  "encoding/hex"
  "strings"
)

func verifyHmac(body, signature, secret string) bool {
	h := hmac.New(sha256.New, []byte(secret))
	h.Write([]byte(body))
	finalSig := hex.EncodeToString(h.Sum(nil))

	return strings.ToLower(signature) == finalSig
}
defmodule HmacVerifier do
	def verify_hmac(body, signature, secret) do
		final_sig =
			:crypto.mac(:hmac, :sha256, secret, body)
			|> Base.encode16(case: :lower)

			String.downcase(signature) == final_sig
	end
end
import hmac
import hashlib
import secrets

def verify_hmac(body: str, signature: str, secret: str) -> bool:
	final_sig = hmac.new(
		secret.encode('utf-8'),
		body.encode('utf-8'),
		hashlib.sha256
	).hexdigest()

	return signature.lower() == final_sig