# ブロック (/ja/docs/flows/blocks)

各ブロックは1つのことを行います。設定はブロックを選択したときにインスペクタに表示され、ポートはキャンバス上にあります（入力は左、出力は右）。このページでは、ブロックピッカーと同じグループ分けで、すべての種類を順に説明します。そのあとで、ブロック間を流れる値、`{{body.id}}`のようなテンプレート、条件を説明します。

## 実行の流れ [#how-a-run-moves]

- ブロックは、接続が入っているすべての入力に値が届くと実行されます。実行後は、いくつかの出力から値を送り出し、それらの出力に接続されたブロックだけが次に実行されます。
- 最初に実行されるのは開始ブロックです。何も接続されていない値ブロックと変数を取得ブロックも、開始時に実行されます。
- ブロックは、可能なら並行して実行されます。表示して待機ブロックがあなたの操作を待っている間も、ポーリングブロックは動き続けられます。
- 失敗する可能性があるブロックがいくつかあります。リクエスト、ポーリング、ツール、フロー、評価、ファイルに書き込むには`fail`出力があります。これが接続されていると、失敗はそこから出て、実行は続きます。接続されていないと、実行全体がそのブロックで失敗します。
- 実行中のものが何もなくなると、実行は終了します。

どのブロックのインスペクタにも<strong>タイトル</strong>（ブロックに表示されます。空のときは種類の名前）と<strong>一時停止中（値はそのまま通過します）</strong>があります。一時停止したブロックは薄く表示されてスキップされ、入ってきた値は最初の出力からそのまま出ていきます。

## トリガー [#triggers]

### 開始 [#start]

実行が始まる場所です。**実行**ボタン、エージェント（フローがツールのとき）、スケジュール、Webhook、`echolot flow run`のいずれかから始まります。インスペクタには、フローの**トリガー**があります。[実行とトリガー](/docs/flows/running-and-triggers)を参照してください。

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `run` | 出力 | フローのすべての入力を1つのオブジェクトにしたもの。 |
| 入力ごとに1つ | 出力 | その入力の値。 |

フローにある開始ブロックはちょうど1つです。ブロックピッカーには表示されません。

### 出力 [#output]

実行が返す内容です。返す先は、フローを呼び出したエージェント、コマンドライン、Webhookの呼び出し元、または親フローです。1つのフローに最大1つです。

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `value` | 入力 | 結果。 |

## アクション [#actions]

### リクエスト [#request]

ワークスペースの保存済みリクエスト（HTTP、GraphQL、MCPリクエスト）を、その認証、スクリプト、チェック、実行の環境とともに送信します。

