ドキュメント

外部のアドレスからカードを最新に保つ

データソースは、screenRIG がスケジュールに従って読み取るアドレスです。見つけた内容を 1 枚のカードのデータに書き込むため、誰も再公開しなくてもカードは最新のままで、カードを表示しているすべてのスクリーンは、変更があるとドキュメントを再取得します。Google、Outlook、iCloud、Nextcloud のカレンダーはアジェンダや会議室ボードに、シートや API はメニューや KPI ボードになり、プリセットを使えば Slack チャンネル、Google レビュー、求人ボードがカードになります。

ソースの仕組み

  • 1 つのソースに 1 枚のカード。 ソースは、データを入れるカードを指定します。1 枚のカードにソースは最大 1 つで、組織ではすべてのプロジェクトを合わせて最大 200 まで作成できます。
  • スケジュールに従って実行されます。 カレンダーのソースは 5 分ごとに同期し、すべてのソースは 1 分から 24 時間の間で設定できます。ソースは作成または変更の数秒後に実行され、source refresh ですぐに同期できます。
  • 同期に失敗してもカードは変更されません。 カードは最後に成功したドキュメントを保持し、ソースのステータスに問題の内容が表示されます。失敗は自動的に再試行され、失敗のたびに待機時間が長くなります。
  • 変更だけが書き込まれます。 同期の結果がカードの内容と同じなら、何も書き込まれず、スクリーンも起こされません。
  • 同期は無料です。 ドキュメントは、ほかの書き込みと同じようにカードデータのストレージとして計上されます。
  • 認証情報は暗号化して保存されます。 アクセス権を与えるアドレスは暗号化して保存され、スキームとホストだけが返され、ログ、エラー、プロジェクトのイベントログには一切現れません。
  • 最後の正常なデータを、選んだ期間だけ保持します。 データソースが更新できないとき、そのカードはデータソースの有効期間(--stale-after、1 分から 7 日。会場予約のデータソースは 30 分)だけ最後の正常なデータを保持し、その後データはオフラインのものを含むすべてのスクリーンで期限切れになり、それに依存するページは後続のページに切り替わります。期間を指定しない場合、最後の正常なデータはデータソースが再び更新されるまで残ります。データソースが更新できないときを参照してください。

プリセットから始める

プリセットは、スクリーンに表示されることの多いサービス向けに用意されたソースです。1 つ選び、いくつかの項目を入力し、サービスが発行する認証情報を追加すると、screenRIG がソースを作り、回答をカードにマッピングします。プリセットは json ソースで、どのプランにも含まれます。

プリセットカード必要なもの
slack-channelworkplace-posts, message-wallチャンネル ID と、ワークスペース内の社内用 Slack アプリのボットトークン (xoxb-…)。api.slack.com/apps でスコープ channels:history と groups:history を追加し、アプリをインストールしてから、チャンネルに追加します
bonuslykudosrecognition:read を持つ Bonusly のアクセストークン。Global または Tech の管理者が Company、Integrations、API & Tokens で作成します
facebook-pagesocial-wallページ ID、表示する名前、そして Graph API エクスプローラーで取得する、pages_read_engagement と pages_show_list を持つページアクセストークン
instagram-businesssocial-wallInstagram アカウント ID、表示する名前、そして instagram_basic、pages_show_list、pages_read_engagement を持つ、リンクされた Facebook ページのアクセストークン
google-reviewsreviewsプレイス ID と、Places API (New) を有効にした Google Cloud の API キー
google-travel-timestravel-times出発地の住所、1 〜 8 件の目的地、車か公共交通機関の別、そして Routes API を有効にした Google Cloud の API キー
greenhouse-jobsnow-hiringboards.greenhouse.io/TOKEN のボードトークン。認証情報は不要です。ボードは公開されています
lever-jobsnow-hiringjobs.lever.co/NAME のサイト名とリージョン。認証情報は不要です
ashby-jobsnow-hiringjobs.ashbyhq.com/NAME のボード名。認証情報は不要です
github-actionsbuild-boardオーナー、リポジトリ、ブランチ、そしてそのリポジトリの Actions への読み取り専用アクセスを持つ細粒度のパーソナルアクセストークン (github.com/settings/personal-access-tokens で作成)

ダッシュボード、エージェント、API は、各項目のヘルプ文と例、各認証情報の取得手順とともにプリセットを一覧表示します。GET /api/source-presets はすべてを返し、GET /api/source-presets/NAME は 1 つを返します (API リファレンスのデータソースのグループ)。プリセットからソースを作成するには、kind と config の代わりに preset、settings、secrets を使います。認証情報はコマンドラインではなくリクエストファイルに入れ、BOT_TOKEN をトークンに置き換えてください。

{
  "name": "Announcements",
  "preset": "slack-channel",
  "target": {"card_id": "crd_CARD"},
  "settings": {"channel": "C0123456789", "channel_label": "#announcements"},
  "secrets": {"token": "BOT_TOKEN"}
}
curl -sS https://api.screenrig.ai/api/sources/test \
  -H "Authorization: Bearer $SCREENRIG_TOKEN" -H "Content-Type: application/json" -d @source.json

POST /api/sources/test は、カードが表示するドキュメント、カードがそれを受け入れるかどうか、気づいた点を出力し、何も書き込みません。POST /api/sources は同じファイルを保存し、新しい settings を付けた PATCH /api/sources/ID は、プリセットからソースを作り直します。

  • あなたのアカウント、あなたの規約。 プリセットは、あなたが作成した認証情報であなた自身のアカウントを読み取り、サービスの規約に従います。カードは規約が求める内容を表示します。たとえば Google レビューは、Google のマークと各投稿者の名前とともに表示されます。
  • スケジュールと有効期限。 プリセットごとに、更新間隔と有効期間が決まっています。たとえば Slack は 1 分と 15 分、Google レビューは 6 時間と 24 時間です。ソースは別の間隔を選べますが、プリセットの最小値より短くはできません。同期に失敗すると、カードは有効期間が過ぎるまで最後のデータを保持し、その後は空白になります。
  • 課金はサービス側で発生します。 Google レビューの更新は 1 回ごとに、お使いの Google Cloud プロジェクトでの Place Details リクエスト 1 件になります。Google の所要時間の更新は 1 回ごとに、目的地ごとにルート要素 1 件です。4 件の目的地を 15 分ごとに更新すると、月あたり約 11,500 要素になります。
  • Slack には社内用のアプリが必要です。 配布しないでください。Slack は、Marketplace の外で配布されたアプリを 1 分あたり 1 リクエストに制限します。アプリは追加されたチャンネルだけを読み取り、カードには参加通知、ボットの投稿、チャンネルのお知らせではなく、人が書いたメッセージが表示されます。

