Documentación

Tarjetas: comandos CLI

Busca tipos de tarjeta, crea una tarjeta, define sus parámetros y datos en vivo, previsualízala y actualiza sus datos con webhooks firmados.

Cada comando se ejecuta como describe la referencia de la CLI: banderas globales, salida JSON, códigos de salida, revisiones y reintentos.

Tarjetas

Descubra los tipos de tarjetas, cree una instancia y actualice sus datos en directo. Una lista de reproducción coloca el ID de tarjeta devuelto.

screenrig cards list --category ops
screenrig cards show gauge
screenrig card create --type gauge --file gauge-params.json
screenrig card list
screenrig card show crd_01EXAMPLEGAUGE000000000
screenrig card params crd_01EXAMPLEGAUGE000000000 --file gauge-params.json
screenrig card data get crd_01EXAMPLEGAUGE000000000
screenrig card data put crd_01EXAMPLEGAUGE000000000 --file gauge-data.json --ttl 30m --expect-rev 1
screenrig card preview crd_01EXAMPLEGAUGE000000000 --output gauge.png
screenrig card delete crd_01EXAMPLEGAUGE000000000
ParámetroTipoRequeridoPredeterminadoNotas
cards list --tag TAGstringnoningunoCoincide con una etiqueta del catálogo.
cards list --category CATEGORYstringnoningunoCoincide con una categoría del catálogo. Con --tag, una tarjeta debe coincidir con ambas.
cards show <id>stringsíningunoEl id de tarjeta del catálogo que da cards list, como gauge.
card create --type IDstringsíningunoEl id de tarjeta del catálogo que da cards list.
card create --major Nintegernoversión principal actualFija una versión principal del catálogo.
card create --file FILErutasíningunoLos parámetros estáticos como objeto JSON de como máximo 1 MiB, o - para stdin.
<id>stringsíningunoEl id de tarjeta crd_ que toman card show, card params, card delete y card data.
card params --file FILErutasíningunoLos nuevos parámetros estáticos, leídos como en card create. Reemplazan a los anteriores de inmediato.
card data put --file FILErutasíningunoEl documento de datos como objeto JSON, o - para stdin. Reemplaza todo el documento.
card data put --ttl DURATIONstringnoningunoDeja en blanco los datos pasado este tiempo, incluidas las pantallas sin conexión: 30m, 12h o 1d, de 1s a 365d. No se combina con --expires-at.
card data put --expires-at INSTANTstringnoningunoDeja en blanco los datos en esta marca de tiempo ISO 8601, que lleva una zona horaria. Una escritura sin ninguna de las dos opciones borra la caducidad anterior.
card data put --expect-rev REVISIONstringnoningunoEscribe solo si los datos siguen en esta revisión, la que muestra card data get. Un valor obsoleto es revision_conflict (salida 6).
card preview <type|id>stringsíningunoUn id de tarjeta del catálogo, o un id de tarjeta crd_ para dibujar esa instancia con sus propios parámetros y datos.
card preview --output FILErutasíningunoEscribe el PNG aquí. Se crean los directorios padres.
card preview --params FILErutanoningunoPropiedades estáticas como un objeto JSON.
card preview --data FILErutanoningunoEl documento dinámico como objeto JSON.
card preview --feed FILErutanoningunoEl documento de feed del host como objeto JSON. Se informa de un feed que la tarjeta necesita y que usted omite.
card preview --width PX / --height PXintegerno1920 / 1080Tamaño de la imagen, de 1 a 8192.
card preview --layout LAYOUTstringnofullfull, free, center, wide, header, footer, corner, chip o strip: el diseño que se dibuja.
card preview --anchor ANCHORstringnoningunoLa esquina de un diseño corner o chip, o el borde de un strip.
card preview --now ISOstringnola hora actualCongela el reloj en este instante ISO 8601.
card preview --timezone ZONEstringnoel de esta máquinaDibuja en esta zona horaria IANA, como America/Vancouver.

