Documentation

Cartes : commandes CLI

Trouvez des types de cartes, créez une carte, réglez ses paramètres et ses données en direct, prévisualisez-la et mettez-la à jour par webhooks signés.

Chaque commande s’exécute comme décrit dans la référence CLI : drapeaux globaux, sortie JSON, codes de sortie, révisions et réessais.

Cartes

Découvrez les types de cartes, créez une instance et mettez à jour ses données en direct. Une liste de lecture place l’identifiant de carte retourné.

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
ParamètreTypeRequisPar défautNotes
cards list --tag TAGstringnonaucunCorrespond à une étiquette du catalogue.
cards list --category CATEGORYstringnonaucunCorrespond à une catégorie du catalogue. Avec --tag, une carte doit correspondre aux deux.
cards show <id>stringouiaucunL’identifiant de carte du catalogue issu de cards list, comme gauge.
card create --type IDstringouiaucunL’identifiant de carte du catalogue issu de cards list.
card create --major Nintegernonversion majeure actuelleÉpingle une version majeure du catalogue.
card create --file FILEcheminouiaucunLes paramètres statiques sous forme d’objet JSON d’au plus 1 Mio, ou - pour stdin.
<id>stringouiaucunL’identifiant de carte crd_ que prennent card show, card params, card delete et card data.
card params --file FILEcheminouiaucunLes nouveaux paramètres statiques, lus comme pour card create. Ils remplacent immédiatement les anciens.
card data put --file FILEcheminouiaucunLe document de données sous forme d’objet JSON, ou - pour stdin. Il remplace tout le document.
card data put --ttl DURATIONstringnonaucunVide les données après cette durée, écrans hors ligne compris : 30m, 12h ou 1d, de 1s à 365d. Incompatible avec --expires-at.
card data put --expires-at INSTANTstringnonaucunVide les données à cet horodatage ISO 8601, qui porte un fuseau horaire. Une écriture sans aucune des deux options efface l’ancienne expiration.
card data put --expect-rev REVISIONstringnonaucunÉcrit seulement si les données sont toujours à cette révision, celle que montre card data get. Une valeur périmée donne revision_conflict (sortie 6).
card preview <type|id>stringouiaucunUn identifiant de carte du catalogue, ou un identifiant de carte crd_ pour dessiner cette instance avec ses propres paramètres et données.
card preview --output FILEcheminouiaucunÉcrit le PNG ici. Les dossiers parents sont créés.
card preview --params FILEcheminnonaucunPropriétés statiques sous forme d’objet JSON.
card preview --data FILEcheminnonaucunLe document dynamique sous forme d’objet JSON.
card preview --feed FILEcheminnonaucunLe document de flux hôte sous forme d’objet JSON. Un flux dont la carte a besoin et que vous omettez est signalé.
card preview --width PX / --height PXintegernon1920 / 1080Taille de l’image, de 1 à 8192.
card preview --layout LAYOUTstringnonfullfull, free, center, wide, header, footer, corner, chip ou strip : la mise en page à dessiner.
card preview --anchor ANCHORstringnonaucunLe coin d’une mise en page corner ou chip, ou le bord d’un strip.
card preview --now ISOstringnonl’heure actuelleFige l’horloge à cet instant ISO 8601.
card preview --timezone ZONEstringnoncelui de cette machineDessine dans ce fuseau horaire IANA, comme America/Vancouver.

cards show affiche le params_schema et le data_schema de la carte, ses propriétés statiques et dynamiques, son niveau, ses mises en page et son flux, ainsi qu’un exemple à copier dans une page de liste de lecture. card create renvoie l’identifiant crd_ de l’instance, et une relance identique après une réponse perdue réutilise la clé d’idempotence enregistrée.

card data put remplace le document immédiatement, sans republier la liste de lecture. La validation propre à la carte refuse un document qu’elle ne peut pas afficher (card_data_invalid), et une expiration vide les données sur chaque écran quand rien ne les renouvelle. card delete supprime l’instance et ses données, et répond resource_conflict (sortie 5) tant qu’une liste de lecture la place.