ソースを作成する

まずカードを作成し、次にプレビューして、最後に保存します。

screenrig card create --type events --file events.json
screenrig source test --kind ics --card crd_CARD \
  --set 'calendars=[{"key":"lobby"}]' --set time_zone=America/Vancouver \
  --secret calendar_url.lobby=@lobby.url
screenrig source create --kind ics --card crd_CARD --name "Lobby calendar" \
  --set 'calendars=[{"key":"lobby"}]' --set time_zone=America/Vancouver \
  --secret calendar_url.lobby=@lobby.url
screenrig source show src_SOURCE

source test はアドレスを取得し、カード向けに整形して、結果をカードで検証します。何も保存せず、何も書き込みません。ドキュメント、カードが受け入れるかどうか、途中で気づいた点を表示します。アドレスはシェルの履歴に残らないよう、ファイル (@FILE) または標準入力 (-) で渡してください。

コマンド動作
source list, source show IDプロジェクトのソース。ステータス、設定、マスクされたシークレット付き
source createソースを保存し、数秒以内に実行します
source update ID名前、カード、設定 (--set KEY=VALUE または --settings JSON)、シークレット (--secret、--unset-secret)、スケジュール (--refresh 10m)、または --enable と --disable を変更します
source test保存済みかどうかにかかわらず、ソースを書き込みなしでプレビューします
source refresh IDすぐに同期して結果を表示します
source delete IDソースを削除します。カードは最後のドキュメントをそのまま保持します

--settings はソースの設定全体を JSON、@FILE、または - で受け取ります。CLI の --config オプションは認証情報ファイルを指すもので、ソースとは関係ありません。

データソースが更新できないとき

データソースは、各ドキュメントを期限付きで書き込みます。期限は書き込みからデータソースの有効期間後で、データソースが更新を続ける限り延長されます。データソースが動いている間は期限が先に進み続けます。失敗すると、カードは期限まで最後の正常なデータを表示し続け、その後データはオフラインのものを含むすべてのスクリーンで期限切れになります。

  • 期間を設定するには、source create または source update で --stale-after 30m を使います。1 分から 7 日までで、更新間隔の 2 倍以上にします。--stale-after none は最後の正常なデータを次の更新まで保持します。会場予約のデータソース(momentus)は指定がなければ 30 分保持し、ほかの種類は次の更新まで保持します。
  • 独自のコンテンツに切り替える。 visibility.data の条件がドキュメント(部屋の場合は momentus-room-{screen.field.room})を指しているページは、データがある間は表示され、期限が切れると次のページに切り替わります。その後ろに、ブランドを載せた通常のページを代替として置いておきます。
  • 確認する。 source show は stale_after、data_expires_at を表示し、データソースが失敗を続けてデータが期限切れになると stale: true も表示します。ダッシュボードのデータソースのページにも同じ内容が表示されます。失敗しているデータソースは「失敗中」、データが期限切れのものは「期限切れ」です。
  • 通知を受け取る。 条件 source_failed(更新に失敗した)と source_stale(データが期限切れになった)の通知は、スクリーンの場合と同じように、メールを送るか Slack、Teams、PagerDuty、Telegram に投稿します(screenrig notifications create --email owner --conditions source_failed,source_stale --hold 5)。通知にはデータソースの名前とそのページへのリンクが含まれ、更新が成功すると解消されます。--tag がデータソースに一致することはありません。

ステータスとエラー

各ソースにはステータスが表示されます。最後に実行した時刻、最後に成功した時刻、最後にカードを変更した時刻、次の実行時刻、連続して失敗した同期の回数、そして直近のエラーです。

状態意味
pendingソースはまだ実行されていません
ok直近の取得が成功し、カードがドキュメントを受け入れました
error直近の同期が失敗しました。カードは最後に成功したドキュメントを保持します
disabledスケジュールが停止しています

ok は、元のデータが正しいか最新かどうか、またどのスクリーンがカードを表示しているかは判断しません。

エラーコード発生した内容
unreachablescreenRIG はアドレスに到達できませんでした。ポート 80 または 443 の公開 http(s) アドレスを使ってください
timeoutアドレスが 20 秒以内に応答しませんでした
too_large応答が 5 MB を超えています
http_statusアドレスが HTTP エラーを返しました。404 は、アドレスがもう正しくないことを意味します
auth_failedアドレスが認証情報を拒否しました。次の試行は 1 時間後です
not_sharedGoogle スプレッドシートが共有されていません。Google がサインインページ、401、または 403 を返しました。「リンクを知っている全員」で共有するか、ウェブに公開してください
parse_failed応答がカレンダーではありません。ログインページはカレンダーではなくウェブページとして扱われます。カレンダーの ICS アドレスを使ってください
rate_limitedサービスがリクエストを制限しています。次の同期は待機します
mapping_failedメッセージが示す場所でマッピングが応答を読み取れませんでした。たとえば、配列が見つからない rows_path です
card_data_invalidカードは、メッセージが示すパスでドキュメントを拒否しました
target_missingカードが削除されました。ソースを別のカードに向けてください
payment_requiredプロジェクトのストレージがいっぱいのため、ドキュメントは書き込まれませんでした
config_invalid設定または保存済みのシークレットが使えなくなりました。もう一度入力してください
internal同期が screenRIG の内部で失敗しました。再試行されます

ソースの作成または変更では、source_target_taken(そのカードにはすでにソースがあります)、source_target_unsupported(この種類ではそのカードを埋められません。回答に埋められるカードが一覧されます)、source_secret_required(シークレットがない、または別のアドレス用に入力されていて、再入力が必要です)、source_limit_reached、source_busy(同期の実行中です。間隔をおいて再試行してください)が返ることがあります。アドレスを読み取れない場合、source test は理由とともに source_test_failed を返します。

カレンダー

カレンダーのソースは iCalendar (ICS) のアドレスを読み取ります。Google カレンダー、Outlook、iCloud、Nextcloud がカレンダーごとに発行する非公開アドレスや、あらゆる webcal:// リンクに対応します。すべてのカレンダーをまとめた予定表を events カードに、またはカレンダーごとに会議室を 1 つずつ study-rooms カードに入れます。

