注: 以下の翻訳の正確性は検証されていません。AIPを利用して英語版の原文から機械的に翻訳されたものです。
このページのソースのインポート手順とコード例は、TypeScript v1 関数に固有のものです。オントロジー SDK のサポートや設定可能なリソースリクエストなど、より充実した機能を利用するには、TypeScript v2 への移行を推奨します。
このガイドでは、Webhook を使用して外部システムにリクエストを送信できる関数を設定する手順を説明します。
代わりに TypeScript v2 または Python 関数で Webhook を使用するには、Webhook 関数として公開します。公開済みの関数を関数リポジトリにインポートし、オントロジー SDK を使用して呼び出します。Webhook 関数は、Workshop、関数ベースのアクション、およびほかの関数からも呼び出せます。
アウトバウンドアプリケーションを元にした Webhook がサポートされています。詳細については、アウトバウンドアプリケーションの設定ページのサポートされるワークフローセクションを参照してください。
このガイドに沿って進める前に、次の準備が完了していることを確認してください。
まず、ソースを Code Repositories にインポートできるようにする必要があります。これを行うには、REST API ソースのコードのインポートを有効化メニューに移動し、ソースを Code Repositories にインポートできるようにするオプションを有効にします。関数が使用されるすべてのワークフローでエクスポート可能なマーキングの検証を実行できるわけではないため、各ソースのエクスポートを有効化メニューで、マーキングの検証を行わずにソースにエクスポートすることも有効にする必要があります。


次に、関数で Webhook を使用するには、Webhook の元となる REST API ソースをまずリポジトリにインポートする必要があります。左側のリソースのインポートパネルを選択すると、リポジトリにインポートされたソースが表示されます。追加 > ソースを選択すると検索ダイアログが表示され、インポートするソースを選択できます。このダイアログからインポートできるのは、API名を持つソースのみです。

Webhook の使用を目的とした関数リポジトリへのソースのインポートは、Python トランスフォームのリポジトリや Compute Module へのソースのインポートとは動作が異なります。特定のソースを Webhook の使用のみに利用する関数リポジトリは、ソースの概要に表示されるリポジトリの一覧には_表示されません_。ソースに対して閲覧者のアクセス権を持つユーザーは、その Webhook をインポートし、外部関数で使用できます。
REST API ソースを関数リポジトリにインポートすると、TypeScript 環境で利用可能になり、ソースの名前空間を通じてアクセスできます。
Copied!1 2import { Function } from "@foundry/functions-api"; import { MyDictionarySource } from "@foundry/external-systems/sources";
Cannot find module '@foundry/external-systems' or its corresponding type declarations. エラーが発生した場合は、functions-typescript/functions.json ファイルで enableExternalSystems の値が true に設定されていることを確認してください。更新して変更をコミットすると、システムによって @foundry/external-systems を含む必要なパッケージがインストールされるはずです。