| 設定 | 内容 |
| --- | --- |
| **リクエスト** | 保存済みリクエストを一覧から選びます（必須）。 |
| **変数** | 名前をカンマで区切って指定します。それぞれがリクエストの`{{variable}}`を埋める入力になります。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `send` | 入力 | リクエストを送信します。オブジェクトが届くと、そのキーがそれぞれこの送信の変数になります。 |
| **変数**の名前ごとに1つ | 入力 | その変数の値。 |
| `success` | 出力 | リクエストが成功したときの[レスポンス](#the-response-object)。 |
| `fail` | 出力 | 2xx以外で応答した、またはチェックに失敗したときはレスポンス。何も返ってこなかったときはエラー。 |

リクエストは、2xxで応答し、チェック、スクリプトのテスト、スクリプトがすべて成功したときに成功します。これは[ランナー](/docs/requests/runner)と同じです。フローが渡した変数は、その送信に限り、環境の変数より優先されます。

フロー**Place a test order**では、**Sign in**の`success`出力が**Create order**の`send`に接続されています。注文はサインインが成功した後でのみ行われ、Sign inがキャプチャしたトークンはすでに`{{token}}`に入っています。

### ツール [#tool]

モックの起動、フォルダの実行、仕様のリント、MCPサーバのツールの呼び出しなど、Echolot自身のツールを1つ実行します。ルールはエージェントの場合と同じです。

| 設定 | 内容 |
| --- | --- |
| **ツール** | ツールを一覧から選びます（必須）。 |
| **引数** | ツールの引数をJSONで指定します（`{ "name": "{{value}}" }`など）。テキストの値にはテンプレートを使えます。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `run` | 入力 | ツールを実行します。オブジェクトが届くと、そのキーが引数に追加されます。 |
| `result` | 出力 | ツールが返した内容。 |
| `fail` | 出力 | 失敗した理由。 |

ツールブロックから別のフローは実行できません。その場合はフローブロックを使います。

<Edition only="direct">
  ローカルのプログラム（stdio）として動くMCPサーバを呼び出すツールブロックは、ダイレクトダウンロード版で使えます。
  App Store版ではEcholotがそのプログラムを起動できないため、ブロックに警告が表示され、実行すると失敗します。
</Edition>

### フロー [#flow]

ワークスペースの別のフローを実行し、その出力ブロックが受け取った内容を送ります。

| 設定 | 内容 |
| --- | --- |
| **フロー** | 実行する別のフロー（必須）。フローは自分自身を実行できず、フロー同士が循環して実行し合うこともできません。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `input` | 入力 | 別のフローの入力を持つオブジェクト。 |
| `output` | 出力 | 別のフローが返した内容。 |
| `fail` | 出力 | 別のフローが失敗した理由。 |

フローが互いに呼び出せるのは、最大8階層までです。シークレットは値としてはフロー間で渡されません。代わりに変数として保存してください。

## 人の操作 [#people]

人の操作のブロックは、実行を一時停止してあなたに確認します。アプリではシートが開きます。エージェントが開始した場合は、質問がエージェントのクライアントに届きます。コマンドラインでは、ターミナルで質問されます。スケジュールやWebhookが開始した実行には確認できる相手がいないため、人の操作のブロックはそこで失敗します。`echolot flow run --no-input`でも同様です。

### 確認 [#ask]

小さなフォームで値を尋ねます。

| 設定 | 内容 |
| --- | --- |
| **メッセージ** | 尋ねる内容。テンプレートを使えます。 |
| **フィールド** | フォームのフィールド（必須）。それぞれに、`name`（ポートとキー）、横に表示される`label`、`type`（`text`、`number`、`bool`、`secret`、`choice`）、選択肢の場合はカンマ区切りの`choices`、`default`があります。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `run` | 入力 | 尋ねます。オブジェクトはメッセージのテンプレートを埋めます。 |
| `answers` | 出力 | すべての回答を1つのオブジェクトにしたもの。 |
| フィールドごとに1つ | 出力 | そのフィールドの回答。 |
| `cancelled` | 出力 | ユーザーが**キャンセル**をクリックしたときは`true`。 |

シートには**キャンセル**と**続ける**があります。`secret`フィールドの回答は、実行ログでは隠されます。

### 表示して待機 [#show-and-wait]

メッセージ、コピー用のコード、開くリンクを表示し、**続ける**が押されるか、`until`に値が届くまで待ちます。デバイスでのサインインに使います。ポーリングブロックが承認を待つ間、コードを表示します。

| 設定 | 内容 |
| --- | --- |
| **タイトル** | シートのタイトル。 |
| **メッセージ** | 表示する内容（必須）。 |
| **コード** | 大きく表示され、**コードをコピー**が付きます（デバイスコード）。 |
| **リンク** | **ブラウザで開く**が付いて表示されます。 |
| **QRコード** | **リンクをQRコードでも表示します。** デフォルトではオフです。 |

5つすべてでテンプレートを使えます。

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `run` | 入力 | シートを表示します。オブジェクトはテンプレートを埋めます。 |
| `until` | 入力 | ポーリングブロックの`success`など、値が届くと自動的に続行します。 |
| `done` | 出力 | `run`に入ってきた内容。 |

`until`が接続されていると、シートに<strong>完了すると自動的に続行します。</strong>と表示されます。<strong>待機を停止</strong>を押すとシートが閉じ、ブロックは失敗します。

### 承認 [#approve]

元に戻せないことを行う前など、フローを続ける前にあなたの承認を求めます。

| 設定 | 内容 |
| --- | --- |
| **メッセージ** | 質問（必須）。テンプレートを使えます。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `run` | 入力 | 尋ねます。オブジェクトはメッセージのテンプレートを埋めます。 |
| `approved` | 出力 | **承認**した後に、`run`に入ってきた内容。 |
| `declined` | 出力 | **拒否**した後に、`run`に入ってきた内容。 |

承認は、常に人が行うものです。エージェントがフローを実行して承認ブロックに答えようとする場合も、Echolotはまずあなたに質問します。<strong>Place a test order</strong>では、承認ブロック<strong>Keep the order?</strong>が、ショップが作成したばかりの注文について`Keep order {{body.id}} for CHF {{body.total.amount}}?`と尋ねます。<strong>拒否</strong>すると、<strong>Cancel order</strong>に進みます。

<Shot id="flows-approve-sheet" alt="Place a test orderの承認シート。Keep the order?という質問、注文のIDとスイスフランでの合計額、拒否ボタンと承認ボタン" />

## ロジック [#logic]

### 条件分岐 [#if]

入ってきた値を、[条件](#conditions)によって`true`または`false`に送ります。

| 設定 | 内容 |
| --- | --- |
| **条件** | `value.status == 200`のようなJavaScriptの式（必須）。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `value` | 入力 | 判定する値。 |
| `true`、`false` | 出力 | 同じ値が、2つのうちどちらかから出ます。 |

<strong>Morning stock check</strong>では、ショップが返した商品に対して、条件分岐ブロック<strong>Running low?</strong>が`value.body.items.some(p => p.stock.bern < 5)`を使っています。

### 場合分け [#switch]

入ってきた値を、条件が成り立つ最初のケースに送ります。どれも成り立たなければ`default`に送ります。

| 設定 | 内容 |
| --- | --- |
| **ケース** | リスト（必須）。各ケースには、`name`（出力ポート）と`condition`があります。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `value` | 入力 | 判定する値。 |
| ケースごとに1つ | 出力 | そのケースが最初に成り立ったときの値。 |
| `default` | 出力 | どのケースも成り立たなかったときの値。 |

### 評価 [#evaluate]

入ってきた値に対してJavaScriptを実行します。最後の式が結果になります（`({ id: value.body.id })`や`a + b`など）。独自に`return`を持つコードは関数の本体として実行され、`return`が返す値が結果になります。Promiseは待機されます。`pm.test`と`pm.expect`は[スクリプト](/docs/requests/scripts-and-tests)と同じように使え、その結果は実行のテストとして数えられます。`console.log`の行は実行ログに出ます。

| 設定 | 内容 |
| --- | --- |
| **コード** | JavaScript（必須）。 |
| **入力** | 入力名をカンマで区切って指定します。それぞれがコード内の変数になります。空のときは`value`です。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| **入力**の名前ごとに1つ | 入力 | その変数の値。 |
| `result` | 出力 | 結果。 |
| `fail` | 出力 | コードが例外を投げたときのエラー。 |

```js
// 入力: pages。収集ブロックが集めたリストを1つにつなげます。
return pages.flat();
```

### 遅延 [#delay]

待機してから、値をそのまま渡します。

| 設定 | 内容 |
| --- | --- |
| **ミリ秒** | 待機する時間（必須）。数値、または`{{wait}}`のようなテンプレート。 |

ポート: `value`が入力、`value`が出力。

## ループ [#loops]

### 繰り返す [#repeat]

**回数**の分だけ、0から数えた`index`を送り、最後に`done`を送ります。

| 設定 | 内容 |
| --- | --- |
| **回数** | 繰り返す回数（必須）。0から100,000まで。数値、または`{{pages}}`のようなテンプレート。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `run` | 入力 | ループを開始します。 |
| `index` | 出力 | 1回ごとに0、1、2…。 |
| `done` | 出力 | 最後の回が終わった後に、`run`に入ってきた内容。 |

### 各項目を繰り返す [#for-each]

リストの各項目を順に送り、最後に`done`を送ります。設定はありません。

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `list` | 入力 | リスト。それ以外が届くと、ブロックは失敗します。 |
| `item` | 出力 | 1回につき1項目。 |
| `index` | 出力 | 項目の位置（0から数えます）。 |
| `done` | 出力 | 最後の回が終わった後の、リスト全体。 |

### 収集 [#collect]

ループ中に届いた値を1つのリストにまとめ、ループが終わったときに送ります。設定はありません。

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `item` | 入力 | 1回につき1つの値。 |
| `list` | 出力 | 集めたすべての値。属しているループが終わったときに出ます。 |

ループの各回は、前の回が終わってから始まり、その回で到達したブロックは毎回実行し直されます。開始ブロックの入力のようにループの外にある値は、どの回でも使えます。

### ポーリング [#poll]

条件が成り立つ（サインインが承認された、ジョブが完了したなど）か、期限が過ぎるまで、保存済みリクエストを繰り返し送信します。

| 設定 | 内容 |
| --- | --- |
| **リクエスト** | 保存済みリクエスト（必須）。 |
| **変数** | 名前をカンマで区切って指定します。それぞれが`{{variable}}`を埋める入力になります。 |
| **終了条件** | 直近のレスポンスである`response`に対する[条件](#conditions)。デフォルト: `response.status >= 200 && response.status < 300`。 |
| **間隔** | 送信の間隔（秒）。デフォルトは5。数値またはテンプレート。 |
| **期限** | あきらめるまでの秒数。デフォルトは300。数値またはテンプレート。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `send` | 入力 | ポーリングを開始します。オブジェクトが届くと、そのキーが変数になります。 |
| **変数**の名前ごとに1つ | 入力 | その変数の値。 |
| `success` | 出力 | 条件を満たしたレスポンス。 |
| `timeout` | 出力 | 期限が過ぎたときの、直近のレスポンス。`timeout`が接続されていないと、代わりにブロックが失敗します。 |
| `fail` | 出力 | 送信が失敗したときのエラー。 |

リクエストと違い、2xx以外のレスポンスでもポーリングは失敗しません。**終了条件**が成り立つまで、再び送信します。

## データ [#data]

### 値 [#value]

固定の値です。テキスト、数値、`true`または`false`、リスト、オブジェクトが使えます。

| 設定 | 内容 |
| --- | --- |
| **値** | テキスト、数値、またはJSON（必須）。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `run` | 入力 | 何かが届くたびに、値を再び送ります。 |
| `value` | 出力 | その値。`run`に何も接続されていないと、開始時に1回送られます。 |

### テンプレート [#template]

届いたオブジェクトと実行の変数で`{{name}}`を埋めたテキストです。

| 設定 | 内容 |
| --- | --- |
| **テキスト** | [テンプレート](#templates)を含むテキスト（必須）。 |

ポート: `values`が入力（オブジェクト）、`text`が出力。

### 抽出 [#select]

入ってきた値からパスで値を取り出し、1つずつ別の出力に送ります。

| 設定 | 内容 |
| --- | --- |
| **フィールド** | リスト（必須）。各フィールドには、`name`（出力ポート）と、`$.body.user_code`のような`path`があります。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `value` | 入力 | 取り出す元の値。多くの場合はレスポンス。 |
| フィールドごとに1つ | 出力 | そのパスにある値。何もなければ`null`。 |
| `all` | 出力 | すべてのフィールドを1つのオブジェクトにしたもの。 |

パスは、JSONPathの共通部分です。

| パス | 取り出すもの |
| --- | --- |
| `$.body.items[0].sku` | キーを取り出し、続けてリストの最初の項目。 |
| `$.body.items[-1]` | 最後の項目。 |
| `$.body.items[*].sku` | すべての項目の`sku`をリストにしたもの。 |
| `$['content-type']` | ドットでは指定できない文字を含むキー。 |
| `body.id` | `$`がなければ、パスは値の先頭から始まります。 |

### 変数を設定 [#set-variable]

値を変数として保存し、後のブロックやリクエストが`{{name}}`で読めるようにします。

| 設定 | 内容 |
| --- | --- |
| **変数** | リスト（必須）。それぞれに、`name`、入ってきた値の中の`path`（空のときは全体）、`scope`、`secret`があります。 |

| スコープ | 値の保存先 |
| --- | --- |
| `run` | この実行と、それが送信するリクエストのみ。 |
| `environment` | アクティブな環境（デフォルト）。環境が選ばれていないと、実行はここで失敗します。 |
| `workspace` | ワークスペース自身の変数。 |
| `global` | フローからは書き込めません。実行が失敗し、環境かワークスペースに保存するよう促されます。 |

`secret`をオンにすると、値はファイルではなくキーチェーンに保存され、その前のブロックから出た時点から、実行ログとエージェントに見える内容では隠されます。`path`で何も見つからないときは、変数は古い値のままです。そのため、新しいリフレッシュトークンを含まないトークンのレスポンスが、すでに持っているリフレッシュトークンを消すことはありません。[シークレット](/docs/workspaces/secrets)を参照してください。

ポート: `value`が入力、`value`が出力（入ってきた値をそのまま渡します）。

### 変数を取得 [#get-variable]

リクエストから見えるとおりに変数を読み取ります。実行自身の変数、次に環境、ワークスペース、グローバルの変数の順です。

| 設定 | 内容 |
| --- | --- |
| **名前** | 変数（必須）。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `run` | 入力 | 何かが届くたびに、再び読み取ります。 |
| `value` | 出力 | その値。なければ`null`。`run`に何も接続されていないと、開始時に1回読み取られます。 |

## 出力 [#output]

### 表示 [#display]

入ってきた値をそのまま渡し、確認できるようにします。実行後にこのブロックを選択して、インスペクタの**前回の実行**を読んでください。

| 設定 | 内容 |
| --- | --- |
| **フォーマット** | `auto`、`text`、`json`、`table`、`image`。デフォルトは`auto`。 |

ポート: `value`が入力、`value`が出力。

### ログ [#log]

実行ログに1行書き込みます。

| 設定 | 内容 |
| --- | --- |
| **メッセージ** | 書き込む行。テンプレートを使えます。`{{value}}`は入ってきた値で、メッセージが空のときは値全体です。 |

ポート: `value`が入力、`value`が出力。**Place a test order**では、注文できなかったときに**Order failed**が`Create order answered {{status}}`をログに書きます。

### アサート [#assert]

入ってきた値をチェックします。各チェックは実行のテスト結果になり、失敗したチェックがあると`echolot flow run`は失敗します。

| 設定 | 内容 |
| --- | --- |
| **チェック** | リスト（必須）。各チェックには、`name`と、`value`に対する`condition`があります。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `value` | 入力 | チェックする値。 |
| `passed` | 出力 | すべてのチェックが成り立ったときの値。 |
| `failed` | 出力 | いずれかのチェックが失敗したときの値。 |

```js
value.status === 200   // 200で応答する
value.time < 2000      // 2秒以内
```

### 通知 [#notify]

Echolotからの通知をmacOSで表示します。初回はmacOSが許可を求めます。コマンドラインでは、通知の代わりに内容が出力されます。

| 設定 | 内容 |
| --- | --- |
| **タイトル** | 通知のタイトル（必須）。テンプレートを使えます。 |
| **メッセージ** | 通知の本文。テンプレートを使えます。 |

ポート: `value`が入力、`value`が出力。**Morning stock check**は、タイトルが`Restock Bern`の通知ブロック**Restock**で終わります。

### ファイルに書き込む [#write-file]

入ってきた値を、ワークスペースフォルダ内のファイルに書き込みます。

| 設定 | 内容 |
| --- | --- |
| **パス** | ワークスペースフォルダからの相対パス（`exports/items.json`など、必須）。テンプレートを使えます。 |
| **フォーマット** | `json`（整形あり）、`text`、`csv`。デフォルトは`json`。 |

| ポート | 向き | 運ぶ値 |
| --- | --- | --- |
| `value` | 入力 | 書き込む内容。 |
| `path` | 出力 | ファイルのパス（ワークスペースからの相対パス）。 |
| `fail` | 出力 | 書き込めなかった理由。 |

すでにあるファイルは置き換えられます。ワークスペース自身のファイルは書き込み禁止です。`requests`、`flows`、`environments`、`mocks`、`mcp-servers`、`specs`フォルダ、`workspace.toml`、隠しファイルが該当します。CSVでは、オブジェクトのリストはオブジェクト1つにつき1行、キー1つにつき1列になり、それ以外は1行に1つの値で書き込まれます。

## ブロック間の値 [#values-between-blocks]

値はJSONです。テキスト、数値、`true`と`false`、リスト、オブジェクト、`null`のいずれかです。

### レスポンスオブジェクト [#the-response-object]

リクエストとポーリングは、レスポンスをオブジェクトとして送ります。

```json
{
  "status": 201,
  "reason": "Created",
  "headers": { "content-type": "application/json", "location": "/v1/orders/ord_9Px3Kd" },
  "body": { "id": "ord_9Px3Kd", "total": { "amount": 449, "currency": "CHF" } },
  "time": 182.4,
  "url": "https://demo.echolot.dev/v1/orders"
}
```

- `body`は、レスポンスがJSONのときは解析済みのJSON、それ以外はテキスト、空のときは`null`です。
- ヘッダー名は小文字です。複数回送られたヘッダーは`, `で連結されます。
- `time`は、やり取り全体にかかった時間（ミリ秒）です。
- 8 MBを超えるボディは`null`になり、`"truncated": true`が付きます。完全なレスポンスは[履歴](/docs/workspaces/history)に残っています。

### テンプレート [#templates]

「テンプレートを使えます」と書かれた設定では、ブロックに入ってきた値から`{{name}}`が埋められます。

- `{{status}}`、`{{body.id}}`、`{{body.items[0].sku}}`: 入ってきたオブジェクトのキー、またはそこへの[パス](#select)。
- ログ、通知、ファイルに書き込むでの`{{value}}`: 入ってきた値全体。
- 変数を設定ブロックがスコープ`run`で保存した変数。

どれにも一致しない名前はそのまま残るので、リクエストブロック自身の`{{variables}}`は、送信するときに環境から解決されます。オブジェクトとリストはJSONテキストとして書き込まれます。

### 条件 [#conditions]

条件分岐、場合分け、ポーリング、アサートは、真偽が決まるJavaScriptの式を受け取ります。`value`は入ってきた値です。ポーリングの**終了条件**では、これを`response`として読みます。どこでも使えます。

```js
value.status == 200
response.status === 200 && !!(response.body && response.body.access_token)
value.body.items.length > 0
```

例外を投げる式は、ブロックを失敗させます（アサートでは、そのチェックが失敗します）。

## 上限 [#limits]

間違った接続で実行が止まらなくなることがないよう、実行は、ブロックの実行が10,000回に達するか、1時間たつと停止します。Webhookが開始した実行は、2分で停止します。
