テンプレート
アプリまたはecholot flow newで、用意されたテンプレート(デバイスサインイン、リフレッシュトークン、ページを取得して書き出す、死活監視、データ作成と後片付け)からフローを始めます。
テンプレートは、ほとんどのAPIで必要になる作業のために用意された、できあいのフローです。テンプレートには、ブロック、ブロック間の接続、キャンバス上のメモが含まれています。あなたのAPIのことは知らないので、リクエストブロックとポーリングブロックにはまだリクエストが設定されていません。リクエストを選ぶまで、それぞれに問題が表示され、メモには何を選ぶかが書かれています。
テンプレートからフローを作成する
アプリでの手順:
- フローのページで、サイドバーのフローの横にある+をクリックします。
- テンプレートからの下でテンプレートを選びます。ポインタを合わせると、何をするものかが読めます。
- テンプレートの名前でフローが開き、表示に収まります。インスペクタの名前で名前を変更します。
- メモを読み、リクエストブロックとポーリングブロックを1つずつ選択してリクエストを選びます。ツールバーの問題の数がなくなれば、フローを実行できます。

コマンドラインでの手順:
# テンプレートを一覧表示する
echolot flow new
# テンプレートからフローを作成する
echolot flow new "Export products" --template paginate-and-export -w Alpenglow.echolotecholot flow newはflows/export-products.flow.tomlを書き込み、そのパスを出力します。--templateを付けないと、開始ブロックを出力ブロックにつないだ空のフローが作成されます。リクエストは、アプリまたはフローのファイルで選びます。echolot flowを参照してください。
エージェントも、EcholotのMCPサーバを通じて、テンプレートからフローを作成できます。
デバイスサインイン
device-sign-in。OAuth 2.0のデバイスグラント(RFC 8628)でサインインします。デバイスコードを要求し、コードとリンクを表示し、あなたが承認するまでトークンエンドポイントをポーリングして、アクセストークンとリフレッシュトークンをシークレット変数として保存します。
| ブロック | 種類 | 内容 |
|---|---|---|
| Ask for a device code | リクエスト | device_code、user_code、verification_uri、interval、expires_inを返すリクエストを送信します。このリクエストを選んでください。 |
| Codes | 抽出 | ボディからその5つの値を取り出します(codeは$.body.device_code)。 |
| Show the code | 表示して待機 | Open {{verification_uri}} and enter the code. This goes on by itself once you have approved it.、コードをコピー付きのユーザーコード、ブラウザで開くとQRコード付きのリンクを表示します。 |
| Wait for approval | ポーリング | トークンのリクエストを{{interval}}秒ごとに送信し、access_token付きの200が返るまで、最長で{{expires_in}}秒続けます。変数codeはデバイスコードです。このリクエストを選んでください。 |
| Save the tokens | 変数を設定 | accessTokenとrefreshTokenを、環境にシークレットとして保存します。 |
| Done | テンプレート | Signed in; the tokens are in the Keychain. |
| Output | 出力 | そのテキストを返します。 |