以下の例では、1個の関数を使用して辞書 API を複数回呼び出す方法を説明します。
関数でオントロジーを編集しない場合は、@Query() 関数を作成します。オントロジーを編集する場合は、代わりに @OntologyEditFunction デコレーターが必要です。関数からのオントロジーの編集については、ドキュメントを参照してください。
標準の TypeScript async/await パターン ↗ を使用すると、関数から複数の Webhook 呼び出しを同時に実行できます。@foundry/functions-api からエクスポートされる isOk ヘルパー関数を使用して、呼び出しの成功を確認します。
次の関数は、単語のリストを TypeScript の文字列配列として受け取り、単語ごとに1回呼び出しを行います。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26import { OntologyEditFunction, isOk } from "@foundry/functions-api"; import { MyDictionarySource } from "@foundry/external-systems/sources"; export class MyFunctions { @OntologyEditFunction() public async defineWords(words: string[]): Promise<void> { const results = await Promise.all(words.map(word => MyDictionarySource.webhooks.GetDefinition.call({ wordToDefine: word }))); results.forEach((result, i) => { if (isOk(result)) { const output = result.value.output; output.dictionary_definitions.forEach(definitions_for_word => { definitions_for_word.meanings.forEach(meaning => { meaning.definitions.forEach(def_for_part_of_speech => { console.log(`Found a ${meaning.partOfSpeech} definition for "${words[i]}": ${def_for_part_of_speech.definition}`); }) }) }); } }); } }
入力が ["tuba", "cool"] の場合のログ出力:
LOG [2023-07-28T03:16:22.968Z] Found a noun definition for "tuba": A large brass musical instrument, usually in the bass range, played through a vibration of the lips upon the mouthpiece and fingering of the keys.
LOG [2023-07-28T03:16:22.968Z] Found a noun definition for "tuba": A type of Roman military trumpet, distinct from the modern tuba.
LOG [2023-07-28T03:16:22.968Z] Found a noun definition for "tuba": A large reed stop in organs.
LOG [2023-07-28T03:16:22.968Z] Found a noun definition for "tuba": A Malayan plant whose roots are a significant source of rotenone, Derris malaccensis.
LOG [2023-07-28T03:16:22.968Z] Found a noun definition for "tuba": A reddish palm wine made from coconut or nipa sap.
LOG [2023-07-28T03:16:22.968Z] Found a noun definition for "tuba": A tube or tubular organ.
LOG [2023-07-28T03:16:22.968Z] Found a noun definition for "cool": A moderate or refreshing state of cold; moderate temperature of the air between hot and cold; coolness.
LOG [2023-07-28T03:16:22.968Z] Found a noun definition for "cool": A calm temperament.
ネットワーク接続されたシステムを操作する際の失敗に対処しやすくするため、関数は Result オブジェクトを使用して Webhook から伝播されたエラーを公開します。このオブジェクトには、発生したエラーの種類に関する情報が含まれます。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29import { OntologyEditFunction, isOk } from "@foundry/functions-api"; import { MyDictionarySource } from "@foundry/external-systems/sources"; export class MyFunctions { @OntologyEditFunction() public async defineWords(words: string[]): Promise<void> { const results = await Promise.all(words.map(word => MyDictionarySource.webhooks.GetDefinition.call({ wordToDefine: word }))); results.forEach((result, i) => { if (isOk(result)) { // レスポンスを抽出します } else { const errorName = result.error.name; if (errorName === "WebhookExecutionFailedToStart") { console.log("We were unable to initiate a request to the dictionary API."); } else if (errorName === "ParsingResponseFailed") { console.log("The external request succeeded, but the response couldn't be parsed."); } else { console.log("Something went wrong."); } } }); } }
エラーを処理する際は、作成するコードで特定の名前を検知し、それに応じた処理を行う必要があります。現在、関数は次のエラーを返します。
| エラー | 説明 |
|---|---|
WebhookExecutionFailedToStart | Webhook の開始に失敗しました。このエラーが返された場合、外部システムへのリクエストは行われていないと考えて問題ありません。 |
WebhookExecutionTimedOut | Webhook の実行は開始されましたが、設定された Webhook の制限時間内に外部システムからレスポンスを受信できませんでした。 |
RemoteRestApiReturnedError | 外部システムがエラーを返しました。REST API ソースに設定された Webhook の場合にのみ返されます。 |
RemoteApiReturnedError | 外部システムがエラーを返しました。REST API 以外のソースに設定された Webhook の場合にのみ返されます。 |
ParsingResponseFailed | Webhook の実行には成功しましたが、外部システムからのレスポンスを正常にパースできませんでした。たとえば、外部システムからのレスポンスに期待されるフィールドが含まれていなかった場合に発生することがあります。Webhook 呼び出しの結果が必ずしも使用されるとは限らないため、これをエンドユーザーに対して失敗として指定するかどうかは、アプリケーションの作成者が判断します。 |
ServerError | Webhook サービスまたはコネクター内で内部的な問題が発生しました。 |
UnknownError | どの Foundry サービスにも直接原因を特定できないエラーが発生しました。 |
このエラーの種類の一覧は変更される可能性があります。関数のエグゼキューターが新しい名前のエラーを返す場合に備えて、コードにデフォルトのケースを含める必要があります。
次のコードは、同じ関数内で一部が成功し、一部が失敗する複数の Webhook 呼び出しを処理する方法を示しています。この例では、辞書サーバーが指定された単語の定義を見つけられない場合に、RemoteRestApiReturnedError が返されます。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30import { OntologyEditFunction, isOk } from "@foundry/functions-api"; import { MyDictionarySource } from "@foundry/external-systems/sources"; export class MyFunctions { @OntologyEditFunction() public async defineWords(words: string[]): Promise<void> { const results = await Promise.all(words.map(word => MyDictionarySource.webhooks.GetDefinition.call({ wordToDefine: word }))); results.forEach((result, i) => { if (isOk(result)) { const output = result.value.output; output.dictionary_definitions.forEach(definitions_for_word => { definitions_for_word.meanings.forEach(meaning => { meaning.definitions.forEach(def_for_part_of_speech => { console.log(`Found a ${meaning.partOfSpeech} definition for "${words[i]}": ${def_for_part_of_speech.definition}`); }) }) }); } else { if (result.error.name === "RemoteRestApiReturnedError") { console.log(`ERROR: ${words[i]} could not be defined`, result.error.message); } } }); } }
上記の関数に ["asdf", "shire"] を入力すると、次の結果が返されます。
LOG [2023-07-28T15:38:47.263Z] ERROR: asdf could not be defined Request returned an unsuccessful response code: 404 Response body: {"title":"No Definitions Found","message":"Sorry pal, we couldn't find definitions for the word you were looking for.","resolution":"You can try the search again at later time or head to the web instead."}
LOG [2023-07-28T15:38:47.264Z] Found a noun definition for "shire": Physical area administered by a sheriff.
LOG [2023-07-28T15:38:47.264Z] Found a noun definition for "shire": Former administrative area of Britain; a county.
LOG [2023-07-28T15:38:47.264Z] Found a noun definition for "shire": The general area in which a person lives or comes from, used in the context of travel within the United Kingdom.
LOG [2023-07-28T15:38:47.264Z] Found a noun definition for "shire": A rural or outer suburban local government area of Australia.
LOG [2023-07-28T15:38:47.264Z] Found a noun definition for "shire": A shire horse.
LOG [2023-07-28T15:38:47.264Z] Found a verb definition for "shire": To (re)constitute as one or more shires or counties.
現在、オントロジー編集関数内から実行できるリクエストの数に制限はありませんが、既存の関数のリソース制限は引き続き適用されます。Webhook の制限も適用されます。
関数は現在、次の入力および出力のデータ型を持つ Webhook をサポートしています。
@Query 関数から Webhook を呼び出す場合、Webhook は外部システムを変更しない Read API 呼び出しのみを実行する必要があります。クエリ関数は頻繁に再試行されたり、ページの読み込み時に通知なく実行されたりするため、@OntologyEditFunction で可能な、体系的かつ意図的な実行と同じ水準を提供しません。Webhook を設定する際は、Read API または Write API のオプションを使用して、クエリ関数から安全に実行できるかどうかを指定できます。
OR 型を使用する Webhook には、現在対応していません。これらの Webhook に対してコードは生成されません。関数と Webhook にはバージョンがあり、呼び出し元は関数または Webhook の任意のバージョンを呼び出せます。関数が公開されると、その時点で利用可能な最新の Webhook バージョンが固定されます。
Code Repositories アプリケーションで関数リポジトリを開くと、オートコンプリートに使用される生成済みコードバインディングは、常に Webhook の最新バージョンを使用します。この Webhook バージョンは、左側のリソースのインポートサイドパネルに表示されます。

Webhook の機能に依存する関数を公開する前に、Webhook が安定していることを確認してください。
Webhook または関数を変更した場合は、忘れずに関数を再公開し、ユーザーが新しいバージョンを使用するように更新してください。以前に公開され、バージョンが固定された関数は、引き続き利用可能です。
次のテーブルは、外部関数の開発、公開、利用に必要な権限をまとめたものです。
| 操作 | ユーザー | 必要な権限 |
|---|---|---|
| Webhook を関数リポジトリにインポートする | 関数の編集者 | Webhook に対する webhooks:editor 権限。この権限は、編集者デフォルトロールに付与されます。 |
| Webhook を呼び出す関数を公開する | 関数の編集者 | ソースに対する webhooks:execute 権限。この権限は、所有者および編集者デフォルトロールにのみ付与されます。 |
Webhook を呼び出す @OntologyEditFunction() を使用するようにアクションを設定する | アクションの編集者 | Webhook に対する webhooks:grant-action-validated-execution 権限、および関数に対する閲覧者権限 |
Workshop から @Query() Webhook を実行する | エンドユーザー | ソースに対する webhooks:execute 権限。この権限は、所有者および編集者デフォルトロールにのみ付与されます。 |
アクションから @OntologyEditFunction() を実行する | エンドユーザー | ユーザーは、アクションの実行条件を満たす必要があります。この場合、ソース、Webhook、関数に対する権限は確認されません。アクションを作成および管理するユーザーは、実行条件が適切に設定されていることを確認する必要があります。 |
関数からの Webhook 実行について、より多くのインサイトを得るには、次のプラットフォームツールを使用します。
外部ソースを使用して関数から Webhook を呼び出す場合は、次のベストプラクティスを推奨します。
record 型パラメーターを使用します。JSON ではなく明示的なデータ型を使用することで、関数コードで予期しない実行時エラーが発生する可能性が低くなります。@foundry/functions-api からエクスポートされる組み込み関数 isOk と isErr を使用して、成功状態とエラー状態を確認し、name フィールドを通じてエラーの種類を絞り込みます。