card preview dessine la carte dans un Chromium ou Chrome local et écrit un PNG ; il ne publie rien. Définissez SCREENRIG_BROWSER sur le chemin du navigateur si aucun des navigateurs habituels n’est installé. data.file est le chemin écrit et data.unrendered liste ce que l’aperçu n’a pas pu dessiner, par exemple un flux hôte que vous n’avez pas fourni. Ouvrez l’image avant de publier. Cartes intégrées décrit les mises en page, les propriétés et les flux de chaque carte.

Webhooks de carte

Un webhook de carte est une URL qui écrit le document de données d'une carte, de sorte qu'un système externe comme un CMS, un point de vente ou un script envoie des données à une carte avec un seul POST HTTP. kv webhook create, list, rotate-secret et delete acceptent --card CARD_ID à la place de --app-id, jamais les deux ; update et deliveries ci-dessous ne fonctionnent que sur les cartes. Une carte peut avoir au maximum 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

La création d’un webhook de carte ne prend aucune clé. --map FILE (ou - pour stdin) est le mappage, --key-template écrit des documents par clé, --signing active la signature, et --verify et --handshake acceptent les envois propres à un fournisseur (Signatures et poignées de main des fournisseurs). La réponse contient data.secret et, si le webhook signe, data.signing_secret, chacun affiché une seule fois.

L'expéditeur s'authentifie comme pour un webhook d'application : Authorization: Bearer <secret> avec le secret srkw_…, ou HTTP Basic avec l'identifiant du webhook comme nom d'utilisateur, de sorte que https://kvw_ID:srkw_…@api.screenrig.ai/… convient à un expéditeur qui n'accepte qu'une URL. Le corps, d'au plus 1 Mio, est du JSON ou application/x-www-form-urlencoded ; un nom de formulaire répété devient un tableau. Sans mappage, l'objet envoyé est le document de données de la carte.