設定意味
calendars1〜60 件のカレンダー。それぞれ {key, name, floor, capacity} の形式で指定します。キーは小文字、数字、-、_ で構成します。名前、階、定員は会議室を説明します
days今日から何日分を表示するか。1〜31 で、既定は 7 です
time_zoneAmerica/Vancouver のような IANA タイムゾーン。1 日の区切りと、フィードがタイムゾーンなしで残した時刻に使われます
private_title非公開の予定に表示するタイトル(既定は Private)
include, excludeタイトルでイベントを残す、または非表示にするキーワード。キーワードでイベントを残す・隠すを参照してください

各カレンダーにはシークレットが 1 つあり、calendar_url.KEY にそのアドレスを入れます。

  • 繰り返しの予定(毎日、毎週、毎月、毎年のルール、例外、移動またはキャンセルされた回)とタイムゾーンはサーバー側で展開されるため、夏時間をまたいでも予定の時刻は保たれ、カードがカレンダーのルールを繰り返すことはありません。Outlook が使う Windows のタイムゾーン名にも対応しています。
  • 非公開の予定(CLASS:PRIVATE または CONFIDENTIAL)は、時間だけを表示し、非公開用のタイトルを使い、主催者と場所は表示しません。この規則は非公開とマークされた予定が対象で、それ以外の予定が明かす内容については判断しません。
  • 空き時間(透過または空きとマークされた予定)は予定表には残り、占有時間だけが対象となる会議室ボードでは除外されます。キャンセルされた予定は破棄され、仮の予定は埋まっているものとして扱われます。
  • 終日の予定は日付として表示されます。終了のない予定には終了が表示されません。
  • 警告。 フィードにタイムゾーンがない、screenRIG が判別できないタイムゾーンを使っている、1 つの予定の回数が 500 を超える、または予定が 5,000 件を超える場合でも、同期は成功し、ステータスに警告が表示されます。
  • 複数のカレンダーはまとめて同期されます。1 つでも失敗すると同期全体が失敗し、エラーにそのカレンダーの名前が示されるため、ボードに一部だけが表示されることはありません。

キーワードでイベントを残す・隠す

ics、microsoft365、google_calendar、momentus のソースには、任意の設定 include と exclude が 2 つあり、どちらも 1 〜 20 個のキーワード (各 1 〜 100 文字) のリストです。イベントは、タイトルに include のキーワードが少なくとも 1 つ含まれ (include を設定した場合)、exclude のキーワードが 1 つも含まれないときに残ります。キーワードは、大文字と小文字やアクセントの違いを区別せずにタイトルの中で一致するため、café と CAFE は互いに一致します。

  • タイトルのみ。 場所、主催者、説明は照合されません。タイトルのないイベントは Untitled event として照合されます。
  • 非公開イベントは、それ自体のタイトルで照合され、表示は非公開タイトルのままです。非公開タイトルそのものは照合されないため、exclude: ["private"] では何も除外されません。
  • ソースが書き込むものすべてが、フィルター後のカレンダーを読み取ります。カードも、キー別の各会議室ドキュメントも同様です。フィルターが除外するのはイベントだけで、カレンダーや部屋は除外されず、空き時間のイベントも他と同様に扱われます。
  • ステータスは除外された件数を数えます (filtered。0 の場合も含みます)。期間内にイベントがあるのにキーワードですべて除外された場合、同期は成功し、キーワードを確認するよう促す警告が出て、カードには空のリストが表示されます。source test でも同じ内容を確認できます。
screenrig source create --kind ics --card crd_EVENTS --name "Public events" \
  --set 'calendars=[{"key":"main"}]' --set 'include=["open house","tour"]' --set 'exclude=["cancelled"]' \
  --secret calendar_url.main=@calendar.url

シート、CSV、JSON

sheets、csv、json ソースは表または JSON ドキュメントを読み取り、マッピングでカードのデータを作るため、どのカードにも使えます。価格表からメニュー、指標シートから KPI ボード、順位表シートから表を作れます。マッピングはソースの設定に入れる JSON テンプレートです。マッピングが作ったものを受け入れるかどうかはカード自身のルールが決め、source test はドキュメントとカードが受け入れるかどうかを表示するので、受け入れられるまでマッピングを編集します。これらのソースは 5 分ごとに同期し、最短では 1 分ごとです。

screenrig source test --kind sheets --card crd_MENU --settings @menu-sheet.json
screenrig source create --kind sheets --card crd_MENU --name "Cafe menu" --settings @menu-sheet.json
screenrig source create --kind json --card crd_KPI --name "Daily numbers" \
  --settings @kpi-api.json --secret token=@api.token
設定種類意味
urlすべてシートのリンク、または CSV ファイルや JSON ドキュメントのアドレス。ポート 80 または 443 の公開 http(s) アドレス
mappingすべてカードのデータを作るテンプレート。必須
key_templateすべて{screen.field.NAME} トークンを含む任意のキー。マッピングは {fields,document} からなる documents 配列を返します
sheetsheetsリンクが指すタブ以外のタブを読むためのタブ名
header_rowsheets, csvtrue(デフォルト)は最初の行に列名がある場合、falseはすべての行がデータで、Column 1、Column 2という名前になる場合
key_columnsheets, csvセルが行の名前になる列。マッピングが名前で行を探せるようにします
delimitercsv,、;、tab。デフォルトは最初の行で最も多く使われているもの
authcsv, jsonnone (デフォルト)、bearer、header、basic、oauth2、token_request: リクエスト、サインイン、ページを参照してください
header_namecsv, jsonauth が header のとき、トークンを運ぶヘッダー。たとえば X-API-Key
rows_pathjson応答の中で行の配列がある場所。たとえば data.items
key_fieldjson各行の名前になるメンバー。rows_path と一緒に設定します

Google スプレッドシートを共有する

sheets ソースは Google の CSV エクスポートでシートを読み取ります。サインインも Google アカウントへのアクセスも不要で、シートはリンクを知っている全員が読める状態にしておく必要があります。

  1. Google スプレッドシートで「共有」を選び、「一般的なアクセス」を「リンクを知っている全員」、役割を「閲覧者」にします。代わりに公開するには、「ファイル」、「共有」、「ウェブに公開」を選びます。
  2. ブラウザーのアドレスバーのリンクを url にコピーします。タブへのリンクはそのタブを保ちます。別のタブを名前で読むには sheet を設定します。公開リンクでは sheet は使えません。
  3. source test でプレビューします。シートのヘッダー行が、マッピングが読む列キーになります。