cards show muestra el params_schema y el data_schema de la tarjeta, sus propiedades estáticas y dinámicas, nivel, diseños y feed, y un ejemplo para copiar en una página de lista de reproducción. card create devuelve el id crd_ de la instancia, y una repetición idéntica tras una respuesta perdida reutiliza la clave de idempotencia guardada.

card data put reemplaza el documento de inmediato, sin volver a publicar la lista de reproducción. La validación propia de la tarjeta rechaza un documento que no puede mostrar (card_data_invalid), y una caducidad deja en blanco los datos en todas las pantallas cuando nada los renueva. card delete elimina la instancia y sus datos, y responde resource_conflict (salida 5) mientras una lista de reproducción la coloque.

card preview dibuja la tarjeta en un Chromium o Chrome local y escribe un PNG; no publica nada. Defina SCREENRIG_BROWSER con la ruta del navegador cuando no haya instalado ninguno de los habituales. data.file es la ruta escrita y data.unrendered enumera lo que la vista previa no pudo dibujar, por ejemplo un feed del host que no proporcionó. Abra la imagen antes de publicar. Tarjetas integradas describe los diseños, las propiedades y los feeds de cada tarjeta.

Webhooks de tarjeta

Un webhook de tarjeta es una URL que escribe el documento de datos de una tarjeta, de modo que un sistema externo como un CMS, un punto de venta o un script envía datos a una tarjeta con un solo POST HTTP. kv webhook create, list, rotate-secret y delete aceptan --card CARD_ID en lugar de --app-id, nunca ambos; update y deliveries a continuación solo funcionan con tarjetas. Una tarjeta tiene como máximo 20 webhooks.

kv webhook create --card CARD_ID [--description TEXT] [--map FILE|-] [--key-template TEMPLATE] [--signing]
                  [--verify VENDOR [--verify-secret-file FILE|-] [--verify-header NAME] [--verify-encoding hex|base64]
                   [--verify-timestamp-header NAME] [--verify-tolerance SECONDS]] [--handshake VENDOR]
kv webhook list --card CARD_ID
kv webhook rotate-secret <webhook_id> --card CARD_ID [--signing]
kv webhook delete <webhook_id> --card CARD_ID

Crear un webhook de tarjeta no requiere clave. --map FILE (o - para stdin) es el mapeo, --key-template escribe documentos por clave, --signing activa la firma, y --verify y --handshake aceptan los envíos propios de un proveedor (Firmas y handshakes de proveedores). La respuesta incluye data.secret y, si el webhook firma, data.signing_secret, cada uno mostrado una sola vez.

El remitente se autentica como en un webhook de aplicación: Authorization: Bearer <secret> con el secreto srkw_…, o HTTP Basic con el ID del webhook como nombre de usuario, así que https://kvw_ID:srkw_…@api.screenrig.ai/… sirve para un remitente que solo admite una URL. El cuerpo, de como máximo 1 MiB, es JSON o application/x-www-form-urlencoded; un nombre de formulario repetido pasa a ser un arreglo. Sin mapeo, el objeto enviado es el documento de datos de la tarjeta.

Un mapeo es una plantilla JSON que construye el documento a partir del cuerpo. Una cadena con marcadores como {{body.alert.title}} o {{body.items[0].name}} es texto, y una cadena que es exactamente un marcador conserva el tipo del valor. Una ruta empieza con body o query (los parámetros de consulta de la URL), y una ruta que no contiene nada queda vacía en el texto y omite un valor aislado. $each mapea un arreglo con item e index en el ámbito, $group con $by agrupa en el orden de primera aparición, $number lee 1,234.50, $3.50, 3,50 € o 12% (añada "$decimal": "," para una coma decimal), $bool lee true, yes, y, 1 y x, y $text con $max recorta el texto. La plantilla se comprueba al guardarla: invalid_request indica el lugar que falló.

