2017年2月3日金曜日

GAS のようなリダイレクトが絡む HTTP 呼出しを LogicFlow で扱う

LogicFlow において HTTP コネクタはよく利用するものの一つですが、現在の仕様としてアクセスするとリダイレクトするものについては、実行時にエラーとなってしまいます。この場合の対応についてとある人から質問がきたので色々試してみました。

お題となったのは Google Action Script です。これは通常の API のように、POST でアクセスすることも可能ですが、その場合には色々とパラメータを設定したり、認証をどうこうする必要があります。そのため、別の手段として GET でアクセスする方法も用意されており、こちらを利用した場合はブラウザでみているように API を利用できるようになっています。

ただし、GET でアクセスした場合、結果は別のアドレスへとリダイレクトが行われます。

image

GAS の場合、このような形で Response Body にリダイレクト先の情報が設定されてきます。ブラウザで見ている場合は、自動でこのリンク先へとリダイレクトされますが、LogicFlow の HTTP コネクタではそれは手動で行う必要があります。

image

手動で行う場合は、上記のように HTTP コネクタが失敗した場合に、後続の処理を動かせるようにする必要があり、過去のエントリにもあったように runAfter 設定を用いて、「失敗した場合に実行する」という記述を行います。

image

runAfter の記述は CodeView でのみ行えます。CodeView 上で、runAfter の箇所に、条件として HTTP 呼出しを行ったコネクタ(上記例では HTTP という名前)が失敗(Failed)したら、という記述を行っておきます。こうすることで、HTTP コネクタが失敗(200 以外のステータスが戻された)場合に、処理を継続することができます。

そしてここからが力技ですw

戻されたリダイレクトの情報は、HTML で記述されておりそのままでは LogicFlow 上で扱うのが困難です。このような場合は、力づくで XML に変換します。LogicFlow の XML 関数は、渡された文字列や JSON 値を XML として変換しますが、その条件は XML として読める文字列であること、で具体的には先頭一行目に XML を表す

<?xml version=\"1.0\" encoding=\"utf-8\" ?>

という一行を加えます。文字列の結合は concat 関数で行えますので、次のように LogicFlow を記述します。

image

@xml(concat('<?xml version=\"1.0\" encoding=\"utf-8\" ?> ',body('HTTP')))

上記のように記述すると、HTTP コネクタの結果に、xml version ~なヘッダ情報を付与し、その結果を xml 関数で XML に変換します。こうすることで、戻された情報からリンク先の情報を取得するための下準備が行えたことになります。

image

次に、XML に変換した結果から、A タグで設定されているリダイレクト先の情報を抽出します。この場合では xpath 関数を利用して、特定の要素の特定の属性値を抽出させています。上記で言うと、BODY タグの中にある A 要素で指定されている HREF 属性、を文字列として取得させています。こうすることで取得できた結果が次のようなものです。

image

この結果がリダイレクト先の URL となっていますので、この値を用いて再度 HTTP コネクタでアクセスします。

image

ここでは URL に先ほど抽出した結果を設定しています。これで、リダイレクト先にアクセスして、結果を得ることができます。

image

このように、GET で GAS にアクセスし、リダイレクト先から結果の JSON を取得できました。

今回の場合、この取得した値に一癖あり、JSON の要素名に : が使われているのですが、

LogicFlow では現状 : が含まれた名前を扱えません。

そのため、この結果を JSON として扱う前に、名前から:を除去しておく必要がありました。具体的には、以下のように replace 関数を用いて、今回の名前で利用されている ga: という部分を ga に置き換える、ということを行っています。:だけ置き換えようとすると、JSON の名前と値を区切っている箇所の:も変換してしまうので、そこはちょっとだけ注意が必要です。

image

今回は取得した結果から、gadate という名前に設定されていた値を Slack に投稿させています。

slackres

このように、無事に結果から必要な値だけを連携することができました。

リダイレクトを含んでいる場合は、このような形で「HTTP 失敗時の処理」を記述することで対応が可能です。最後に今回作成した LogicFlow の JSON 定義を置いておきますので、似たようなことをやる人は参考にしてみて下さい。

0 件のコメント:

コメントを投稿