共有されていないシートは、サインインページ、401、または 403 を返します。このときステータスは not_shared になり、メッセージで変更する設定が示されます。共有、一般的なアクセス、リンクを知っている全員、閲覧者、またはファイル、共有、ウェブに公開です。シートの所有者に共有を依頼してください。not_shared が判断するのはこの 3 つの応答だけです。列とマッピングの照合は行いません。

トークンが必要なアドレス

公開アドレスにある CSV ファイルや JSON ドキュメントにトークンは不要です。保護されたものには、auth を bearer(screenRIG は Authorization: Bearer TOKEN を送ります)または header と header_name(HEADER_NAME: TOKEN を送ります)に設定し、トークンをシークレット token として渡します。

screenrig source create --kind csv --card crd_TABLE --name "Standings" \
  --settings @standings.json --secret token=@api.token

トークンは暗号化して保存され、ヒントだけが返されます。12 文字以上なら末尾 4 文字、それ未満なら … です。トークンはアドレス自身のオリジン(スキーム、ホスト、ポート)にだけ送られます。別のサイトへのリダイレクトにはトークンを付けて従わず、トークンを入力し直さずにソースを別のオリジンに向けると source_secret_required で拒否されます。パスやクエリだけを変えた場合はトークンが保たれます。basic、OAuth 2、トークンリクエスト、および本文、ヘッダー、ページを使うリクエストについては、リクエスト、サインイン、ページを参照してください。header_name には Host、Cookie、Content-Length、Connection、Transfer-Encoding、Upgrade、Proxy- ヘッダー、および screenRIG 自身が設定するヘッダーは使えません。

リクエスト、サインイン、ページ

csv または json のソースは、url に GET を送ります。これらの設定を使うと、本文や追加のヘッダーを送ったり、サインインしたり、複数のページを読み取ったり、リクエストに今日の日付を入れたりできます。1 回のリクエストには 20 秒、実行全体には 60 秒が与えられます。

設定意味
methodGET (デフォルト) または POST。body または graphql があると POST になります
bodyJSON のオブジェクトまたは配列、あるいはそのまま送るテキスト。プレースホルダーを埋めた後で最大 16 KiB
body_formatjson (デフォルト) または form。フォーム本文は、テキスト、数値、真偽値の項目からなるオブジェクト、または a=1&b={{today}} のようなテキストで、値は URL エンコードされます
graphql{query, variables}。JSON の POST として送られます。エラーがあってデータがない応答は parse_failed で、データとともにエラーがある場合は警告です
headers値が秘密でない追加ヘッダーを最大 8 つ。Authorization は拒否され、header_name が拒否するヘッダーも同様です。auth またはヘッダーのシークレットを使ってください
time_zone日付プレースホルダー用の IANA タイムゾーン。指定しないと UTC で読み取られ、ステータスに警告が表示されます
pagination複数のページを読み取ります。詳細は下記のとおりです
formatjson の種類のみ: auto (デフォルト)、json、csv、xml

header.NAME という名前のシークレットはヘッダー NAME として送られるため、認証用ヘッダーが 2 つある API では header.X-Client-Id と header.X-Api-Key を使います。query.NAME という名前のシークレットは、NAME=value としてアドレスに追加されます。それぞれ最大 8 つまでで、どちらも封印して保存され、表示されません。プレビューでは、クエリのシークレットは NAME=*** と表示されます。

認証設定とシークレット
noneデフォルトです
bearerシークレット token。Authorization: Bearer として送られます
headerheader_name とシークレット token
basicusername (コロンなし) とシークレット password。Authorization: Basic として送られます
oauth2クライアント資格情報: token_url、client_id、任意の scope と audience、token_auth (デフォルトの body または basic)、そしてシークレット client_secret。screenRIG は token_url にトークンを要求し、Authorization: Bearer として送ります
token_requestトークンを返すログイン: token_url、token_body (文字列が保存済みのシークレットを {{secrets.NAME}} として読めるオブジェクト)、token_body_format (json または form)、token_path (応答の中でトークンがある場所。たとえば token.accessToken)、そして任意で token_expires_path、token_ttl (60 〜 86,400 秒、デフォルトは 3,600 秒)、header_name (トークンをそのまま運ぶヘッダー。指定しない場合は Authorization: Bearer)

screenRIG はトークンをメモリ上にのみ保持し (ストレージには保存しません)、有効期限の 1 分前に更新します。アドレスがトークンを 401 で拒否した場合は、新しいトークンを 1 回だけ要求します。トークンのアドレスでの拒否 (HTTP 400、401、403) は auth_failed になり、トークンのアドレスが返す内容は引用されません。

{
  "url": "https://api.example.com/v2/orders/summary",
  "method": "POST",
  "body": {"from": "{{today-7d}}", "to": "{{today}}"},
  "time_zone": "America/Vancouver",
  "auth": "oauth2",
  "token_url": "https://login.example.com/oauth/token",
  "client_id": "screen-signs",
  "scope": "orders.read",
  "mapping": {"body": "{{body.total}} orders this week"}
}
screenrig source create --kind json --card crd_BOARD --name "Orders" \
  --settings @orders.json --secret client_secret=@client.secret

日付プレースホルダーは、アドレス、本文、headers に入ります。{{now}} (2026-11-01T17:30:00Z)、{{today}} (2026-11-01)、{{unix}} (秒) があり、それぞれ {{now-90m}}、{{now+7d}}、{{today-1d}} のようなオフセットを付けられます (単位は m、h、d。{{today}} は日単位のみ)。値は time_zone で、なければ UTC で読み取られます。実行のたびに時計から埋められるため、明日の実行は明日の日付を要求します。

ページ。 pagination は {type, max_pages} で、max_pages は 1 〜 20 (デフォルトは 5) です。json ソースでは rows_path を設定して各ページの行を 1 つの配列にまとめ、csv ソースでは表の行を結合します。