{
  "title": "{{body.alert.title}}",
  "body": "{{body.alert.message}}",
  "items": { "$each": "{{body.items}}", "$limit": 20, "$template": { "text": "{{item.name}}" } }
}
curl https://api.screenrig.ai/api/cards/crd_01EXAMPLEBOARD0000000000/kv-webhooks/kvw_01EXAMPLEWEBHOOK00000/write \
  -H "Authorization: Bearer $CARD_WEBHOOK_SECRET" \
  -H "Content-Type: application/json" \
  --data '{"alert":{"title":"Fire drill","message":"Leave by the east door"},"items":[{"name":"Floor 2"}]}'

--key-template TEMPLATE escribe documentos por clave en lugar del documento propio de la tarjeta. La plantilla es una clave de datos de tarjeta con tokens {screen.field.NAME}, como room-{screen.field.room}, y el objeto mapeado (o el cuerpo enviado, sin mapeo) contiene solo un array documents de objetos {fields, document}: cada objeto fields rellena la plantilla y cada document se escribe bajo la clave que produce. Un elemento de página que indica la misma plantilla como su data muestra a cada pantalla el documento de sus propios campos. Cada documento se comprueba antes de escribir ninguno, y una clave repetida se rechaza. Un fallo de almacenamiento puede dejar parte del lote escrita: reenvíe el mismo cuerpo con el mismo Idempotency-Key. Las claves que un envío omite conservan sus datos, y un webhook no fija caducidad. Documentos por clave muestra un mapeo.

Cada envío se comprueba como datos de la propia tarjeta: card_data_invalid indica la ruta y no se escribe nada. Un documento igual al actual de la tarjeta se responde con unchanged y no escribe nada, así que no se despierta ninguna pantalla. Un envío aceptado no cuenta para el límite de solicitudes de agentes, un webhook admite como máximo 120 envíos por minuto y un encabezado Idempotency-Key deduplica los reintentos de un remitente durante 24 horas.

Una dirección incorrecta, un secreto incorrecto o ausente, un webhook desactivado, una firma ausente o incorrecta y cada GET reciben la misma respuesta 404, de modo que una vista previa de enlace o una suposición no revela nada. kv webhook deliveries explica el motivo.

Con --signing, cada envío debe incluir también ScreenRig-Signature: t=<unix seconds>,v1=<hex>, donde v1 es el HMAC-SHA256 de t, un punto y el cuerpo sin procesar con el secreto de firma whsec_…, y t debe estar a menos de cinco minutos del reloj del servidor. Es el formato de las firmas de webhook de screenRIG.

Firmas y handshakes de proveedores

Los proveedores firman sus envíos a su manera, y algunos no pueden enviar su secreto en absoluto. Un webhook de tarjeta puede verificar la firma del proveedor en lugar del secreto y responder al handshake de configuración del proveedor, así que GitHub, Stripe, Shopify, Slack, Linear, Vercel, Asana, Microsoft Graph, monday.com, Trello y Azure Event Grid envían directamente a él, sin intermediarios. Cualquier otro remitente que firme con HMAC también funciona. Defínalos con --verify y --handshake en kv webhook create, y cámbielos con kv webhook update.

  • --verify VENDOR acepta la firma propia de un proveedor, con --verify-secret-file FILE (o - para stdin, nunca como argumento) que contiene el secreto que muestra el proveedor. Para generic_hmac, --verify-header NAME nombra el encabezado que lleva la firma, --verify-encoding es hex (el valor predeterminado) o base64, --verify-timestamp-header NAME nombra un encabezado que lleva la hora Unix, y --verify-tolerance SECONDS es cuánto puede separarse del reloj del servidor (300 por defecto). Un envío que lleva la firma válida del proveedor se acepta sin el secreto srkw_ propio del webhook, que sigue funcionando a su lado. El secreto del proveedor se almacena sellado y solo se muestra como set y una hint de sus cuatro últimos caracteres. En kv webhook update, --verify sin --verify-secret-file conserva el secreto almacenado mientras el proveedor siga siendo el mismo, y --clear-verify elimina la verificación y su secreto. --verify y --signing se excluyen entre sí.
  • --handshake VENDOR es microsoft_graph, monday, trello o azure_event_grid, y --clear-handshake lo elimina. Slack y Asana responden a sus propios handshakes mediante --verify.
