D Apache FreeMarkerリファレンス

組込みのFreeMarker文字列操作

次の表は、testerという文字列変数を使用して、"hello world "に送信される値(末尾に3つの空白文字を含む)を使用して、いくつかの組込み文字列操作の使用方法を示しています。
ノート

次の式を使用すると、ボットでtester値またはno string found (変数に設定された値がない場合)のいずれかを出力できます。
${tester.value!'no string found'}
組込み操作 使用方法 出力
capitalize ${tester.value?capitalize} Hello World
last_index_of ${tester.value?last_index_of('orld')} 7
left_pad ${tester.value?left_pad(3,'_')} ___hello world
length ${tester.value?length} 14
lower_case ${tester.value?lower_case} hello world
upper_case ${tester.value?upper_case} HELLO WORLD
replace ${tester.value?replace('world', 'friends')} hello friends
remove_beginning ${tester.value?remove_beginning('hello')} world
trim ${tester.value?trim} hello world (末尾の3つのスペースが削除されます)
ensure_starts_with ${tester.value?ensure_starts_with('brave new ')} brave new hello world
ensure_ends_with ${tester.value?ensure_ends_with(' my friend')}$ hello world my friend
contains ${tester.value?contains('world')?string ('You said world', 'You did not say world')} You said world

contains('world')式は、trueまたはfalseを返します。これらのブール値は、string ('string1','string2')関数を使用して文字列に置換されます。