タイプ次のページの見つけ方
link_headerLink ヘッダーの rel="next" アドレス
next_urlpath。次のアドレスを持つ応答内の場所 (json のみ)
cursorparam と path。カーソルは param としてアドレスに入れるか、"in": "body" を指定して本文に入れます。カーソルがない、または空になると読み取りは終わります (json のみ)
pageparam、start (デフォルトは 1)、size を伴う size_param。ページ番号はアドレスに入れるか、"in": "body" を指定して本文に入れます。行がないページ、または size 未満のページで読み取りは終わります

次のアドレスはソース自身のオリジンにとどまる必要があるため、シークレットがその外に出ることはありません。同じページが繰り返された場合や、max_pages を超えるページがある場合は、警告とともに読み取りが終わり、全ページを合わせて最大 5 MB です。

XML と RSS。 < で始まる応答、または format xml は XML として読み取られます。body はルート要素を保持し、属性は @name、子を持つ要素のテキストは #text、繰り返される要素はリストになり、名前は接頭辞を保ちます (item["media:thumbnail"]["@url"])。RSS または Atom フィードは body.items も得られ、各エントリには、あれば title、link、published、summary (プレーンテキスト、最大 1,000 文字)、image が入ります。DOCTYPE は決して辿られず、そこから何も取得されません。

source test は、request に、送信された最初のリクエストを表示します。プレースホルダーを埋めた状態、クエリのシークレットは NAME=***、Accept と Content-Type 以外のヘッダーの名前 (値は含まない)、本文の先頭 1 KiB、読み取ったページ数です。

ソースが読み取るもの

  • CSV とシート。通常の CSV を読み取ります。バイト順マーク、引用符で囲まれたフィールド、二重の引用符、引用符内の改行、CRLF の行末はすべて読めます。セルは前後の空白が除かれ、内容のない行は捨てられます。ヘッダーは小文字でアクセントを除いたキーになり、それ以外の文字の連続は 1 つの _ になるため、Sold out は sold_out になります。空のヘッダーは column_3(位置)、重複は _2、_3 になります。スプレッドシートファイルなど UTF-8 のテキストでないファイルは parse_failed になります。UTF-8 の CSV として保存してください。
  • JSON。数値は桁が保たれます。rows_path があると、ソースはそこにある行の配列を探します。配列が見つからないパスは rows_path で mapping_failed になり、空の配列は行のない表になります。
  • 上限。表は 10,000 行、200 列まで読み取ります。それを超えても同期は成功し、省いた行や列の数を示す警告がステータスに表示されます。
  • アドレスがデータではなくウェブページを返すと、parse_failed になります。

マッピング

マッピングは JSON テンプレートです。{{item.price}} のようなプレースホルダーを含む文字列はテキストになり、プレースホルダー 1 つだけの文字列は値の型を保ちます。何も指していないパスは、テキストの中では空になり、単独の値としては省かれるため、カードが足りないものを示します。パスの起点は種類によって決まります。

種類起点内容
sheets, csvrowsデータ行すべて。列キーごとのオブジェクト
sheets, csvcolumns[{key, name}](シートの順)
sheets, csvby_keykey_column がある場合:その列のセルの前後の空白を除いたテキストで引く行
jsonbody応答全体
jsonby_keyrows_path と key_field がある場合:そのメンバーの前後の空白を除いたテキスト、数値、真偽値で引く行

rows[2] のような位置より by_key を使ってください。キーで見つけた行は、誰かがシートを並べ替えたり上に行を挿入したりしても見つかり続けます。スペースを含むキーは by_key["Net sales"].value のように書きます。2 つの行が同じキーを持つ場合は最初の行が優先され、重複の数を示す警告がステータスに表示されます。どの警告もセルの内容を引用しません。

セルはテキストなので変換します。{"$number": "{{item.price}}"} は 1,234.50、$4.50、3,50 €、12% を読み取ります(コンマを小数点にするには "$decimal": "," を加えます)。{"$bool": "{{item.sold_out}}"} は true、yes、y、1、x を読み取ります。$each は item と index を使えるようにしてリストを展開し、$group は $by と合わせて行を最初に現れた順にまとめ、group.key と group.items を使えるようにします。$text と $max はテキストを切り詰めます。テンプレートはソースの保存時に検証されます。

Section、Item、Price、Sold out の列があるシートから作るメニューは、行をセクションごとにまとめます。

{
  "url": "https://docs.google.com/spreadsheets/d/SHEET_ID/edit#gid=0",
  "mapping": {
    "sections": {
      "$group": "{{rows}}", "$by": "{{item.section}}",
      "$template": {
        "name": "{{group.key}}",
        "items": {
          "$each": "{{group.items}}",
          "$template": {
            "name": "{{item.item}}",
            "price": { "$number": "{{item.price}}" },
            "soldOut": { "$bool": "{{item.sold_out}}" }
          }
        }
      }
    }
  }
}

Metric、Value、Unit、Change の列があるシートから作る KPI ボードは、各指標を名前で探すので、シートを並べ替えても何も動きません。

{
  "url": "https://docs.google.com/spreadsheets/d/SHEET_ID/edit#gid=0",
  "key_column": "Metric",
  "mapping": {
    "tiles": [
      { "label": "Revenue", "value": { "$number": "{{by_key.Revenue.value}}" },
        "unit": "{{by_key.Revenue.unit}}", "delta": { "$number": "{{by_key.Revenue.change}}" } },
      { "label": "Orders", "value": { "$number": "{{by_key.Orders.value}}" },
        "delta": { "$number": "{{by_key.Orders.change}}" } }
    ]
  }
}

表カードはすべての行を一覧にします。

{
  "mapping": {
    "rows": {
      "$each": "{{rows}}", "$limit": 50,
      "$template": {
        "team": "{{item.team}}",
        "points": { "$number": "{{item.points}}" },
        "played": { "$number": "{{item.played}}" }
      }
    }
  }
}

ソースが何を読み取るかを確認するには、マッピング {"columns": "{{columns}}", "rows": "{{rows}}"} でテストします。カードはそのドキュメントを拒否しますが、プレビューにはすべてのキーと行が表示されます。

これらのソースで ok は、アドレスが応答し、マッピングで作ったドキュメントをカードが受け入れたことを意味します。シートや応答にマッピングが期待する行があることまでは示しません。消えた列のメンバーは省かれ、必須のメンバーが欠けたドキュメントはカードが拒否します。

計算値