--verifyEncabezadoQué se firmaMarca de tiempo
githubX-Hub-Signature-256HMAC-SHA256 del cuerpoNinguno
stripeStripe-SignatureHMAC-SHA256 de la marca de tiempo, un punto y el cuerpo; cualquier v1 puede coincidir5 minutos
shopifyX-Shopify-Hmac-Sha256HMAC-SHA256 del cuerpo, en base64Ninguno
slackX-Slack-SignatureHMAC-SHA256 de v0:, la marca de tiempo, dos puntos y el cuerpoX-Slack-Request-Timestamp, 5 minutos
linearLinear-SignatureHMAC-SHA256 del cuerpowebhookTimestamp en el cuerpo, 1 minuto
vercelx-vercel-signatureHMAC-SHA1 del cuerpoNinguno
asanaX-Hook-SignatureHMAC-SHA256 del cuerpo, con el X-Hook-Secret del handshake como claveNinguno
generic_hmacEl --verify-header que usted nombraHMAC-SHA256 del cuerpo o, con un --verify-timestamp-header, de la marca de tiempo, un punto y el cuerpo--verify-tolerance

La clave de cada HMAC es el texto del secreto tal como lo muestra el proveedor (el de Stripe incluye whsec_). Una firma se comprueba sobre el cuerpo exactamente como llegó, en tiempo constante, antes de que el envío consuma presupuesto de escritura, y se juzga antes que su marca de tiempo: timestamp_stale siempre significa que el secreto era correcto. Un cuerpo puede ser JSON, un formulario o multipart/form-data, donde un campo de texto es body.FIELD y los archivos se cuentan, no se leen.

ProveedorscreenRIG respondeEnvíos posteriores
Slack (--verify slack)El url_verification firmado con su challenge; una persona que pruebe con curl puede enviar en su lugar el secreto del webhookFirmados con el secreto de firma
Asana (--verify asana)El X-Hook-Secret del handshake, que guarda sellado como clave de cada X-Hook-Signature. El mismo secreto de nuevo es un reintento; uno distinto se rechaza como handshake_invalidX-Hook-Signature
Microsoft Graph (--handshake microsoft_graph)El ?validationToken= decodificado como text/plainLlevan el secreto del webhook
monday.com (--handshake monday)El challenge que envía, devuelto como JSONLlevan el secreto del webhook
Trello (--handshake trello)Una comprobación HEAD responde 200 sin cuerpo, solo para este webhookLlevan el secreto del webhook
Azure Event Grid (--handshake azure_event_grid){"validationResponse": "CODE"}Llevan el secreto del webhook

Un handshake se responde solo para un webhook configurado para ese proveedor, antes de pedir ninguna credencial, a una solicitud que es ese handshake, y nunca por un webhook desactivado. No escribe nada, nunca se factura y no gasta presupuesto de velocidad. Microsoft Graph, monday.com, Trello y Azure Event Grid no envían ningún encabezado que screenRIG verifique, así que sus entregas solo se aceptan con el secreto del webhook. Azure Event Grid lo lleva como un encabezado de entrega estático, Authorization: Bearer srkw_…, marcado como secreto, y sus eventos llegan como una matriz, así que un mapeo lee body[0].