Show the codeとWait for approvalは並行して実行されます。ポーリングが送信している間はシートが開いたままで、ポーリングが成功すると自動的に閉じます(successがシートのuntilに接続されています)。
トークンのリクエストは、grant_typeにurn:ietf:params:oauth:grant-type:device_code、device_code={{code}}を付けて送信します。以降は、ほかのリクエストが{{accessToken}}を使います。トークンは環境に保存されるので、環境を選んだ状態でフローを実行してください。
リフレッシュトークン
refresh-token。リフレッシュトークンで新しいアクセストークンを取得し、両方をシークレット変数として保存します。開始ブロックにスケジュールを設定すると、トークンを新しく保てます。
| ブロック | 種類 | 内容 |
|---|---|---|
| Refresh the token | リクエスト | トークンのリクエストを送信します。grant_type=refresh_tokenとrefresh_token={{refreshToken}}です。このリクエストを選んでください。 |
| Save the tokens | 変数を設定 | accessTokenとrefreshTokenを、環境にシークレットとして保存します。新しいリフレッシュトークンがないレスポンスでは、古いものが残ります。 |
| Valid for | 抽出 | $.body.expires_inを取り出します。 |
| Output | 出力 | 新しいトークンが有効な秒数を返します。 |
| Say it failed | 通知 | リクエストが失敗したとき: The token could not be refreshedとThe server answered {{status}}. Sign in again. |
ページを取得して書き出す
paginate-and-export。ページごとに1回リクエストを送信し、すべてのページの項目を1つのリストにまとめて、ワークスペースフォルダのexports/items.jsonに書き込みます。入力pages(数値、デフォルトは3)で、取得するページ数を指定します。
| ブロック | 種類 | 内容 |
|---|---|---|
| Each page | 繰り返す | {{pages}}回実行します。 |
| Page number | 評価 | return { page: index + 1 };で、ページは1、2、3…になります。 |
| Fetch the page | リクエスト | {{page}}を設定してリクエストを送信します(たとえば?page={{page}})。このリクエストを選んでください。 |
| Items | 抽出 | 1ページ分のリストである$.bodyを取り出します。 |
| All pages | 収集 | すべてのページのリストを集めます。 |
| One list | 評価 | return pages.flat();でそれらをつなげます。 |
| Export | ファイルに書き込む | exports/items.jsonをJSONとして書き込みます。 |
| Output | 出力 | ファイルのパスを返します。 |
リストがボディ全体ではない場合は、Itemsのパスを変更します。AlpenglowのCatalog › List productsでは、アドレスに&page={{page}}を追加し、Itemsを$.body.itemsにします。デモAPIは、商品をitemsの下に返します。
死活監視
smoke-monitor。1時間ごとにリクエストを送信し、2秒以内に200で応答するかをチェックします。応答しないときは通知が表示されます。スケジュール(60分ごと)は、すでに開始ブロックに設定されています。開始するには、そこで許可をクリックするか、echolot flow serveで実行します。
| ブロック | 種類 | 内容 |
|---|---|---|
| Send | リクエスト | 監視するリクエストを送信します。このリクエストを選んでください。 |
| Healthy | アサート | Answers 200(value.status === 200)とWithin two seconds(value.time < 2000)をチェックします。 |
| Output | 出力 | 2つのチェックがどちらも成功したときに、レスポンスを受け取ります。 |
| Unhealthy | 通知 | チェックが失敗したとき: Smoke check failedと{{url}} answered {{status}} in {{time}} ms. |
| Failed | 通知 | リクエストが失敗したとき: Smoke check failedとThe request failed or did not answer with a 2xx status. |
アサートのチェックはテストなので、APIが正常でないとecholot flow runは失敗します。そのため、同じフローをCIのチェックにできます。
データ作成と後片付け
seed-and-clean-up。リストの項目ごとに1件のレコードを作成し、作成したものをログに書き、その後で各レコードを削除します。データが必要なチェックは、ログがある場所に置いてください。
| ブロック | 種類 | 内容 |
|---|---|---|
| Records | 値 | [{"title": "First"}, {"title": "Second"}, {"title": "Third"}]。 |
| Each record | 各項目を繰り返す | 各レコードを順に送ります。 |
| Create | リクエスト | レコードを作成します。各レコードのキーがその送信の変数になるため、リクエストでは{{title}}を使います。このリクエストを選んでください。 |
| Its id | 抽出 | $.body.idを取り出します。 |
| Made | 収集 | 新しいIDを集めます。 |
| Use the data | ログ | Seeded {{value}}をログに書きます。データが必要な処理に置き換えてください。 |
| Each id | 各項目を繰り返す | 各IDを順に送ります。 |
| Delete | リクエスト | レコードを削除します。変数は{{id}}です。このリクエストを選んでください。 |
| Deleted | 収集 | 削除したものを集めます。 |
| Count | 評価 | return { deleted: gone.length }; |
| Output | 出力 | 削除した件数を返します。 |
新しいIDがレスポンスの別の場所にある場合は、Its idを変更します。
Alpenglowのフロー
サンプルのワークスペースには、テンプレートと並べて見られる3つのフローがあります。
- Place a test order: サインインし、注文を行い、承認ブロックで注文を残すかどうかをあなたに確認し、拒否されると注文をキャンセルします。エージェントには
place_test_orderとして提供されています。 - Morning stock check: 毎日6:00に商品を一覧取得し、ベルンのテントの在庫が少なくなったときに通知を表示します。
- Order status on webhook:
POST /order-statusに、注文で応答します。
フローで自動化するでは、1つを手順に沿って組み立てます。