マッピングは、サーバー上で真偽値や数値も計算できるため、visibility.data と equals: true のように等しいかどうかだけを調べるページ条件でも、数値に追従できます。カード Webhook とオーバーレイトリガーのマッピングにも同じヘルパーがあります。

ヘルパー結果書き方
$gt, $gte, $lt, $lte真偽値。両方の値を数値として読み取ります{"$lt": ["{{body.stock}}", 5]}
$between値が両方の境界の範囲内 (境界を含む) のとき真{"$between": ["{{body.temp}}", 18, 24]}
$eq, $ne数値は値で比較 (5、"5"、"5.00" は一致)、それ以外は大文字と小文字を区別した完全一致のテキスト{"$eq": ["{{body.status}}", "open"]}
$containsテキストが別のテキストを含む (大文字と小文字は無視)、またはリストが値を含む{"$contains": ["{{body.title}}", "closed"]}
$in値がリストのいずれかである{"$in": ["{{body.tier}}", ["gold", "silver"]]}
$and, $or, $not条件を組み合わせる{"$and": [{"$gt": ["{{body.a}}", 1]}, {"$not": {"$eq": ["{{body.s}}", "x"]}}]}
$sum, $avg, $min, $maxリストから 1 つの数値{"$sum": "{{rows}}", "$of": "{{item.amount}}"}
$count要素の数、または $where を満たす要素の数{"$count": "{{body.queue}}", "$where": {"$gt": ["{{item.wait}}", 5]}}
  • 実行できない比較は偽になります。警告には場所が示され、値は示されません。そのため、値がない、空、または数値でない場合にページが表示されることはありません。$bool は、値がない場合を偽として扱う唯一のリーダーです。
  • リスト。 $of は各要素から 1 つのプレースホルダーを読み取り、item と index を使えます。$where は条件に当てはまる要素だけを残します。空の要素や数値でない要素はスキップされ、警告にまとめて数えられます。合計する対象がない場合、$sum と $count は 0 になり、$avg、$min、$max はそのメンバーを省きます。
  • 数値。 小数点にカンマを使う値 (3,50、1.234,50) には "$decimal": "," が必要です。$avg は小数 2 桁に丸め、"$round" で 0 〜 6 桁を設定できます。$sum、$min、$max は正確な値になります。

JSON の応答から作る在庫僅少フラグ。visibility.data が path /low_stock と equals true でドキュメントを指定しているページは、在庫が少ない間だけ表示されます:

{
  "sku": "{{body.sku}}",
  "stock": {"$number": "{{body.stock}}"},
  "low_stock": {"$lt": ["{{body.stock}}", 5]}
}

シートから、再発注の基準を下回るすべての商品:

{"low_stock": {"$gt": [{"$count": "{{rows}}", "$where": {"$lt": ["{{item.stock}}", "{{item.reorder_at}}"]}}, 0]}}

キー別ドキュメント

JSON、CSV、Sheets ソースは key_template を受け付けます。例は room-{screen.field.room} です。フィードを {"fields":{"room":"A101"},"document":{"body":"Room A101"}} オブジェクトからなる documents 配列にマッピングします。カードの Webhook は同じ出力に --key-template を使用するか、マッピングなしで外側のオブジェクトを直接受信します。

{
  "key_template": "room-{screen.field.room}",
  "mapping": {
    "documents": {
      "$each": "{{rows}}",
      "$template": {
        "fields": {"room": "{{item.room}}"},
        "document": {"body": "{{item.title}}"}
      }
    }
  }
}

対象の crd_ インスタンスを data: "room-{screen.field.room}" 付きで配置します。各画面は、自身の room フィールドから生成されたキーだけを読み取ります。すべての出力はインスタンスのカードスキーマを使用します。同じフィードから異なる種類のカードを作る場合は、インスタンス、マッピング、プレフィックスを分けてください。

source test でプレビューします。無効なドキュメント、欠けているフィールド、重複するキーがある場合、書き込み前にバッチ全体を拒否します。ストレージ障害では一部が書き込まれた状態になることがあります。同じ Idempotency-Key で同一の Webhook 本文を再送するか、ソースを更新してください。省略されたキーには以前のデータと有効期限が残り、Webhook は有効期限を設定しません。Webhook のテンプレートは --clear-key-template で解除します。

ファイルとシートのヒント

  • OneDrive と SharePoint。 共有リンクはプレビューページを開き、ソースはそれを Web ページとして読み取ります (parse_failed)。CSV ファイルのリンクに ?download=1 を付けるか (すでに ? がある場合は &download=1)、リンクがファイルそのものを返すようにします。リンクはサインインなしで使える必要があります。
  • 名前で行を引く。 key_column に、各行を名前で呼ぶ列を、大文字小文字を問わないヘッダーで指定し、行は by_key.NAME.column として読みます。シートを並べ替えたり行を挿入したりしても、何も変わりません。どの列にも一致しない名前は key_column で mapping_failed になり、重複したキーは最初の行を残して、重複数を数えた警告を出します。

会議室

会議室ソースは会議室のカレンダーを読み取り、1 室のドアサインである room カード、または建物のすべての部屋を表す room-board カードに反映します。events のアジェンダや study-rooms カードに反映することもでき、カレンダーのアドレス(ICS)も同じカードに反映できます。

カードは保持している予約から、部屋が空いているか、使用中か、次に何があるかを、画面上で毎秒算出します。そのため、画面がオフラインでもサインは正しいままです。会議室ソースは読み取り専用です。カードは予約を表示するだけで入力を受け付けないため、画面から予約、終了、チェックインを行うことはありません。

設定意味
rooms1〜60 室。各室に key(小文字、数字、-、_)、部屋のアドレス(Microsoft 365 は email、Google は calendar_id)、任意で name、floor、capacity を指定します。room カードが受け付ける部屋はちょうど 1 室です
days今日から何日分を表示するか。1〜31 で、既定は 7 です
time_zoneAmerica/Los_Angeles のような IANA ゾーン。日付の境界と終日の予定に使われます。指定しない場合、1 日は UTC の午前 0 時に始まり、ステータスに警告が表示されます
private_title非公開の予定に表示するタイトル(既定は Private)

Microsoft 365 のルームメールボックス