ProveedorEn los ajustes del proveedor
GitHubSettings, Webhooks, Add webhook: la Payload URL es el url del webhook, el tipo de contenido es application/json, y el mismo secreto. El ping de GitHub está firmado y se acepta
StripeWorkbench, Webhooks: añada el url y revele su secreto de firma. Mientras Stripe rota un secreto envía un v1 por cada uno y se acepta cualquiera de los dos; después sustituya el secreto almacenado con kv webhook update --verify stripe --verify-secret-file FILE
ShopifySuscríbase con el url en formato JSON. El secreto es el secreto de cliente de la aplicación
SlackLa Request URL de la Events API es el url, y el secreto es el secreto de firma de la aplicación. Un comando de barra envía un formulario: {{body.text}}, {{body.user_name}}
LinearEn los ajustes de la API cree un webhook con el url y copie su secreto de firma. El webhookTimestamp del cuerpo debe estar a menos de un minuto del reloj del servidor
VercelTeam settings, Webhooks: cree uno con el url. Vercel muestra el secreto una sola vez
AsanaCree el webhook con --verify asana: todavía no tiene secreto y rechaza los eventos con secret_pending. Después cree el webhook de Asana con target establecido en el url, y el handshake fija el secreto. Para tomar un secreto nuevo, ejecute kv webhook update con --clear-verify y luego otra vez con --verify asana
Microsoft GraphCree la suscripción con notificationUrl establecido en el url
monday.comEjecute create_webhook con el url
TrelloPOST /1/webhooks con callbackURL establecido en el url
Azure Event GridCree la suscripción de eventos con el url como su punto de conexión de webhook, y añada el encabezado de entrega anterior
echo '{"title":"{{body.repository.full_name}}","body":"{{body.head_commit.message}}"}' |
  screenrig kv webhook create --card crd_01EXAMPLEBOARD0000000000 --description "Pushes" \
    --verify github --verify-secret-file github.secret --map -

Un remitente que firma con su propio HMAC nombra el encabezado, la codificación y, si firma una marca de tiempo, el encabezado de la marca de tiempo:

echo '{"title":"{{body.sensor}}","body":"{{body.state}}"}' |
  screenrig kv webhook create --card crd_01EXAMPLEBOARD0000000000 --verify generic_hmac --verify-secret-file acme.secret \
    --verify-header X-Acme-Signature --verify-encoding base64 --verify-timestamp-header X-Acme-Time --verify-tolerance 120 \
    --map -
ts=$(date +%s); body='{"sensor":"door","state":"open"}'
sig=$(printf '%s.%s' "$ts" "$body" | openssl dgst -sha256 -hmac "$SECRET" -binary | openssl base64 -A)
curl "$URL" -H "Content-Type: application/json" -H "X-Acme-Time: $ts" -H "X-Acme-Signature: $sig" -d "$body"

Cada fallo da el mismo 404 que cualquier otro rechazo. kv webhook deliveries muestra el motivo, y un handshake aparece con el resultado handshake:

MotivoSignificado
signature_missingHay una verificación de proveedor definida y el envío no llevaba ni el secreto ni el encabezado del proveedor
signature_invalidEl encabezado está mal formado o no coincide con el cuerpo
timestamp_missingLa firma necesita una marca de tiempo que el envío no llevaba
timestamp_staleLa firma es válida y su marca de tiempo está fuera de la ventana
secret_pendingUna verificación de Asana sigue esperando su handshake
handshake_invalidLa solicitud es el handshake de un proveedor y no puede responderse

kv webhook update#

Cambiar un webhook de tarjeta: su descripción, mapeo, documentos por clave, estado activado, firma, verificación de proveedor o handshake.

kv webhook update <webhook_id> --card CARD_ID [--description TEXT] [--map FILE|-] [--clear-map]
                   [--key-template TEMPLATE] [--clear-key-template] [--enable|--disable] [--signing|--no-signing]
                   [--verify VENDOR [--verify-secret-file FILE|-] [--verify-header NAME] [--verify-encoding hex|base64]
                    [--verify-timestamp-header NAME] [--verify-tolerance SECONDS]] [--clear-verify]
                   [--handshake VENDOR] [--clear-handshake]