ends_with ${tester.value?ends_with('world')?string ('Ends with world', 'Doesn't end with world')} Ends with world
starts_with ${tester.value?starts_with('world')?string ('Starts with world', 'Doesn't start with world')} Doesn't start with world
matches (正規表現がtrueまたはfalseを返す) ${tester.value?matches('^([^0-9]*)$')} この正規表現は、値に数値が含まれているかどうかに応じて、trueまたはfalseを返します(数値が含まれている場合、ブール値はfalseとして返されます)。tester値はtrueを返します。
matches (正規表現が文字列を返す) ${tester.value?matches('^([^0-9]*)$')?} 前述のものと同じですが、この場合はtrueが文字列として返されます。matches('regular expression')関数は、trueまたはfalseをブール型として返します。System.Outputコンポーネントでtrueまたはfalseを出力するには、?stringを使用して文字列への変換を実行します。

ノート: 正規表現を使用して値のグループを返すことはできません。正規表現は、一致する単一の値(または一致なし)を返す場合に使用します。

例: switchコンポーネントを使用した大/小文字の変換

choice変数に格納されているユーザー入力(wineまたはbeer)に応じて異なる状態がコールされる場合を考えてみます。

1つの単語(WiNE)の中でも、ユーザー入力の大/小文字は一貫していない可能性があります。考えられるバリエーションすべてをコンポーネント定義に追加するかわりに、upper_caseなどのFTL操作を使用して大/小文字の違いを統一します:
${choice.value?upper_case}

例: FTL式の連結

FTL操作を単一の式に連結することもできます。

次の例では、UA1234およびUA 1234の航空会社のフライト番号(flight.value変数で表される)が1234に変換されます。
${flight.value?trim?lower_case?remove_beginning('ua ')?remove_beginning('ua')}"

組込みのFreeMarker数値操作

次の表では、組込み数値操作をリストし、negativeValue変数に設定された値(-2.5)およびpositiveValue変数に設定された値(0.5175)がどのように出力されるかを示します。
操作 出力
abs ${negativeValue.value?abs} 2.5

この演算子は、負の数値を正の値に変換します。

string (数値とともに使用) ${negativeValue.value?abs?string.percent} 250%

この演算子は、まず負の値を正の値に変更します。次に、暗黙的にその値に100を乗算して、パーセントに変換します。

string (小数点書式の値および様々な通貨を使用)

ヒント: その他の通貨記号は、Charbaseを参照してください。

${positiveValue.value?string['###.##']} 0.51
${positiveValue.value?string['###.##%']} 51%

この演算子は、値に100を乗算した後でパーセント文字を追加します。

${positiveValue.value?string['##.###\u00A4']} 0.51 $
${positiveValue.value?string['##.###\u20AC']} 0.51 €
${positiveValue.value?string['##.###\u00A3']} 0.51 £
round ${negativeValue.value?round} -2

この演算子は、値を最も近い整数に丸めます。数値が.5で終わる場合は切り上げます。

${positiveValue.value?round} 1

この演算子は、値を最も近い整数に丸めます。数値が.5で終わる場合は切り上げます。

floor ${positiveValue.value?floor} 0

この演算子は値を切り捨てます。

ceiling ${positiveValue.value?ceiling} 1

この演算子は値を切り上げます。

lower_abc ${negativeValue.value?abs?round?lower_abc} c

この演算子は、負の値を正の値に変換した後、3に丸めます。これは、アルファベットの3番目の文字であるcを返します。

upper_abc ${negativeValue.value?abs?round?upper_abc} C

この演算子は、負の値を正の値に変換した後、3に丸めます。これは、アルファベットの3番目の文字であるCを返します。

is_infinite ${positiveValue.value?is_infinite?string} false

IEEE 754 (Standard for Floating-Point Arithmetic)によると浮動小数点値は無限大ではないため、この演算子はfalseを返します。

ノート: 返される値は、?stringなしのブール値になります。

組込みのFreeMarker配列操作

配列(またはシーケンス)操作を使用すると、配列のサイズの確認、配列のソート、配列内のコンテンツの検索などをボットで行うことができます。

配列を使用して、テスト用のモック・データや、ユーザー・セッションが終了しても保持されるデータ構造を定義するためのモック・データを作成できます。配列は、フロー変数またはグローバル変数でカスタム・コンポーネントに保存できます。person変数およびcolors変数の配列をそれぞれ示します。
[
  {
    "firstName" : "Frank",
    "lastName" : "Normal"
  },
  {
    "firstName" : "Grant",
    "lastName" : "Right"
  },
  {
    "firstName" : "Geoff",
    "lastName" : "Power"
  },
  {
    "firstName" : "Marcelo",
    "lastName" : "Jump"
  }
]
[
    "yellow", "blue", "red", "black", "white", "green"
  ]
次の表と例: 配列の反復処理では、これらの配列を使用して配列操作を示します。
演算子 出力
size ${person.value?size?number} 4person配列のサイズ(4人のメンバー)
配列索引 ${person.value[1].firstName} Grant—これは、person配列内の2番目のfirstNameプロパティの値です。
${person.value[1].firstName !'unknown'} 前述のものと同じですが、この場合は、2番目のfirstNameプロパティに値がないときにunknownと出力されます。
first ${person.value?first.firstName} Frank—person配列の最初のエントリ。この操作では、配列索引は使用されません。
last ${person.value?last.firstName} Marcelo—person配列内の最後のlastName値。
sort_by ${person.value?sort_by('lastName') [0].firstName} Marcelo
この演算子は、lastNameプロパティを基準にしてperson配列を昇順でソートします。その後、person配列内の最後のエントリに対応するfirstNameプロパティの値を出力します:
  • Jump, Marcelo

  • Normal, Frank

  • Power, Geoff

  • Right, Grant

ノート: System.SetVariableを使用してソート済配列を変数に保存しないかぎり、データのソートは単一のリクエストについてのみ維持されます。

${person.value?sort_by('lastName')?reverse[0].firstName} Grant—値は降順でソートされます:
  • Right, Grant

  • Power, Geoff

  • Normal, Frank

  • Jump, Marcelo

seq_index_of ${colors.value?seq_index_of('red')} 2—colors配列内のredの索引値。
seq_last_index_of ${colors.value?seq_last_index_of('red')} 2—redの最後の索引値
join ${colors.value?join(',')} colors配列をカンマ区切り文字列として返します: yellow, blue, red, black, white, green
seq_contains ${colors.value?seq_contains('red')?string('Yes', 'No') 配列にredが含まれているため、Yesを返します。

ノート: ?seq_containsはブール値を返します。この値はその後、?string('...','...')式を使用して文字列に置換されます。

sort ${colors.value?sort?join(',')} colors配列を昇順のカンマ区切り文字列として返します: black, blue, green, red, white, yellow
reverse ${colors.value?sort?reverse?join(',')} colors配列を降順のカンマ区切り文字列として返します: yellow, blue, red, black, white, green

インテントおよびスコアの返却

配列操作を使用して、インテントおよびエンティティ処理の結果を返すことができます。例:
  • ${skill.system.nlpresult.value.entityMatches[‘name of entity’]}は、nlpresult変数に格納されたインテント・エンジンに渡されるユーザー文字列で見つかったエンティティの配列を返します。

  • ${skill.system.nlpresult.value.intentMatches.summary[n].intent}は、信頼度ランキングがnのインテントの名前を返します。0は最上位ランクのインテント、1は2番目のランクのインテントなどを表します。

  • ${skill.system.nlpresult.value.intentMatches.summary[n].score}は、指定されたインテントの信頼度スコアを返します。
これらの2つの式の場合、nは検索するアイテムの索引です。たとえば、最上位の解決済インテント名を返す式は次のようになります:
${skill.system.nlpresult.value.intentMatches.summary[0].intent}
最上位インテントのスコアの場合、式は次のようになります:
${skill.system.nlpresult.value.intentMatches.summary[0].score}

これらの式は、信頼度しきい値を超えてスコアリングされたインテントに使用できますが、スコアが信頼度しきい値未満であるインテントを返すためにも使用できます。これらの式は、スキルの「設定」ページで構成されている信頼度しきい値に依存しないため、インテントを解決できず、unresolvedIntentアクションがトリガーされている場合でも、候補者インテントとそのスコアを返すことができます。この場合、たとえば、これらの式を使用して、上位3つのインテントとその信頼度しきい値スコアを返できます。

ノート

明確化を求められた後にユーザーが選択したインテントを参照する必要がある場合は、${system.intent.name}を使用できます。(${skill.system.nlpresult.value.intentMatches.summary[0].intent}は、常に最上位スコアを持つインテントを返します。これは、ユーザーがあいまい化解除時に選択するインテントではない可能性があります。

例: 配列の反復処理

配列では、ユーザー入力のエンティティの数が確認されます。

共通レスポンス・コンポーネントのメタデータ・プロパティの次のスニペットは、person変数に保持されている配列のサイズを決定し、その要素を反復処理してスキルが次のように出力する方法を示しています:


responseItems:
- type: "text"
  text: "${person?index+1}. ${person.firstName} ${person.lastName}"
  name: "Sorry"
  separateBubbles: true
  iteratorVariable: "person"
ノート

このコードで記述される出力はソートされていません(つまり、sort_by操作は使用されていません)。

組込みのFreeMarker日付操作

次の式は、FreeMarker特殊変数参照である.nowと組込みのdate演算子を使用して、現在の日付を導出します。
${.now?date}
次の表に、プロパティの定義およびエンティティ値の操作に使用できる組込み日付操作の一部を示します。
操作 出力
date ${.now?date} 現在の日付
time ${.now?time} 5:46:09 PMのような時刻
datetime ${.now?datetime} Jan 17, 2018 5:36:13 PMのような現在の日時を出力します。
longおよびnumber_to_date ${(.now?long + 86400000)?number_to_date } 現在の日付に24時間を加算します。2018年1月17日にコールされた場合、FreeMarkerではJanuary 18, 2018と出力されます。
string (書式スタイルを使用) ${.now?string.full} 現在の日付をWednesday, January 17, 2018 6:35:12 PM UTCのような書式の文字列に変換します。
${.now?string.long} 日付を文字列に変換してJanuary 17, 20186:36:47 PM UTCのような書式で出力します。
${.now?string.short} 日付を文字列に変換して1/17/18 6:37 PMのような書式で出力します
${.now?string.medium} 日付を文字列に変換してJan 17, 2018 6:38:35のような書式で出力します。
${.now?string.iso}

2018-01-17T18:54:01.129ZのようなISO 8601標準で日付を出力します。

string (指定された出力書式を使用) ${.now?string['dd.MM.yyyy, HH:mm']}

17.01.2018, 18:58のようなカスタム書式で現在の日付を出力します。

${.now?string['yyyy']}

2018

datetime (stringおよび書式スタイルを使用) ${date_variable?datetime?string.short} 日付を1/17/18 6:37 PMのような書式の文字列に変換します。

datetime演算子を使用すると、FreeMarkerは、日付と時刻の両方の情報を含む日付を変数が保持しているかどうかを判断できます。同様に、dateまたはtime演算子を使用して、日付値に日付のみが含まれているか、または時刻のみが含まれているかを示すこともできますが、datetime?stringを使用するとエラーを回避できます。

次のものを使用した文字列へのエンティティ値の変換
  • date

  • long

  • number_to_date

  • 書式スタイル

  • カスタム日付書式

${dateVar.value.date?long?number_to_date?date?string.short} エンティティ抽出からの日付を11/17/18のような書式の文字列に変換します。

date演算子によって、FreeMarkerは変数が日付のみを保持し、時刻情報を保持していないことを認識します。このフォーマットを使用すると、エラーを回避できます。

${dateVar.value.date?long?number_to_date?string.medium} エンティティ抽出から導出された日付をJan 17, 2018のような書式の文字列に変換します。

ノート: fullshortlongisoなどの他の書式はすべて、エンティティ抽出から導出された日付でも同様に機能します。

${dateVar.value.date?long?number_to_date?string['dd.MM.yyyy']} 日付をカスタム書式で出力します。例: 17.01.2018, 18:58。
${dateVar.value.date?long?number_to_date?string['yyyy']} エンティティから導出された日付をカスタム書式で出力します。

例: ユーザー入力からの日付の抽出

次の例は、アポイントを管理するスキルのものです。ユーザーがCan you arrange a meeting with Mr. Higgs a day later than tomorrow?と尋ねると、ボットは、複雑なエンティティであるDATEを使用してリクエストからtomorrowを抽出します。${(theDate.value.date?long + 86400000)?number_to_date}を使用して要求日を出力し、24時間(または86,400,000ミリ秒)を「明日」に追加します。
式を含むテキスト 出力
"Today is: ${.now}"
  • Today is: 1/18/18 8:31 AM
"Date found is: ${theDate.value.date}"
  • Date found is: Jan 19, 2018

"A day later is ${(theDate.value.date?long + 86400000)?number_to_date}"
  • A day later is Jan 20, 2018

例: デフォルト日付の設定(日付値が設定されていない場合)

ユーザー・メッセージに日付情報が含まれていない場合、スキルはユーザーに日付の入力を要求するか、デフォルト日付を提供できます。現在の日付を指定するには、次の式を使用します。

${.now?datetime?string.long}

FreeMarkerがアクセス可能なシステム変数

Oracle Digital Assistantには、FreeMarker式を介してダイアログ・フローで有益な情報を取得するために使用できる一連のシステム変数が用意されています。

最も単純な形式の場合、これらの式は次のような形式になります:

${system.variableName}

変数の中には、次の形式で変数名の後にドット表記を使用してアクセスできる、ネストされたプロパティを持つオブジェクトを保持できるものもあります。

${system.variableName.propertyName}

さらに、ネストされたプロパティ値を、ネストされたプロパティを持つオブジェクトにすることもできます。

FreeMarker式で使用可能なシステム変数を次に示します。

変数 説明
system.actualState ユーザーが古い順不同のボタンをタップしてナビゲートした状態の名前。ポストバック・ペイロードにsystem.stateプロパティが含まれている場合、ダイアログ・エンジンはこの状態にナビゲートして、この変数をその状態の名前に設定します。予期しないアクションのダイアログ・フローの構成も参照してください。
system.authorizedUsers 特定のグループ・チャットが許可されているすべてのユーザーのリスト。
system.channelType 現在のユーザー・セッションのチャネルのタイプ。使用可能な値: facebookandroidsdkiossdkwebsdkslacktwiliomsteamscortanawebhooktest

セッションがテスターで実行されている場合、この値は、シミュレートされているチャネル・タイプに対応します。

system.entityToResolve コンポーネントの変数プロパティがコンポジット・バッグentity.Theオブジェクトを参照している場合に、共通レスポンス・コンポーネントで解決する現在のコンポジット・バッグ・アイテムを表すオブジェクトには、次のプロパティがあります:
  • nextRangeStart - 「さらに表示」ボタンをタップしたときにナビゲートされる、エンティティで許可される値リストの索引番号。
  • updatedEntities - 最後のユーザー・メッセージに基づいて更新されたコンポジット・バッグ・アイテムのリスト。
  • needShowMoreButton - エンティティ値の次のセットにナビゲートする「さらに表示」ボタンを条件に応じてレンダリングするためにvisibleプロパティのexpressionとして使用できるブール・プロパティ。
  • outOfOrderMatches - ユーザーが別のバッグ・アイテムの入力を求められたときに最後のユーザー・メッセージに基づいて値が移入されたバッグ・アイテムのリスト。
  • rangeStartVar - エンティティ値の現在の範囲開始を保持する変数の名前。
  • validationErrors - 現在のバッグ・アイテムについて、最後のユーザー・メッセージで指定された無効な値が原因となって生成されたエラー・メッセージのリスト。
  • allMatches - 最後のユーザー・メッセージに基づいて新しい値または更新された値を取得したバッグ・アイテムのリスト。
  • resolvingField - ユーザーが入力を求められている現在のバッグ・アイテムの名前。
  • userInput - 最後のユーザー・メッセージ。
  • skippedItems - 値の入力要求の最大数を超えたバッグ・アイテムのリスト。
  • disambiguationValues - 最後のユーザー・メッセージに一致がある、許可されたエンティティ値のリスト。
  • enumValues - 現在のバッグ・アイテムについて許可されたエンティティ値のリスト。

system.entityToResolveの使用方法の例は、system.entityToResolve変数を参照してください。

system.errorAction 状態の実行中にスローされた予期しないエラーのエラー・メッセージ・テキスト。
system.errorState 実行中に予期しないエラーをスローした状態の名前。
system.expectedState ユーザーがメッセージ履歴を上にスクロールし、古い順不同のボタンをタップしたときに、実行されると予期されていたが、ユーザーがこの順不同のボタンをタップすることを決定したために実行されなかった状態の名前がこの変数に移入されます。予期しないアクションのダイアログ・フローの構成も参照してください。
system.intent.name Mサイズは箱入りとなりますSサイズは箱なしでのラッピングとなります ギフトボックス・ラッピングについて_______________________________________________
${iResult.value.intentMatches.summary[0].intent}
常に最上位スコアのインテントを返します。これは、ユーザーがあいまい性の解除時に選択するインテントではない可能性があります。)
system.invalidUserInput リクエストされた変数タイプとユーザー入力が一致しない場合にtrueに設定されるブール値。
system.message Oracle Digital Assistantが最後に受信したメッセージ。この変数には次のプロパティがあります:
  • channelConversation - 次のプロパティを持つチャネル会話オブジェクト:
    • botId
    • channelType - テスターで実行されている場合、これはtestを返します。テスターでシミュレートされているチャネルの名前を取得する場合は、かわりにsystem.channelTypeを使用します。
    • channelName
    • channelCategory - チャネルのタイプを返します。DA (エージェント)チャネルの場合、これはbotAsAgentを返します。
    • groupConversation - 会話がグループ・チャットの場合、trueを返します。
    • userId - ユーザーIDを返します。DA (エージェント)チャネルの場合、エンゲージメントIDが返されます。
    • sessionId - セッションIDを返します。DA (エージェント)チャネルの場合、エンゲージメントIDが返されます。
    • sessionExpiryDuration
  • messagePayload - ユーザーによって送信された実際のメッセージ。アクセスできるプロパティは、メッセージのタイプによって異なります:
    • テキスト・メッセージ: ユーザーによって入力された実際のメッセージを返すtextプロパティ
    • ポストバック・メッセージ: ポストバック・オブジェクトのプロパティ(共通レスポンス・コンポーネントを使用している場合は通常、actionおよびvariables)。たとえば、変数pizzaSizeを設定するボタンをユーザーがタップしたときに、次の式を使用してこの値を取得できます: ${system.message.messagePayload.variables.pizzaSize}
    • ロケーション・メッセージ: 次のプロパティを持つロケーション・オブジェクトを保持するlocationプロパティ:
      • title
      • url
      • latitude
      • longitude
  • stateCount - 最後のユーザー・メッセージを処理するために実行された状態の数。
  • platformVersion - 現在のランタイム・プラットフォーム・バージョン。
system.requestedState ユーザーが会話を開始した状態が認可を必要としているが、そのユーザーがsystem.authorizedUsersに格納されているユーザーのリストに含まれない場合、ダイアログ・エンジンは、実行しようとした状態をこの変数に格納します。
system.selectedCardIndex Twilioなどのテキストのみのチャネルに対してカードのレンダリングを最適化する機能を使用するときに、この変数は、選択されたカードの索引を保持します。この最適化では、ユーザーは2ステップのプロセスでカードを選択できます: 最初にカードのリストが表示された後、ユーザーは選択するカードの番号を入力できます。このカードの対応する索引番号がこの変数に格納されます。
ノート

上の表のシステム変数は、FreeMarker式で使用できる唯一の変数です。他のシステム変数は公開されておらず、その使用は変更される可能性があります。つまり、スキルはそれらに依存できません。

たとえば、system.routingFromSkillsystem.routingToSkillsystem.routingFromIntentおよびsystem.routingToIntent変数は、特定のデジタル・アシスタント設定でのみ使用できます。デジタル・アシスタントのシステム変数を参照してください。