種類 microsoft365 は、お客様自身の Microsoft Entra アプリで Exchange Online のルームメールボックスを読み取ります。アプリ、そのシークレット、読み取れる範囲はお客様の管理下に置かれます。追加の設定は 2 つです。tenant はディレクトリ ID または contoso.com のような確認済みドメイン(common、organizations、consumers は拒否されます)、client_id はアプリのアプリケーション(クライアント)ID です。シークレット client_secret はアプリのクライアントシークレットの値です。

  1. Microsoft Entra 管理センターで、リダイレクト URI のないシングルテナントのアプリを登録し、クライアントシークレットを追加(シークレット ID ではなく値をコピー)し、Microsoft Graph のアプリケーションのアクセス許可 Calendars.Read を追加して、管理者の同意を付与します。
  2. アプリをルームメールボックスに限定します。アプリケーションアクセスポリシーで制限するまで、Calendars.Read は組織のすべてのメールボックスに届きます。部屋をメール対応セキュリティグループに入れ、下の最初の 2 つのコマンドを Exchange Online PowerShell で実行します。グループ内の部屋に対して Test-ApplicationAccessPolicy は Granted を返します。Exchange のアプリケーション向け RBAC でも同じようにアプリを限定できます。
  3. ルームメールボックスは、設定を変えない限り、会議の件名を主催者の名前に置き換えます。会議のタイトルを表示するには、各部屋に対して 3 番目のコマンドを実行します。
  4. プレビューしてから保存します。source test はサインインして各部屋を読み取り、読み取った部屋と予約、部屋ごとの件数、アプリが Place.Read.All も持っている場合は組織が一覧表示する部屋数を報告します。
# Exchange Online PowerShell
New-ApplicationAccessPolicy -AppId CLIENT_ID -PolicyScopeGroupId rooms@example.com -AccessRight RestrictAccess -Description "screenRIG room signs"
Test-ApplicationAccessPolicy -AppId CLIENT_ID -Identity boardroom@example.com
Set-CalendarProcessing -Identity boardroom@example.com -DeleteSubject $false -AddOrganizerToSubject $false

# screenRIG (source create takes the same options, plus --name)
screenrig source test --kind microsoft365 --card crd_ROOM \
  --set tenant=contoso.com --set client_id=CLIENT_ID --set time_zone=America/Los_Angeles \
  --set 'rooms=[{"key":"boardroom","email":"boardroom@example.com","name":"Boardroom","floor":"Level 4","capacity":12}]' \
  --secret client_secret=@secret.txt
  • マッピング。非公開および機密の会議は、非公開タイトルが表示され、主催者は表示されません。空き時間または別の場所で作業中として設定された会議と、部屋が辞退した会議は空き時間として扱われ、仮の会議は使用中として数えられ、キャンセルされた会議は除外されます。終日の予定は部屋のタイムゾーンでの日付です。
  • スケジュール。会議室ソースは 2 分ごとに同期します。サインインは約 1 時間有効で、再利用されます。
  • エラー。Microsoft のエラーコードとテキストがそのまま引用されます(クライアントシークレットが誤っている場合は AADSTS7000215 など)。アプリが読み取れない部屋があると同期は失敗し、その部屋が名前で示されます。
  • 代わりに接続を使う。 tenant、client_id、client_secret の代わりに、connection_id にプロジェクトの Microsoft 接続を、どちらのモードでも設定できます。その場合、ソースはシークレットを持たず、接続と同じ方法でサインインします。

Google Workspace のリソースカレンダー

種類 google_calendar は、お客様自身の Google サービスアカウントでリソースと会議室のカレンダーを読み取ります。シークレット service_account_key は Google が発行したままのキーファイルで、そのヒントはアカウントのアドレスです。任意の設定 subject は、ドメイン全体の委任でアカウントが代理として動作するユーザーを指定します。

  1. Google Cloud で Google カレンダー API を有効にし、サービスアカウントを作成して、その JSON キーをダウンロードします。
  2. アカウントに部屋へのアクセス権を与えます。各部屋のカレンダーをアカウントのアドレスに「予定の詳細をすべて表示」権限で共有するか、管理コンソールでアカウントのドメイン全体の委任をスコープ https://www.googleapis.com/auth/calendar.events.readonly で有効にし、subject を部屋を閲覧できるユーザーに設定します。
  3. 部屋の calendar_id は、管理コンソールの「建物とリソース」にあるリソースのカレンダー ID で、末尾は @resource.calendar.google.com です。source test でプレビューしてから保存します。
screenrig source test --kind google_calendar --card crd_ROOM \
  --set time_zone=America/Los_Angeles \
  --set 'rooms=[{"key":"boardroom","calendar_id":"CALENDAR_ID","name":"Boardroom"}]' \
  --secret service_account_key=@key.json
  • マッピング。非公開および機密の予定は、非公開タイトルが表示され、主催者は表示されません。「空き時間」として設定された予定と、部屋が辞退した予定は空き時間として扱われ、キャンセルされた予定は除外されます。終日の予定は日付がそのまま保たれます。
  • エラー。Google のエラーテキストがそのまま引用されます。アカウントから見えないカレンダーはエラーで名前が示され、共有の方法も案内されます。
  • 代わりに接続を使う。 service_account_key の代わりに、connection_id にプロジェクトの Google 接続を設定できます。screenRIG のアプリを使う場合、ソースは承認したアカウントが見られるカレンダーを読み取るため、そのアカウントはソースに挙げたすべての会議室カレンダーを見られる必要があり、subject は使えません。

制限とプライバシー

  • room カードは最も早い 200 件の予約を保持し、room-board カードは部屋ごとに 60 件を保持します。それを超える場合、ステータスに除外された件数を示す警告が表示されます。
  • カードのドキュメントには、カードが描画するものだけが含まれます。カードを表示するすべての画面がそのドキュメントを保持するためです。room カードが主催者を受け取るのは showOrganizer がオンのときだけです。room-board カードは主催者を一切受け取らず、showTitles がオンでない限り、各会議のタイトルの代わりに非公開タイトルを受け取ります。どちらの設定の変更も、次の同期でカードに反映されます。非公開の会議は、どちらの場合も非公開タイトルになります。
  • これらの種類のメッセージには、Microsoft または Google が返したエラーテキストが引用されますが、シークレットは含まれません。

会場の予約システム