ParámetroTipoRequeridoPredeterminadoNotas
<webhook_id>stringsíningunoEl id de webhook kvw_.
--card CARD_IDstringsíningunoEl ID de tarjeta crd_.
--description TEXTstringnoningunoQué envía, máximo 200 bytes. No debe contener credenciales.
--map FILErutanoningunoReemplazar el mapeo por un objeto JSON leído de un archivo, o - para stdin. No se combina con --clear-map.
--clear-mapbooleannoapagadoQuitar el mapeo: el objeto enviado pasa a ser el documento.
--key-template TEMPLATEstringnoningunoDefine la plantilla de clave que asigna la clave a los documentos, como room-{screen.field.room}. No se combina con --clear-key-template.
--clear-key-templatebooleannoapagadoVuelve a escribir el documento propio de la tarjeta.
--enable / --disablebooleannoapagado--disable responde a cada envío como a un secreto incorrecto hasta que se use --enable.
--signing / --no-signingbooleannoapagado--signing exige el encabezado de firma y muestra el secreto de firma una vez; un webhook que ya firma conserva su secreto, que kv webhook rotate-secret --signing reemplaza. --no-signing deja de exigirlo. No se combina con --verify.
--verify VENDORstringnoningunoReemplaza la verificación del proveedor: github, stripe, shopify, slack, linear, vercel, asana o generic_hmac. Sin --verify-secret-file, se conserva el secreto almacenado si el proveedor es el mismo, de modo que un encabezado o una ventana puede cambiar solo; un proveedor distinto necesita el suyo. No se combina con --clear-verify.
--verify-secret-file FILErutanoel secreto almacenadoLee el secreto del proveedor desde un archivo, o - para stdin (nunca como argumento). asana no admite ninguno. Solo una opción lee stdin.
--verify-header NAMEstringcon generic_hmacningunoEl encabezado que lleva la firma, de 1 a 100 letras, dígitos, - o _.
--verify-encoding ENCODINGstringnohexCon generic_hmac: hex o base64; puede empezar por sha256=.
--verify-timestamp-header NAMEstringnoningunoCon generic_hmac: un encabezado que lleva la hora Unix en segundos, o en milisegundos con 13 dígitos.
--verify-tolerance SECONDSintegerno300Con --verify-timestamp-header: cuánto puede separarse la marca de tiempo del reloj del servidor, de 1 a 86400.
--clear-verifybooleannoapagadoDeja de aceptar la firma del proveedor y olvida su secreto. Una verificación de Asana solo admite un nuevo handshake tras --clear-verify y de nuevo --verify asana.
--handshake VENDORstringnoningunoDefine el handshake al que responde la URL: microsoft_graph, monday, trello o azure_event_grid. No se combina con --clear-handshake.
--clear-handshakebooleannoapagadoDeja de responder al handshake del proveedor.

Se requiere al menos un cambio.

screenrig kv webhook update kvw_01EXAMPLEWEBHOOK00000 --card crd_01EXAMPLEBOARD0000000000 --map alert-map.json
screenrig kv webhook update kvw_01EXAMPLEWEBHOOK00000 --card crd_01EXAMPLEBOARD0000000000 --verify stripe --verify-secret-file stripe.secret
screenrig kv webhook update kvw_01EXAMPLEWEBHOOK00000 --card crd_01EXAMPLEBOARD0000000000 --clear-verify

El sobre es el webhook. data.signing_secret aparece una sola vez, en la respuesta que activó la firma. Tras una actualización interrumpida o ambigua, vuelva a ejecutar el mismo comando: reutiliza la clave de idempotencia guardada.

kv webhook deliveries#

Leer el registro de entregas de un webhook de tarjeta, de lo más reciente a lo más antiguo, de los últimos siete días.

kv webhook deliveries <webhook_id> --card CARD_ID [--limit N]
ParámetroTipoRequeridoPredeterminadoNotas
<webhook_id>stringsíningunoEl id de webhook kvw_.
--card CARD_IDstringsíningunoEl ID de tarjeta crd_.
--limit Nnumberno100Cuántas entregas devolver, de 1 a 100.
screenrig kv webhook deliveries kvw_01EXAMPLEWEBHOOK00000 --card crd_01EXAMPLEBOARD0000000000

Cada elemento tiene at, outcome (written, unchanged, refused, invalid o handshake), reason (credentials, signature para un ScreenRig-Signature fallido, disabled, body, mapping, card_data_invalid, rate_limited, internal, o un motivo de proveedor de la tabla anterior), detail, status, bytes, files (las partes de archivo de un envío multipart, que se ignoran), revision y request_id. No se almacena ningún cuerpo, encabezado ni credencial, y un envío a una dirección incorrecta no deja ninguna fila.

Otros grupos de comandos