Cartões
Conheça os tipos de cartões, crie uma instância e atualize seus dados ao vivo. Uma playlist posiciona o ID do cartão retornado.
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âmetro | Tipo | Obrigatório | Padrão | Notas |
|---|---|---|---|---|
cards list --tag TAG | string | não | nenhum | Corresponde a uma tag do catálogo. |
cards list --category CATEGORY | string | não | nenhum | Corresponde a uma categoria do catálogo. Com --tag, um cartão precisa corresponder a ambas. |
cards show <id> | string | sim | nenhum | O id de cartão do catálogo obtido de cards list, como gauge. |
card create --type ID | string | sim | nenhum | O id de cartão do catálogo obtido de cards list. |
card create --major N | integer | não | versão principal atual | Fixa uma versão principal do catálogo. |
card create --file FILE | caminho | sim | nenhum | Os parâmetros estáticos como objeto JSON de no máximo 1 MiB, ou - para stdin. |
<id> | string | sim | nenhum | O id de cartão crd_ que card show, card params, card delete e card data aceitam. |
card params --file FILE | caminho | sim | nenhum | Os novos parâmetros estáticos, lidos como em card create. Substituem os antigos imediatamente. |
card data put --file FILE | caminho | sim | nenhum | O documento de dados como objeto JSON, ou - para stdin. Substitui todo o documento. |
card data put --ttl DURATION | string | não | nenhum | Deixa os dados em branco depois desse tempo, inclusive nas telas offline: 30m, 12h ou 1d, de 1s a 365d. Não se combina com --expires-at. |
card data put --expires-at INSTANT | string | não | nenhum | Deixa os dados em branco neste carimbo de data e hora ISO 8601, que traz um fuso horário. Uma gravação sem nenhuma das duas opções limpa a expiração anterior. |
card data put --expect-rev REVISION | string | não | nenhum | Grava somente se os dados ainda estiverem nesta revisão, conforme mostrada por card data get. Um valor desatualizado é revision_conflict (saída 6). |
card preview <type|id> | string | sim | nenhum | Um id de cartão do catálogo, ou um id de cartão crd_ para desenhar essa instância com seus próprios parâmetros e dados. |
card preview --output FILE | caminho | sim | nenhum | Grava o PNG aqui. Os diretórios pai são criados. |
card preview --params FILE | caminho | não | nenhum | Propriedades estáticas como um objeto JSON. |
card preview --data FILE | caminho | não | nenhum | O documento dinâmico como objeto JSON. |
card preview --feed FILE | caminho | não | nenhum | O documento de feed do host como objeto JSON. Um feed de que o cartão precisa e que você omite é informado. |
card preview --width PX / --height PX | integer | não | 1920 / 1080 | Tamanho da imagem, de 1 a 8192. |
card preview --layout LAYOUT | string | não | full | full, free, center, wide, header, footer, corner, chip ou strip: o layout a desenhar. |
card preview --anchor ANCHOR | string | não | nenhum | O canto de um layout corner ou chip, ou a borda de um strip. |
card preview --now ISO | string | não | a hora atual | Congela o relógio neste instante ISO 8601. |
card preview --timezone ZONE | string | não | o desta máquina | Desenha neste fuso horário IANA, como America/Vancouver. |
cards show mostra o params_schema e o data_schema do cartão, suas propriedades estáticas e dinâmicas, nível, layouts e feed, e um exemplo para copiar em uma página de playlist. card create retorna o id crd_ da instância, e uma nova execução idêntica após uma resposta perdida reutiliza a chave de idempotência salva.
card data put substitui o documento imediatamente, sem republicar a playlist. A validação do próprio cartão recusa um documento que ele não consegue mostrar (card_data_invalid), e uma expiração deixa os dados em branco em todas as telas quando nada os renova. card delete exclui a instância e seus dados, e responde resource_conflict (saída 5) enquanto uma playlist a posicionar.
card preview desenha o cartão em um Chromium ou Chrome local e grava um PNG; não publica nada. Defina SCREENRIG_BROWSER com o caminho do navegador quando nenhum dos habituais estiver instalado. data.file é o caminho gravado e data.unrendered lista o que a pré-visualização não conseguiu desenhar, como um feed do host que você não forneceu. Abra a imagem antes de publicar. Cartões embutidos descreve os layouts, as propriedades e os feeds de cada cartão.
Webhooks de cartão
Um webhook de cartão é uma URL que grava o documento de dados de um cartão, de modo que um sistema externo, como um CMS, um ponto de venda ou um script, envia dados para um cartão com um único POST HTTP. kv webhook create, list, rotate-secret e delete aceitam --card CARD_ID no lugar de --app-id, nunca os dois; update e deliveries abaixo funcionam apenas com cartões. Um cartão tem no 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_IDCriar um webhook de cartão não exige chave. --map FILE (ou - para stdin) é o mapeamento, --key-template grava documentos por chave, --signing ativa a assinatura, e --verify e --handshake aceitam as postagens próprias de um fornecedor (Assinaturas e handshakes dos fornecedores). A resposta traz data.secret e, quando o webhook assina, data.signing_secret, cada um exibido uma única vez.
O remetente se autentica como em um webhook de aplicativo: Authorization: Bearer <secret> com o segredo srkw_…, ou HTTP Basic com o ID do webhook como nome de usuário, então https://kvw_ID:srkw_…@api.screenrig.ai/… serve para um remetente que aceita apenas uma URL. O corpo, de no máximo 1 MiB, é JSON ou application/x-www-form-urlencoded; um nome de formulário repetido vira um array. Sem mapeamento, o objeto enviado é o documento de dados do cartão.
Um mapeamento é um modelo JSON que constrói o documento a partir do corpo. Uma string com marcadores como {{body.alert.title}} ou {{body.items[0].name}} é texto, e uma string que é exatamente um marcador mantém o tipo do valor. Um caminho começa com body ou query (os parâmetros de consulta da URL), e um caminho que não contém nada fica vazio no texto e omite um valor isolado. $each mapeia um array com item e index no escopo, $group com $by agrupa na ordem da primeira ocorrência, $number lê 1,234.50, $3.50, 3,50 € ou 12% (adicione "$decimal": "," para uma vírgula decimal), $bool lê true, yes, y, 1 e x, e $text com $max corta o texto. O modelo é verificado ao salvar: invalid_request indica o lugar que falhou.
{
"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 grava documentos por chave no lugar do documento próprio do cartão. O modelo é uma chave de dados do cartão com tokens {screen.field.NAME}, como room-{screen.field.room}, e o objeto mapeado (ou o corpo postado, sem mapeamento) contém apenas um array documents de objetos {fields, document}: cada objeto fields preenche o modelo e cada document é gravado na chave que ele produz. Um item de página que informa o mesmo modelo como seu data mostra a cada tela o documento dos seus próprios campos. Cada documento é verificado antes de gravar qualquer um, e uma chave repetida é recusada. Uma falha de armazenamento pode deixar parte do lote gravada: reenvie o mesmo corpo com o mesmo Idempotency-Key. As chaves que uma postagem omite mantêm seus dados, e um webhook não define expiração. Documentos por chave mostra um mapeamento.
Cada envio é verificado como dados do próprio cartão: card_data_invalid nomeia o caminho e nada é gravado. Um documento igual ao atual do cartão recebe a resposta unchanged e não grava nada, então nenhuma tela é acordada. Um envio aceito não conta no limite de solicitações de agente, um webhook aceita no máximo 120 envios por minuto e um cabeçalho Idempotency-Key deduplica as novas tentativas de um remetente por 24 horas.
Um endereço errado, um segredo errado ou ausente, um webhook desativado, uma assinatura ausente ou errada e todo GET recebem a mesma resposta 404, então uma pré-visualização de link ou um palpite não revela nada. kv webhook deliveries informa o motivo.
Com --signing, cada envio também deve levar ScreenRig-Signature: t=<unix seconds>,v1=<hex>, em que v1 é o HMAC-SHA256 de t, um ponto e o corpo bruto com o segredo de assinatura whsec_…, e t deve estar a no máximo cinco minutos do relógio do servidor. É o formato das assinaturas de webhook do próprio screenRIG.
Assinaturas e handshakes dos fornecedores
Os fornecedores assinam suas postagens do seu jeito, e alguns não conseguem enviar o seu segredo de jeito nenhum. Um webhook de cartão pode verificar a assinatura do fornecedor no lugar do segredo e responder ao handshake de configuração do fornecedor, então GitHub, Stripe, Shopify, Slack, Linear, Vercel, Asana, Microsoft Graph, monday.com, Trello e Azure Event Grid postam direto nele, sem intermediário. Qualquer outro remetente que assine com HMAC também funciona. Defina-os com --verify e --handshake em kv webhook create e altere-os com kv webhook update.
--verify VENDORaceita a assinatura própria de um fornecedor, com--verify-secret-file FILE(ou-para stdin, nunca como argumento) contendo o segredo que o fornecedor mostra. Parageneric_hmac,--verify-header NAMEnomeia o cabeçalho que carrega a assinatura,--verify-encodingéhex(o padrão) oubase64,--verify-timestamp-header NAMEnomeia um cabeçalho que carrega a hora Unix, e--verify-tolerance SECONDSé o quanto ela pode se afastar do relógio do servidor (300 por padrão). Uma postagem que traz a assinatura válida do fornecedor é aceita sem o segredosrkw_do próprio webhook, que continua funcionando ao lado. O segredo do fornecedor é armazenado selado e mostrado apenas comosete umahintdos seus quatro últimos caracteres. Emkv webhook update,--verifysem--verify-secret-filemantém o segredo armazenado enquanto o fornecedor for o mesmo, e--clear-verifyremove a verificação e seu segredo.--verifye--signingse excluem mutuamente.--handshake VENDORémicrosoft_graph,monday,trelloouazure_event_grid, e--clear-handshakeo remove. O Slack e o Asana respondem aos próprios handshakes por--verify.
--verify | Cabeçalho | O que é assinado | Carimbo de data e hora |
|---|---|---|---|
github | X-Hub-Signature-256 | HMAC-SHA256 do corpo | Nenhum |
stripe | Stripe-Signature | HMAC-SHA256 do carimbo de data e hora, um ponto e o corpo; qualquer v1 pode corresponder | 5 minutos |
shopify | X-Shopify-Hmac-Sha256 | HMAC-SHA256 do corpo, em base64 | Nenhum |
slack | X-Slack-Signature | HMAC-SHA256 de v0:, o carimbo de data e hora, dois-pontos e o corpo | X-Slack-Request-Timestamp, 5 minutos |
linear | Linear-Signature | HMAC-SHA256 do corpo | webhookTimestamp no corpo, 1 minuto |
vercel | x-vercel-signature | HMAC-SHA1 do corpo | Nenhum |
asana | X-Hook-Signature | HMAC-SHA256 do corpo, com o X-Hook-Secret do handshake como chave | Nenhum |
generic_hmac | O --verify-header que você nomeia | HMAC-SHA256 do corpo ou, com um --verify-timestamp-header, do carimbo de data e hora, um ponto e o corpo | --verify-tolerance |
A chave de cada HMAC é o texto do segredo como o fornecedor o mostra (o do Stripe inclui whsec_). Uma assinatura é conferida no corpo exatamente como chegou, em tempo constante, antes de a postagem consumir orçamento de escrita, e é julgada antes do seu carimbo de data e hora: timestamp_stale sempre significa que o segredo estava certo. Um corpo pode ser JSON, um formulário ou multipart/form-data, em que um campo de texto é body.FIELD e os arquivos são contados, não lidos.
| Fornecedor | O screenRIG responde | Postagens seguintes |
|---|---|---|
Slack (--verify slack) | O url_verification assinado com o seu challenge; uma pessoa que testa com curl pode enviar o segredo do webhook no lugar | Assinadas com o segredo de assinatura |
Asana (--verify asana) | O X-Hook-Secret do handshake, que ele guarda selado como chave de cada X-Hook-Signature. O mesmo segredo de novo é uma nova tentativa; um diferente é recusado como handshake_invalid | X-Hook-Signature |
Microsoft Graph (--handshake microsoft_graph) | O ?validationToken= decodificado como text/plain | Levam o segredo do webhook |
monday.com (--handshake monday) | O challenge que ele posta, devolvido como JSON | Levam o segredo do webhook |
Trello (--handshake trello) | Uma verificação HEAD responde 200 sem corpo, só para este webhook | Levam o segredo do webhook |
Azure Event Grid (--handshake azure_event_grid) | {"validationResponse": "CODE"} | Levam o segredo do webhook |
Um handshake só é respondido para um webhook configurado para esse fornecedor, antes de qualquer credencial ser pedida, a uma solicitação que é esse handshake, e nunca por um webhook desativado. Ele não grava nada, nunca é cobrado e não gasta orçamento de taxa. O Microsoft Graph, o monday.com, o Trello e o Azure Event Grid não enviam nenhum cabeçalho que o screenRIG verifique, então as entregas deles só são aceitas com o segredo do webhook. O Azure Event Grid o leva como um cabeçalho de entrega estático, Authorization: Bearer srkw_…, marcado como segredo, e seus eventos chegam como um array, então um mapeamento lê body[0].
| Fornecedor | Nas configurações do fornecedor |
|---|---|
| GitHub | Settings, Webhooks, Add webhook: a Payload URL é a url do webhook, o tipo de conteúdo é application/json, e o mesmo segredo. O ping do GitHub é assinado e aceito |
| Stripe | Workbench, Webhooks: adicione a url e revele o segredo de assinatura dela. Enquanto o Stripe faz a rotação de um segredo, ele envia um v1 para cada um e qualquer um é aceito; depois substitua o segredo armazenado com kv webhook update --verify stripe --verify-secret-file FILE |
| Shopify | Assine com a url no formato JSON. O segredo é o segredo de cliente do aplicativo |
| Slack | A Request URL da Events API é a url, e o segredo é o segredo de assinatura do aplicativo. Um comando de barra posta um formulário: {{body.text}}, {{body.user_name}} |
| Linear | Nas configurações da API, crie um webhook com a url e copie o segredo de assinatura dele. O webhookTimestamp do corpo precisa estar a até um minuto do relógio do servidor |
| Vercel | Team settings, Webhooks: crie um com a url. O Vercel mostra o segredo uma única vez |
| Asana | Crie o webhook com --verify asana: ele ainda não tem segredo e recusa eventos como secret_pending. Depois crie o webhook do Asana com target definido como a url, e o handshake define o segredo. Para adotar um novo segredo, execute kv webhook update com --clear-verify e depois de novo com --verify asana |
| Microsoft Graph | Crie a assinatura com notificationUrl definido como a url |
| monday.com | Execute create_webhook com a url |
| Trello | POST /1/webhooks com callbackURL definido como a url |
| Azure Event Grid | Crie a assinatura de eventos com a url como endpoint do webhook, e adicione o cabeçalho de entrega acima |
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 -
Um remetente que assina com o próprio HMAC nomeia o cabeçalho, a codificação e, se assina um carimbo de data e hora, o cabeçalho do carimbo:
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"
Toda falha dá o mesmo 404 de qualquer outra recusa. kv webhook deliveries mostra o motivo, e um handshake aparece com o resultado handshake:
| Motivo | Significado |
|---|---|
signature_missing | Há uma verificação de fornecedor definida e a postagem não trazia nem o segredo nem o cabeçalho do fornecedor |
signature_invalid | O cabeçalho está malformado ou não corresponde ao corpo |
timestamp_missing | A assinatura precisa de um carimbo de data e hora que a postagem não trazia |
timestamp_stale | A assinatura é válida e o carimbo de data e hora dela está fora da janela |
secret_pending | Uma verificação do Asana ainda está esperando o handshake |
handshake_invalid | A solicitação é o handshake de um fornecedor e não pode ser respondida |
kv webhook update#
Alterar um webhook de cartão: sua descrição, mapeamento, documentos por chave, estado ativado, assinatura, verificação de fornecedor ou 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âmetro | Tipo | Obrigatório | Padrão | Notas |
|---|---|---|---|---|
<webhook_id> | string | sim | nenhum | O id do webhook kvw_. |
--card CARD_ID | string | sim | nenhum | O ID de cartão crd_. |
--description TEXT | string | não | nenhum | O que envia para ele, no máximo 200 bytes. Não deve conter credenciais. |
--map FILE | caminho | não | nenhum | Substituir o mapeamento por um objeto JSON lido de um arquivo, ou - para stdin. Não se combina com --clear-map. |
--clear-map | boolean | não | desligado | Remover o mapeamento: o objeto enviado passa a ser o documento. |
--key-template TEMPLATE | string | não | nenhum | Define o modelo de chave que dá a chave aos documentos, como room-{screen.field.room}. Não se combina com --clear-key-template. |
--clear-key-template | boolean | não | desligado | Volta a gravar o documento próprio do cartão. |
--enable / --disable | boolean | não | desligado | --disable responde a cada envio como a um segredo errado até --enable. |
--signing / --no-signing | boolean | não | desligado | --signing exige o cabeçalho de assinatura e mostra o segredo de assinatura uma vez; um webhook que já assina mantém o seu segredo, que kv webhook rotate-secret --signing substitui. --no-signing deixa de exigi-lo. Não se combina com --verify. |
--verify VENDOR | string | não | nenhum | Substitui a verificação do fornecedor: github, stripe, shopify, slack, linear, vercel, asana ou generic_hmac. Sem --verify-secret-file, o segredo armazenado é mantido se o fornecedor for o mesmo, de modo que um cabeçalho ou uma janela pode mudar sozinho; um fornecedor diferente precisa do seu. Não se combina com --clear-verify. |
--verify-secret-file FILE | caminho | não | o segredo armazenado | Lê o segredo do fornecedor de um arquivo, ou - para stdin (nunca como argumento). asana não aceita nenhum. Apenas uma opção lê stdin. |
--verify-header NAME | string | com generic_hmac | nenhum | O cabeçalho que carrega a assinatura, de 1 a 100 letras, dígitos, - ou _. |
--verify-encoding ENCODING | string | não | hex | Com generic_hmac: hex ou base64; pode começar com sha256=. |
--verify-timestamp-header NAME | string | não | nenhum | Com generic_hmac: um cabeçalho que carrega a hora Unix em segundos ou em milissegundos com 13 dígitos. |
--verify-tolerance SECONDS | integer | não | 300 | Com --verify-timestamp-header: o quanto o carimbo de data e hora pode se afastar do relógio do servidor, de 1 a 86400. |
--clear-verify | boolean | não | desligado | Deixa de aceitar a assinatura do fornecedor e esquece seu segredo. Uma verificação do Asana só aceita um novo handshake depois de --clear-verify e de novo --verify asana. |
--handshake VENDOR | string | não | nenhum | Define o handshake que a URL responde: microsoft_graph, monday, trello ou azure_event_grid. Não se combina com --clear-handshake. |
--clear-handshake | boolean | não | desligado | Deixa de responder ao handshake do fornecedor. |
Pelo menos uma alteração é obrigatória.
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-verifyO envelope é o webhook. data.signing_secret aparece uma só vez, na resposta que ativou a assinatura. Após uma atualização interrompida ou ambígua, execute novamente o comando idêntico: ele reutiliza a chave de idempotência salva.
kv webhook deliveries#
Ler o log de entregas de um webhook de cartão, do mais recente para o mais antigo, dos últimos sete dias.
kv webhook deliveries <webhook_id> --card CARD_ID [--limit N]| Parâmetro | Tipo | Obrigatório | Padrão | Notas |
|---|---|---|---|---|
<webhook_id> | string | sim | nenhum | O id do webhook kvw_. |
--card CARD_ID | string | sim | nenhum | O ID de cartão crd_. |
--limit N | number | não | 100 | Quantas entregas retornar, de 1 a 100. |
screenrig kv webhook deliveries kvw_01EXAMPLEWEBHOOK00000 --card crd_01EXAMPLEBOARD0000000000Cada item tem at, outcome (written, unchanged, refused, invalid ou handshake), reason (credentials, signature para uma ScreenRig-Signature que falhou, disabled, body, mapping, card_data_invalid, rate_limited, internal ou um motivo de fornecedor da tabela acima), detail, status, bytes, files (as partes de arquivo de uma postagem multipart, que são ignoradas), revision e request_id. Nenhum corpo, cabeçalho ou credencial é armazenado, e uma postagem para um endereço errado não deixa linha.