種類 momentus は、Momentus Enterprise(以前は Ungerboeck や EBMS として販売されていたシステム)のファンクション(部屋の各利用と、その日付・時刻)とスペースを、管理者が Momentus で作成した API ユーザー(Main Menu、Api Users)で読み取ります。イベント一覧には events カード、ロビーや廊下には room-board カード、1 つの部屋には room カードを更新し、部屋ごとのドキュメントを使えば、各スクリーンが自分の部屋の予約を表示します。イベント直前に変更された部屋は、更新間隔(既定は 1 分)以内に表示されます。

設定意味
base_urlMomentus の Web サーバーの https アドレス(例: https://momentus.example.com/prod)。API は {base_url}/api/v1/... から読み取ります
organizationデータを読み取る Momentus の組織コード
api_userAPI ユーザーの ID
time_zone会場の IANA タイムゾーン。Momentus は現地の日付と時刻を保持するため、必ず設定してください。未設定の場合、時刻は UTC として読み取られ、ステータスに警告が表示されます
days今日から何日分を読み取るか。1 から 31(既定は 7)
rooms{key, space, name?, floor?, capacity?, area?} の任意のリスト。space は Momentus のスペースコードです。指定しない場合、Momentus が一覧にするすべてのスペースが部屋になります(キーは小文字にしたコード)
space_filter, function_filter読み取るスペースやファンクションを絞り込む、任意の Momentus 検索式
exclude_status_codes除外するファンクションのステータスコード(キャンセル済みなど)。ステータスコードは会場ごとに異なるため、既定値はありません
include, excludeソースが表示するタイトルで機能を残す、または非表示にするキーワード。カレンダーと同じです

2 つのシークレット: API ユーザーのキー GUID の 1 つである api_key と、そのシークレット GUID である api_secret。どちらも暗号化して保存され、再表示されることはありません。データソースが別のサーバー、組織、API ユーザーを指す場合は、入力し直します。

screenrig source test --kind momentus --card crd_EVENTS \
  --set base_url=https://momentus.example.com/prod --set organization=10 \
  --set api_user=venue-api --set time_zone=America/Los_Angeles \
  --set 'exclude_status_codes=["XX"]' \
  --secret api_key=@key.guid --secret api_secret=@secret.guid
screenrig source create --kind momentus --card crd_EVENTS --name "Venue events" \
  --settings @momentus.json --secret api_key=@key.guid --secret api_secret=@secret.guid

source test は Momentus を読み取り、ドキュメントを整形してカードに照らして確認し、読み取った部屋とイベントを表示します(functions、functions_other_spaces、events_KEY)。何も保存も書き込みもされません。

  • ファンクションの扱い。 ファンクションの Space で部屋が決まり、Description がタイトルになります(title_field で代替の説明の 1 つを指定できます)。部屋の名前が場所になります。開始時刻のないファンクションは終日のイベントです。複数の日付にわたり時刻のあるファンクションは、各日付でその時刻を表示し、終了が開始より前のものは夜をまたぎます。
  • 非公開のタイトル。 room-board は、show_titles がオンでない限り非公開のタイトルを表示します。ほかの部屋の種類と同じです。
  • エラー。 サーバーはお客様のものなので、Momentus 自身のメッセージは引用されません。auth_failed は API ユーザー、キー、シークレットが誤っているか、ファンクションとスペースを読み取れないことを、config_invalid はフィルターが有効な Momentus の検索ではないことを、parse_failed は base_url が API ではなく Web ページに到達したことを示します。

部屋ごとのサイン

room_key_prefix(例: momentus-room-)を設定すると、データソースはそのプレフィックスに部屋のキーを続けた名前で、部屋ごとに room ドキュメントも書き込みます。各部屋のスクリーンにその部屋を設定し、data キーがプレフィックスとスクリーン自身のフィールドである room カードを配置します。

screenrig screen update scr_BALLROOM --field room=ballroom-a

この再生リストのプリミティブでは、インラインのカタログ型 room を使用します:

{"id":"door","primitive":"card","card":"room","layout":"full","content_fit":"fill","params":{"room":"{screen.field.room}"},"data":"momentus-room-{screen.field.room}"}

crd_ プリミティブはインスタンス自身の params と major を使用するため、これらのフィールドは省略します。任意の data で、ドキュメントのキーまたは画面ごとのキーのテンプレートを選択できます。ソースの --card crd_ID は引き続き同期先を指定します。ページでは visibility.data.key を momentus-room-{screen.field.room} に設定し、その後に無条件のフォールバックページを追加してください。

バックエンドが各スクリーンのマニフェストでフィールドを埋めるため、1 つのプレイリストで各スクリーンに自分の部屋が表示され、部屋のフィールドがないスクリーンではそのカードには何も表示されません。area_key_prefix は廊下のディスプレイにも同じように働きます。各部屋の area でグループ化され、そのエリアの部屋の room-board が、プレフィックスにエリアのキーを続けた名前で書き込まれます(area_card は events にできます)。screen_field と area_field は、下の確認が読み取るスクリーンのフィールド名です(既定は room と area)。

マッピングを確認する

screenrig source rooms src_ID(およびダッシュボードのデータソースのページにある「部屋のマッピング」セクション)は、データソースが提供していてもどのスクリーンにも表示されていない部屋と、部屋が未設定、または Momentus にない部屋を指定しているスクリーンを一覧にします。

screenrig source rooms src_VENUE

スクリーンは、そのフィールドに値があるか、スクリーン自身のプレイリストがそのキーを読むカードを配置している場合にレポートに含まれます。各スクリーンの状態は mapped、missing(プレイリストはフィールドを読むがスクリーンに値がない)、unknown(値が部屋を指していない。レポートは、大文字小文字だけが違う場合など、意図したと思われる部屋を示します)のいずれかです。スクリーンは screenrig screen update scr_ID --field room=ROOM_KEY で修正します。レポートはデータソースの最後に成功した更新の部屋を読み取るだけで、何も取得しません。rooms を列挙したデータソースは、最初の更新の前から部屋を把握しています。

セキュリティ

アクセス権を与えるアドレスは認証情報です。screenRIG はそれを暗号化して保存し、スキームとホストだけを返し、同期の実行にのみ使います。ソースはポート 80 または 443 の公開 http(s) アドレスを読み取り、リダイレクトは最大 3 回までたどります。公開ホストに解決されないアドレス、拒否された接続、ハンドシェイクの失敗はすべて同じように表示されるため、ソースを使ってネットワークを探ることはできません。どのメッセージにも、アドレスや受け取った応答は引用されません。ソースは読み取るだけで、カレンダーには書き込みません。