Un mappage est un modèle JSON qui construit le document à partir du corps. Une chaîne contenant des espaces réservés comme {{body.alert.title}} ou {{body.items[0].name}} est du texte, et une chaîne qui est exactement un espace réservé conserve le type de la valeur. Un chemin commence par body ou query (les paramètres de requête de l'URL), et un chemin qui ne contient rien est vide dans le texte et omet une valeur isolée. $each mappe un tableau avec item et index dans la portée, $group avec $by regroupe dans l'ordre de première apparition, $number lit 1,234.50, $3.50, 3,50 € ou 12% (ajoutez "$decimal": "," pour une virgule décimale), $bool lit true, yes, y, 1 et x, et $text avec $max tronque le texte. Le modèle est vérifié à l'enregistrement : invalid_request nomme l'endroit en cause.

{
  "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 écrit des documents par clé à la place du document propre à la carte. Le modèle est une clé de données de carte avec des jetons {screen.field.NAME}, comme room-{screen.field.room}, et l’objet mappé (ou le corps posté, sans mappage) ne contient qu’un tableau documents d’objets {fields, document} : chaque objet fields remplit le modèle et chaque document est écrit sous la clé qu’il produit. Un élément de page qui donne le même modèle comme data montre à chaque écran le document de ses propres champs. Chaque document est vérifié avant qu’aucun ne soit écrit, et une clé répétée est refusée. Un échec de stockage peut laisser une partie du lot écrite : renvoyez le même corps avec le même Idempotency-Key. Les clés qu’un envoi omet gardent leurs données, et un webhook ne fixe aucune expiration. Documents par clé montre un mappage.

Chaque envoi est vérifié comme les données de la carte elle-même : card_data_invalid nomme le chemin et rien n’est écrit. Un document identique à celui en cours de la carte reçoit la réponse unchanged et n’écrit rien, de sorte qu’aucun écran n’est réveillé. Un envoi accepté ne compte pas dans le plafond de requêtes d’agent, un webhook accepte au plus 120 envois par minute, et un en-tête Idempotency-Key déduplique les nouvelles tentatives d’un expéditeur pendant 24 heures.

Une mauvaise adresse, un secret erroné ou absent, un webhook désactivé, une signature absente ou erronée et chaque GET reçoivent la même réponse 404, de sorte qu'un aperçu de lien ou une supposition n'apprend rien. kv webhook deliveries en donne la raison.

Avec --signing, chaque envoi doit aussi porter ScreenRig-Signature: t=<unix seconds>,v1=<hex>, où v1 est le HMAC-SHA256 de t, d'un point et du corps brut sous le secret de signature whsec_…, et t doit être à moins de cinq minutes de l'horloge du serveur. C'est le format des signatures de webhook de screenRIG.

Signatures et poignées de main des fournisseurs

Les fournisseurs signent leurs envois à leur façon, et certains ne peuvent pas envoyer votre secret du tout. Un webhook de carte peut vérifier la signature du fournisseur à la place du secret et répondre à la poignée de main de configuration du fournisseur : GitHub, Stripe, Shopify, Slack, Linear, Vercel, Asana, Microsoft Graph, monday.com, Trello et Azure Event Grid y envoient donc directement, sans relais. Tout autre expéditeur qui signe avec HMAC fonctionne aussi. Définissez-les avec --verify et --handshake sur kv webhook create, et modifiez-les avec kv webhook update.

  • --verify VENDOR accepte la signature propre à un fournisseur, avec --verify-secret-file FILE (ou - pour stdin, jamais en argument) qui contient le secret que le fournisseur affiche. Pour generic_hmac, --verify-header NAME nomme l’en-tête qui porte la signature, --verify-encoding vaut hex (par défaut) ou base64, --verify-timestamp-header NAME nomme un en-tête qui porte l’heure Unix, et --verify-tolerance SECONDS indique de combien elle peut s’écarter de l’horloge du serveur (300 par défaut). Un envoi qui porte la signature valide du fournisseur est accepté sans le secret srkw_ propre au webhook, qui continue de fonctionner à côté. Le secret du fournisseur est stocké chiffré et affiché seulement sous la forme set et d’un hint de ses quatre derniers caractères. Avec kv webhook update, --verify sans --verify-secret-file conserve le secret stocké tant que le fournisseur reste le même, et --clear-verify supprime la vérification et son secret. --verify et --signing s’excluent mutuellement.
  • --handshake VENDOR est microsoft_graph, monday, trello ou azure_event_grid, et --clear-handshake le supprime. Slack et Asana répondent à leurs propres poignées de main par --verify.
--verifyEn-têteCe qui est signéHorodatage
githubX-Hub-Signature-256HMAC-SHA256 du corpsAucun
stripeStripe-SignatureHMAC-SHA256 de l’horodatage, d’un point et du corps ; n’importe quel v1 peut correspondre5 minutes
shopifyX-Shopify-Hmac-Sha256HMAC-SHA256 du corps, en base64Aucun
slackX-Slack-SignatureHMAC-SHA256 de v0:, de l’horodatage, de deux-points et du corpsX-Slack-Request-Timestamp, 5 minutes
linearLinear-SignatureHMAC-SHA256 du corpswebhookTimestamp dans le corps, 1 minute
vercelx-vercel-signatureHMAC-SHA1 du corpsAucun
asanaX-Hook-SignatureHMAC-SHA256 du corps, avec pour clé le X-Hook-Secret de la poignée de mainAucun
generic_hmacLe --verify-header que vous nommezHMAC-SHA256 du corps ou, avec un --verify-timestamp-header, de l’horodatage, d’un point et du corps--verify-tolerance

La clé de chaque HMAC est le texte du secret tel que le fournisseur l’affiche (celui de Stripe comprend whsec_). Une signature est vérifiée sur le corps exactement tel qu’il est arrivé, en temps constant, avant que l’envoi ne consomme du budget d’écriture, et elle est jugée avant son horodatage : timestamp_stale signifie toujours que le secret était le bon. Un corps peut être du JSON, un formulaire ou multipart/form-data, où un champ de texte est body.FIELD et où les fichiers sont comptés, non lus.

FournisseurscreenRIG répondEnvois suivants
Slack (--verify slack)Le url_verification signé avec son challenge ; une personne qui teste avec curl peut envoyer le secret du webhook à la placeSignés avec le secret de signature
Asana (--verify asana)Le X-Hook-Secret de la poignée de main, qu’il garde chiffré comme clé de chaque X-Hook-Signature. Le même secret de nouveau est une relance ; un secret différent est refusé avec handshake_invalidX-Hook-Signature
Microsoft Graph (--handshake microsoft_graph)Le ?validationToken= décodé comme text/plainPortent le secret du webhook
monday.com (--handshake monday)Le challenge qu’il envoie, renvoyé en JSONPortent le secret du webhook
Trello (--handshake trello)Une vérification HEAD répond 200 sans corps, pour ce webhook seulementPortent le secret du webhook
Azure Event Grid (--handshake azure_event_grid){"validationResponse": "CODE"}Portent le secret du webhook

Une poignée de main n’est traitée que pour un webhook configuré pour ce fournisseur, avant qu’aucun identifiant ne soit demandé, pour une requête qui est cette poignée de main, et jamais par un webhook désactivé. Elle n’écrit rien, n’est jamais facturée et ne consomme aucun budget de débit. Microsoft Graph, monday.com, Trello et Azure Event Grid n’envoient aucun en-tête que screenRIG vérifie : leurs envois ne sont donc acceptés qu’avec le secret du webhook. Azure Event Grid le transmet comme un en-tête de livraison statique, Authorization: Bearer srkw_…, marqué secret, et ses événements arrivent sous forme de tableau : un mappage lit donc body[0].

FournisseurDans les paramètres du fournisseur
GitHubSettings, Webhooks, Add webhook : l’URL de charge utile est le url du webhook, le type de contenu est application/json, et le même secret. Le ping de GitHub est signé et accepté
StripeWorkbench, Webhooks : ajoutez le url et affichez son secret de signature. Pendant que Stripe fait pivoter un secret, il envoie un v1 pour chacun et l’un ou l’autre est accepté ; remplacez ensuite le secret stocké avec kv webhook update --verify stripe --verify-secret-file FILE
ShopifyAbonnez-vous avec le url au format JSON. Le secret est le secret client de l’application
SlackL’URL de requête de l’API Events est le url, et le secret est le secret de signature de l’application. Une commande à barre oblique envoie un formulaire : {{body.text}}, {{body.user_name}}
LinearDans les paramètres de l’API, créez un webhook avec le url et copiez son secret de signature. Le webhookTimestamp du corps doit se situer à une minute de l’horloge du serveur
VercelTeam settings, Webhooks : créez-en un avec le url. Vercel affiche le secret une seule fois
AsanaCréez le webhook avec --verify asana : il n’a pas encore de secret et refuse les événements avec secret_pending. Créez ensuite le webhook Asana avec target réglé sur le url, et la poignée de main définit le secret. Pour prendre un nouveau secret, exécutez kv webhook update avec --clear-verify, puis de nouveau avec --verify asana
Microsoft GraphCréez l’abonnement avec notificationUrl réglé sur le url
monday.comExécutez create_webhook avec le url
TrelloPOST /1/webhooks avec callbackURL réglé sur le url
Azure Event GridCréez l’abonnement aux événements avec le url comme point de terminaison du webhook, et ajoutez l’en-tête de livraison ci-dessus
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 expéditeur qui signe avec son propre HMAC nomme l’en-tête, l’encodage et, s’il signe un horodatage, l’en-tête d’horodatage :

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"

Chaque échec donne le même 404 que tout autre refus. kv webhook deliveries montre la raison, et une poignée de main apparaît avec le résultat handshake :

RaisonSens
signature_missingUne vérification du fournisseur est définie et l’envoi ne portait ni le secret ni l’en-tête du fournisseur
signature_invalidL’en-tête est mal formé ou ne correspond pas au corps
timestamp_missingLa signature exige un horodatage que l’envoi ne portait pas
timestamp_staleLa signature est valide et son horodatage est hors de la fenêtre
secret_pendingUne vérification Asana attend encore sa poignée de main
handshake_invalidLa requête est la poignée de main d’un fournisseur et ne peut pas recevoir de réponse

kv webhook update#

Modifier un webhook de carte : sa description, son mappage, ses documents par clé, son état activé, sa signature, la vérification du fournisseur ou la poignée de main.

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]
ParamètreTypeRequisPar défautNotes
<webhook_id>stringouiaucunL’identifiant de webhook kvw_.
--card CARD_IDstringouiaucunL'identifiant de carte crd_.
--description TEXTstringnonaucunCe qui y envoie, au maximum 200 octets. Il ne doit pas contenir de justificatif.
--map FILEcheminnonaucunRemplacer le mappage par un objet JSON lu depuis un fichier, ou - pour stdin. Incompatible avec --clear-map.
--clear-mapbooleannondésactivéSupprimer le mappage : l'objet envoyé devient le document.
--key-template TEMPLATEstringnonaucunDéfinit le modèle de clé qui indexe les documents, comme room-{screen.field.room}. Incompatible avec --clear-key-template.
--clear-key-templatebooleannondésactivéRevient à écrire le document propre à la carte.
--enable / --disablebooleannondésactivé--disable répond à chaque envoi comme à un mauvais secret jusqu'à --enable.
--signing / --no-signingbooleannondésactivé--signing exige l’en-tête de signature et affiche le secret de signature une fois ; un webhook qui signe déjà garde son secret, que kv webhook rotate-secret --signing remplace. --no-signing cesse de l’exiger. Incompatible avec --verify.
--verify VENDORstringnonaucunRemplace la vérification du fournisseur : github, stripe, shopify, slack, linear, vercel, asana ou generic_hmac. Sans --verify-secret-file, le secret stocké est conservé si le fournisseur est le même, de sorte qu’un en-tête ou une fenêtre peut changer seul ; un autre fournisseur a besoin du sien. Incompatible avec --clear-verify.
--verify-secret-file FILEcheminnonle secret stockéLit le secret du fournisseur depuis un fichier, ou - pour stdin (jamais en argument). asana n’en prend aucun. Une seule option lit stdin.
--verify-header NAMEstringavec generic_hmacaucunL’en-tête qui porte la signature, de 1 à 100 lettres, chiffres, - ou _.
--verify-encoding ENCODINGstringnonhexAvec generic_hmac : hex ou base64 ; elle peut commencer par sha256=.
--verify-timestamp-header NAMEstringnonaucunAvec generic_hmac : un en-tête qui porte l’heure Unix en secondes, ou en millisecondes sur 13 chiffres.
--verify-tolerance SECONDSintegernon300Avec --verify-timestamp-header : de combien l’horodatage peut s’écarter de l’horloge du serveur, de 1 à 86400.
--clear-verifybooleannondésactivéCesse d’accepter la signature du fournisseur et oublie son secret. Une vérification Asana n’accepte une nouvelle poignée de main qu’après --clear-verify puis de nouveau --verify asana.
--handshake VENDORstringnonaucunDéfinit la poignée de main à laquelle l’URL répond : microsoft_graph, monday, trello ou azure_event_grid. Incompatible avec --clear-handshake.
--clear-handshakebooleannondésactivéCesse de répondre à la poignée de main du fournisseur.

Au moins un changement est requis.

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

L’enveloppe est le webhook. data.signing_secret n’apparaît qu’une fois, dans la réponse qui a activé la signature. Après une mise à jour interrompue ou ambiguë, relancez la même commande : elle réutilise la clé d’idempotence enregistrée.

kv webhook deliveries#

Lire le journal de livraison d'un webhook de carte, du plus récent au plus ancien, pour les sept derniers jours.

kv webhook deliveries <webhook_id> --card CARD_ID [--limit N]
ParamètreTypeRequisPar défautNotes
<webhook_id>stringouiaucunL’identifiant de webhook kvw_.
--card CARD_IDstringouiaucunL'identifiant de carte crd_.
--limit Nnumbernon100Nombre de livraisons à retourner, de 1 à 100.
screenrig kv webhook deliveries kvw_01EXAMPLEWEBHOOK00000 --card crd_01EXAMPLEBOARD0000000000

Chaque élément a at, outcome (written, unchanged, refused, invalid ou handshake), reason (credentials, signature pour un ScreenRig-Signature échoué, disabled, body, mapping, card_data_invalid, rate_limited, internal, ou une raison propre au fournisseur du tableau ci-dessus), detail, status, bytes, files (les parties fichier d’un envoi multipart, qui sont ignorées), revision et request_id. Aucun corps, en-tête ni identifiant n’est stocké, et un envoi à une mauvaise adresse ne laisse aucune ligne.

Autres groupes de commandes