埋め込みパネルアプリを作成
このページは機械翻訳を使用して翻訳されています。
はじめに
Panelアプリを使用すると、お客様は特定のCoupaページのUIパネル内に外部ソースからのデータを表示できます。このデータはコンテキスト固有にすることができ、自動または手動で更新できます。たとえば、サプライヤーページがCoupaでロードされると、そのページのPanelアプリは、特定のサプライヤーに関連するAPIを介して外部ソースからデータを自動的に取得し、Coupaでデータを表示できます。
[設定]>[プラットフォーム]>[インストール済みアプリ]に移動してPanelアプリを作成し、[作成]ボタンをクリックして、[新しいPanelアプリを作成]オプションをクリックします。Panelアプリを作成、設定する際に重要なのは、アプリのパラメーターのJSON形式セットである記述子を使用することです。
以下は、CoupaホームページのPanelアプリの例です。
[設定]>[プラットフォーム]>[インストール済みアプリ]に移動して、Panelアプリを作成できます。[作成]ボタンをクリックし、[新しいパネルアプリを作成]を選択します。
必要条件
R29以降、Panelアプリケーションは、サードパーティAPIへの送信接続を確立するために 少なくともTLS v1.2を必要とします。
Panelアプリの基本
Panelアプリは、JSON形式を用いたアプリ記述子を使用して構築されます。記述子は、データとブロックという2つの主要なプロパティーで構成されます。データは、JQ v1.6を使用して処理されます。
プロパティー | 説明 |
---|---|
slot |
パネルがレンダリングされるページタイプを指定します。現在のオプション:
{ "slot": "user.home" } Panelアプリごとに指定できるスロットは1つだけです。アプリを複数のページに表示するには、目的の |
|
データ属性は、パネルにレンダリングされる目的のデータをフェッチする方法を示します。パネルをレンダリングするためにどのデータをフェッチするかを説明するJSONオブジェクト。このオブジェクトの値は、データを取得するためにCoupaがリクエストを送信するURLになります。これらすべてのデータ要求からの応答は1つのハッシュにマージされ、このオブジェクトでそれらに指定されたキー名でエイリアスされます。 "data": { "study_queue": "https://www.wanikani.com/api/user/{user_ID}/study-queue", "level_progression": "https://www.wanikani.com/api/user/{user_ID}/level-progression" } } |
context |
サプライヤーに関する最近の記事を検索するためのNY Times記事検索へのAPI呼び出しは次のようになります。 "data": { "nyt_data": { "uri": "https://api.nytimes.com/svc/search/v2/articlesearch.json? q={context.supplier.name}&api-key={properties.api_key}" } } 各スロットで利用できるコンテキストデータの最新リストについては、Coupaにお問い合わせください。 |
API呼び出しをパラメーター化する(プロパティ) |
パネルアプリを有効にした後にユーザー/管理者が提供しなければならないプロパティの配列。アプリ/ APIで一意のAPIキー、またはそれを有効にするCoupa顧客ごとのログイン/パスワードが必要な場合は、以下の方法でオプションを提供します。 ブロックの例: "properties": { "username": { "type": "string" }, "password": { "type": "string" } } 次に、次のようにデータブロックでプロパティを参照します。 "data": { "my_data": { "method": "post", "uri": "https://someurl.com/EVToken", "body": "grant_type=password&username={{ properties.username }}& password={{ properties.password }}" } } Coupa管理者が新しいパネルアプリを有効にすると、アプリ記述子で指定されたすべての「プロパティ」フィールドに入力するように求められます。 |
launch |
パネルアプリをすぐに表示する必要がない場合に使用できる起動ボタンを追加します。パネルアプリは自動的に第三者に連絡してデータをレンダリングするのではなく、エンドユーザーが手動で起動ボタンをクリックした場合にのみ連絡します。 このJSONオブジェクトには、 "launch": { "description": "PretendCo Tax Calculator Service", "button_text": "Launch Calculator", "help_text": "Tax Calculator integrates with Coupa to help you calculate international taxes, right in the cart." } 使い方
|
allow_refresh |
ページ上のデータが変更され、パネルアプリでレンダリングされたデータに影響を与える場合に使用できる更新ボタンを追加します。Reqラインが更新された時、これはカートパネルアプリにとって便利です。ユーザーは、[更新]ボタンをクリックして、パネルアプリのデータを更新できます。 これはブール値オプションで、パネル記述子のアプリ記述子に更新ボタンを表示するために使用されます。 "allow_refresh": true 使用方法
ボタンをクリックすると、そのアプリのコンテンツが更新されます。このフィールドは、「スロット」、「データ」、「起動」などと同じレベルに追加する必要がありますが、ブロックには追加しないでください。更新ボタンはパネルアプリケーションの上部に表示されます。 |
blocks |
ブロック属性は、パネルでデータをレンダリングする方法を示します。これは、さまざまなタイプのJSONオブジェクト(「ブロック」)の配列で、それぞれが個別のビジュアライゼーションを説明します。ブロックは、以前に送信されたデータにアクセスし、それを使用してビジュアライゼーションを作成します。 |
error_blocks |
エラーブロック属性はブロック属性と同様に機能しますが、データの取得またはレンダリングに問題がある場合にエラーメッセージを作成するために使用されます。 |
データを取得中...
アプリは、アプリのデータをフェッチするために最大5つの別々のHTTP呼び出しを行うことができます。これらは、記述子のデータ属性を使用して指定されます。API呼び出しは、JSON(推奨)またはXMLを返します。
Panelアプリのブロックタイプ
Panelアプリは、ブロックと呼ばれるさまざまなタイプのUI要素を使用して、既存のCoupaページにそのデータをレンダリングします。Coupaは以下のブロックタイプをサポートしています。
- リッチテキスト(画像を含む)
- フィールド(基本的にキーと値のペア)
- 数字
- 貨幣
- テーブル
- 円グラフ
- 折れ線グラフ/棒グラフ
- 立ち上げ
- 再読み込み
アプリケーション設定
属性 | 説明 |
---|---|
|
ブロックのタイプを識別します。たとえば、 |
|
このJSONオブジェクトは戦略によって異なるプロパティーを持っています。 JQ
JQでデータを処理する たとえば、次のJQスクリプトを使用していくつかの特定のデータピースを抽出し、別のJSONオブジェクトに再パッケージ化できます。 { "username": ".study_queue.user_information.username", "radicals": ".level_progression.requested_information.radicals_progress", "kanji": ".level_progression.requested_information.kanji_progress" } これにより、次のJSONオブジェクトが生成されます。 { "username": "example_user", "radicals": 0, "kanji": 0 } 詳細情報: |
|
異なるブロックタイプには、そのブロックタイプに固有の他のプロパティーがあります。 |
Panelアプリのブロックタイプ
テキストブロック
属性 | 説明 |
---|---|
|
以下と等しい |
template |
テキストブロックタイプはLiquid Markdownテンプレートを使用します。テンプレートは最初にLiquidとして解析され、リクエストから返されたデータを補完します。次に、テンプレートはMarkdownとして再度解析され、HTMLが生成されます。 Markdownは安全なHTML生成方法を提供し、セキュリティー上の理由からCoupaはテンプレート内のインラインHTMLをブロックします。ブロックの構成を保存するデータ列の最大制限以外の文字制限はありません。 Markdownでは、ヘッダー、インライン強調フォーマット、リスト、画像、リンク、ブロック引用が可能です。Coupaは構文の強調表示とテーブルもサポートしています。 LiquidとMarkdownの使用に関する詳細については、「 Liquidテンプレート言語」と「Markdownをマスターする」を参照してください。 |
data |
データ戦略は、単一のJSONオブジェクトを生成する必要があります。オブジェクト内のすべてのキーは、Liquidテンプレートで変数として使用できます。 { "foo": "bar", "fizz": { "buzz": "buzz" } } |
フィールドブロック
属性 | 説明 |
---|---|
|
以下と等しい |
data |
データ戦略は、ラベルと値の属性を持つJSONオブジェクトの配列を作成する必要があります。レンダリング時、ラベルはフィールドラベルとして使用され、値はフィールド値として使用されます。 [ { "label": "Foobar", "value": "fizzbuzz" }, { "label": "Lorem Ipsum", "value": 42 } ] |
title |
フィールドのリストの上に表示されるオプションのタイトル。 |
テーブルブロック
属性 | 説明 |
---|---|
|
以下と等しい |
data |
データ戦略は、配列の配列を生成する必要があります。 [ ["col1", "col2", "col3"], [1, 2, 3], [4, 5, 6] ] |
headers |
ブール値、既定は。false true の場合、データの最初の行はテーブルのヘッダーとして扱われ、特別なスタイルが適用されます。 |
title |
テーブルの上に表示されるオプションのタイトル。 |
description |
小さいテキストでフィールドの下に表示されるオプションの説明。 |
棒/折れ線ブロック
属性 | 説明 |
---|---|
|
以下と等しい |
data |
データ戦略は、配列の配列を生成する必要があります。テーブルブロックとは異なり、棒/折れ線グラフのデータは列指向になります。 各配列は、表示される一連のデータを表します。最初の要素はシリーズの名前で、残りの要素はシリーズのポイントです。 [{ "name": "Year 1800", "data": [107, 31, 635, 203, 2] }, { "name": "Year 1900", "data": [133, 156, 947, 408, 6] }, { "name": "Year 2000", "data": [814, 841, 3714, 727, 31] }, { "name": "Year 2016", "data": [1216, 1001, 4436, 738, 40] }] |
axis |
x軸とy軸のラベルを設定できます。 |
title |
グラフの上に表示されるオプションのタイトル。 |
description |
小さいテキストでグラフの下に表示されるオプションの説明。 |
円ブロック
属性 | 説明 |
---|---|
|
以下と等しい 円 |
data |
データ戦略は、「棒/折れ線ブロック」セクションで説明されているように、配列の列指向の配列を作成する必要があります。 [{ name: 'Chrome', y: 20.41, sliced: true, selected: true }, { name: 'Internet Explorer', y: 11.84 }, { name: 'Firefox', y: 10.85 }, { name: 'Edge', y: 4.67 }, { name: 'Safari', y: 4.18 }, { name: 'Sogou Explorer', y: 1.64 }, { name: 'Opera', y: 2.8 }, { name: 'Other', y: 2.61 }] |
title |
グラフ上に表示されるオプションのタイトル。 |
description |
小さいテキストでグラフの下に表示されるオプションの説明。 |
貨幣ブロック
属性 | 説明 |
---|---|
|
以下と等しい 貨幣 |
data |
データ戦略は、次の構造を持つJSONオブジェクトを生成する必要があります。
{ "amount": 42.0, "currency": "USD" } |
Title |
数字の上に表示されるオプションのタイトル。 |
Description |
小さいテキストで数字の下に表示されるオプションの説明。 |
数字ブロック
属性 | 説明 |
---|---|
|
以下と等しい 数字 |
Data |
データ戦略は、単一のJSON整数または浮動小数点を生成する必要があります。 42.0 |
Decimal |
小数点の後に表示する小数点以下の桁数。既定は0です。 |
Title |
数字の上に表示されるオプションのタイトル。 |
Description |
小さいテキストで数字の下に表示されるオプションの説明。 |
APIの詳細
認証
Coupaは以下の認証タイプをサポートしています:
方法 | 例 |
---|---|
標準APIキー |
"data": { "nyt_data": { "uri": "https://api.nytimes.com/svc/search/v2/articlesearch.json?q={context.supplier.name} &api-key={properties.api_key}" } } |
基本認証 |
"data": { "trip_data": { "uri": "https://someurl.net/trips", "headers": {"Authorization":"basic YOUR_BASE64_ENCODED_TOKEN_HERE"} } } |
「before_data」リクエストを使用した有効期間の短いトークンのリクエスト |
"before_data": { "auth": { "method": "post", "uri": "https://someurl.com/MYToken", "body": "grant_type=password&username={{ properties.username }}&password={{ properties.password }}" } }, "data": { "risk_data": { "uri": "https://someurl.com/MYData?integration_id=%22ID{context.supplier.id}%22", "headers": { "Authorization": "bearer {{ before_data.auth.access_token }}" } } } |
API URL
- URLはHTTPSである必要があります
- CoupaサーバーからURLにアクセスできる必要があります(つまり、HEADリクエストは成功する必要があります)
- URLは有効なLiquidテンプレートとして正常に解析される必要があります。これは補間を有効にするためのものです
APIリクエストの詳細
- Liquidを使用してデータをURLに補間する場合、結果は有効なURLでなければなりません
- 応答コードは200または204でなければなりません
- リモートサーバーは5分のタイムアウト期間内に応答する必要があります
- 回答のコンテンツタイプは
application/json
またはapplication/xmlのいずれかにしてください
ボタン
パネルアプリの 起動ボタン(launch
)と 更新ボタン(allow_refresh
) を設定できます。機能はブロックのように見えますが、技術的にはボタンはブロックではありません。ボタンの詳細については、この記事Panel App basicsセクションをご覧ください。詳細については。
パネルアプリのペイロード
R29以降、以下のページのPanelアプリを作成できます:
- ホームページ:
/
と/user/home
- サプライヤーページ:
/suppliers/:id/record
- 契約ページ:
/contracts/show/:id
- カート
/requisition_headers/{id}/edit
- プロジェクトのホームページ:
projects.show
- ソーシングイベント設定ページ:
quotes/requests.show
各Panel Appタイプには、独自のコンテキストペイロードがあります。以下は、データを照合および検索するためのコンテキストとして使用される、Panel Apps APIペイロードで提供されるフィールドです。
ページ | 可能なフィールド |
---|---|
すべてのパネルアプリ | user_instance (つまり、[ドメイン名] .coupahost.com)は、ペイロードに含まれています。 |
ホームページ | id 、 email 、 fullname 、 login 、 employee_number |
サプライヤーページ |
/ custom_fields |
契約ページ | id 、 parent_contract_id 、 name 、 number 、 version 、 supplier_id 、 start_date 、 status |
カート | カートパネルアプリのペイロードには、申請書ヘッダーAPIペイロードと同じフィールドが含まれます |
プロジェクト | すべてのプロジェクトシステムフィールドとカスタムフィールド |
ソーシングイベント |
|
パネルアプリの例
Coupa Cats
このシンプルなアプリは猫に関連するランダムな画像と事実を示しています。
これはアプリを動かすコードです。
{ "properties": {}, "slot": "user.home", "before_data": {}, "data": { "cat_data": { "uri": "https://aws.random.cat/meow" }, "fact_data": { "uri": "https://cat-fact.herokuapp.com/facts/random" } }, "blocks": [ { "type": "text", "data": { "type": "jq", "jq": ".cat_data" }, "text": "{:height=\"450px\"}" }, { "type": "text", "data": { "type": "jq", "jq": ".fact_data" }, "text": "## Here's an interesting fact about cats:\n\n{{ text }}" } ] }
ニューヨークタイムズの記事検索
このアプリでは、ニューヨークタイムズからのサプライヤーに関する最近のニュースをサプライヤーのページに追加します。これを機能させるには、NYT APIキーを取得する必要があります。
これはアプリを動かすコードです。
{ "properties": { "api_key": { "type": "string" } }, "slot": "suppliers.show", "before_data": { }, "data": { "nyt_data": { "uri": "https://api.nytimes.com/svc/search/v2/articlesearch.json?q={context.supplier.name}&api-key={properties.api_key}" } }, "blocks": [ { "type": "text", "data": { "type": "jq", "jq": "{ \"docs\": .nyt_data | .response | .docs }" }, "text": "{:height=\"100px\"}" }, { "type": "text", "data": { "type": "jq", "jq": "{ \"docs\": .nyt_data | .response | .docs }" }, "text": "1. [{{ docs[0].headline.main }}]({{ docs[0].web_url }}) \n2. [{{ docs[1].headline.main }}] ({{ docs[1].web_url }})\n3. [{{ docs[2].headline.main }}]({{ docs[2].web_url }})\n4. [{{ docs[3].headline.main }}]({{ docs[2].web_url }})\n5. [{{ docs[2].headline.main }}] ({{ docs[4].web_url }})\n" } ] }
天気パネルアプリ
この例のアプリは、場所の温度の側面のグラフィック表現を示しています。これを機能させるには、NYT APIキーを取得する必要があります。
これはアプリを動かすコードです。
{ "properties": { "api_key":{ "type": "string" } }, "slot": "user.home", "data": { "chicago_data": { "method": "get", "uri": "https://api.openweathermap.org/data/2.5/weather?q=Chicago&appid={properties.api_key}&units=imperial" } }, "blocks": [ { "type": "bar", "title": "Here's the weather in Chicago", "data": { "type": "jq", "jq": "[{name:\"Temp\",data:[.chicago_data.main.temp]},{name:\"WindSpeed\",data:[.chicago_data.wind.speed]}, {name:\"Humidity\",data:[.chicago_data.main.humidity]}]" }, "axes": { "xAxis": { "labels": { "enabled": false } }, "yAxis": { "title": { "text": "" }, "max": 100 } } }, { "type": "line", "title": "Here's the weather in Chicago", "data": { "type": "jq", "jq": "[{name:\"Minimum, Current, MaxTemp\", data:[[.chicago_data.main.temp_min],[.chicago_data.main.temp], [.chicago_data.main.temp_max]]}]" }, "axes": { "xAxis": { "labels": { "enabled": false } }, "yAxis": { "title": { "text": "" }, "max": 70 } } } ] }
Panel App APIの例
以下は、自動テストに使用されるアプリ記述子です。正確にこれを返すためにAPI応答をスタブ化します:
[ { "data_title":"Title", "data_number":42, "second_score":88 } ] { # Here is where you'd setup client specific fields. Like login/password. The customer would be prompted to fill in # those values once, when activating the application "properties": {}, # This is the page where the app gets displayed. See the "slot" property for possible values. "slot": "suppliers.show", # Some APIs require a bearer token, or a 2-step process, this is where you handle that. "before_data": {}, "data": { "coupa_data": { # You can add context specific values to this API call, {{context.contract.supplier_name}} for example "uri": "http://fake.test", # This works intuitively, just specify your API headers here, Bearer token, params, etc. "headers": {} } }, "blocks": [ { "type": "number", # This is hard-coded title for this block, cant use api data, or contextual data here "title": "Title for number block", # "coupa_data" was the API response above, .[0] returns the stuff in the {}, ".data_number" gets the value, # in this case "42" "data": { "type": "jq", "jq": ".coupa_data | .[0] | .data_number" } }, # So this block renders a specially formatted number block, with the number "42" in large bold font, # and a text label/title of "Title for number block" { # Fields block has some of the strictest requirements for data, It displays all data in key -> value pairs "type": "fields", "data": { "type": "jq", "jq": ".coupa_data | .[] | to_entries | map({ label: .key, value: .value })" } }, { # For this block, we are just going to pull the hash out from the [] and use the values inside it "type": "text", "data": { "type": "jq", "jq": " .coupa_data | .[0]" }, # Text blocks gives you a lot of flexibility for displaying data from the API response in context. # The text can be formatted just like markup, so you can create links, tables, render/resize images, etc. "text": "{{ data_number }} is the data_number" }, { # Setting up the bar graph is pretty tricky, maybe work with us if you want to go this route. # But this example creates a bar graph with values/labels bar sizes based on the values in the API response "type": "bar", "title": "Bar graph with fake data", "data": { "type": "jq", "jq": "[{name: \"Overall Score\", data: [.coupa_data | .[0].data_number]}, {name: \"Environment score\", data: [.coupa_data | .[0].second_score]}]" }, "axes": {"xAxis": {"labels": { "enabled": false}}, "yAxis": {"title": { "text": ""}, "max": 100} } } ] }
パートナーのインスタンスでテストする
Coupaでこれをテストするには、バージョンR25.0以降である必要があります。最終的に、アプリはカスタムPanelアプリではなく、アプリディレクトリの一部になりますが、Coupaがアプリをアプリディレクトリに正式に追加する前に、これらの手順を使用して独自にテストできます。
- 設定に移動
- [プラットフォーム]で、[インストール済みアプリ]をクリックします。
- [作成]ボタンをクリックし、[新しいパネルアプリを作成]を選択します。
- アプリを作成
- 名前を追加
- 記述子セクションに、上記のコードを含めます。
完了すると、エラーがない場合、パネルアプリが各サプライヤーのページに表示されます。