[RPAExpress]BOTスクリプトの可読性を確保するスニペット、他Tips

皆さんこんにちは。しうへいと申します。

先日、WorkFusion社が開発するRPA製品であるRPAExpress、およびWorkFusion SPAについて、
触れる機会がありました。
期間にして一ヶ月程度ですが、今回はそれらを扱う上で役立つ（と思われる）Tipsを書いてみようと思います。

### 無償版RPAExpressと有償版WorkFusion SPAの違いについて

端的に言いますと、仮に、プロジェクトで有償版のWorkFusion SPAを採用することになったとしても、
開発者が自分のマシンにインストールして開発を行うのは、
WorkFusion公式で誰でも入手できる無償版のRPAExpressです。

RPAExpress / WorkFusion SPA（以下、区別しないときはWorkFusionと呼びます）には、
以下のコンポーネントが含まれています。

- WorkFusion Studio
 - 開発者が一番にイメージするやつ。Eclipseのガワを変えたやつ
 - BOTのレコーディングと、実行と、編集ができる。
 - Contol Towerを使わないと機能が乏しい（WorkFlowが存在しない）
 - 有償版は存在しないと聞いている…
- Control Tower
 - GUIでWorkFlowを書いたり、それを実行したりするやつ
 - 有償版とは機能が少し違うと聞いている（特にML関連の有無）
- Workspace
 - 人間をWorkflowに介在させるための簡単なWebアンケートフォームのようなもの
 - RPA製品を使っても、いきなり業務を全自動化するのは無謀。人間を介在させたい。
 - フォームはControl Tower上で作る。


有償版WorkFusion SPAでは、これらのコンポーネントは別々のサーバーにインストールされますが、
RPAExpressでは、これらはすべてローカルのリソースを使用しています。
開発者はローカル環境でBOTスクリプトやBusiness Process（WorkFlow)の修正をして、
うまくできたらWorkFusion SPAに持っていくというのが開発のサイクルになるでしょう。

Control TowerのTop画面はこんな感じです。
<img width="1021" alt="Control Tower Top" src="https://qiita-image-store.s3.amazonaws.com/0/105865/46f0f6df-bceb-9dca-76cd-97b627949068.png">

Control Towerの使い方に慣れることでグッとWorkFusionの全体像が見えてきますので、
最初はその辺のドキュメントを読むことをおすすめします。

機械学習に関連しては、今回あまり触れられなかったのですが、聞きかじった話によれば、
他の環境で学習済みのモデルを、WorkFusion独自のAutoML SDKで統合しWorkFusionで扱えるようにし、（ここまでは多分無料版でもできる？）
あとはControl Tower上でWorkFlowに組み込む（おそらく有償版が必須）、という流れのようです。

オンライン学習も可能という話でした。

### レコーダースクリプトでBOT開発を完結しようとすると死んじゃう

自分は最初、RPA開発にこんなイメージを持ってました。

「RPA開発と言えばレコーディング！」
「レコーディングボタンを押して、操作して見せて、停止ボタンを押せばもう操作が記録されている！」
「誰でも簡単にできちゃう！」

そう…なんですけどね…

少なくともWorkFusionに関して言えば、レコーディングは、
「最初に皆の認識を事前に合わせる程度。とても本番には持っていけない。早めにGroovyスクリプト開発へ移行すべし」と思ってます。
根拠はいくつかありますが…


1. Windowsネイティブアプリケーションは、クリック操作の再現性が低い。
2. sleep処理を指定したり読んだりするのが大変。
3. Studioのアクションとして用意されてないことはできない。
4. 制御文や例外処理はレコーディングではできない。Studioのアクションとしては存在しているが、普通にコード書いた方が速くて正確。

幸い、レコーダースクリプト.rpaeは、Groovyコードを本体に持つBOTスクリプト.xmlに一発で変換できます。([Export code]ボタン）
変にレコーダースクリプトのままで作り込んでいない限り、この変換はうまく行くでしょう。
先にことわっておきますが、.xmlから.rpaeへの変換はできません。
操作を追加したくなったら、他のレコーダースクリプト上で行って、それをxmlへ変換して、対象のコードに貼り付けるという流れになるでしょう。
（それかもしくは直接XML中のGroovyスクリプトを編集する。後述の方法であれば不可能ではないです。）


### BOTスクリプトはそのままだと渡○謙ばりに読めない。その対策。

サンプルとして、メモ帳で「Hello World」を行うレコーダースクリプトを用意しました。
<img width="1014" alt="レコーダースクリプト" src="https://qiita-image-store.s3.amazonaws.com/0/105865/48c430e4-669c-cad9-5681-8fb67d4d1f93.png">

これをXML形式のBOTスクリプトに変換すると以下のようになります。
<img width="1029" alt="BOTスクリプト.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/105865/0030fdcf-9541-a8f8-b00e-cc320b683f56.png">

今話題にしたいのは、26行目～49行目のアクションの指示にあたる部分です。
Groovyで書かれています。


```groovy


inDesktop {
	sendKeys(StringTransformations.getHotKeyText(114, 4))
}




inDesktop {
	sendKeys(StringTransformations.escapeAutoitText("notepad"))
}




inDesktop {
	sendKeys(StringTransformations.getKeyPressText(28, 13, 10, 0))
}




inDesktop {
	sendKeys(StringTransformations.escapeAutoitText("Hello World!"))
}

```


やたら改行が挿入されているのも不可思議ですが、Win+rキー、Enterキーの入力がコード値化されてしまっていて、コードから読み取れなくなっています。（コメントも一緒につけてくれたらいいのに…）
これでは可読性が失われてしまい、保守性が落ちてしまうのは明らかです。
また、テキストを入力する箇所は読み取れますけども、その呼び出しは完全な定型文ですから、
自分で書けるようにしたいです。

というわけで、自分は以下のようなコードスニペットを用意しました。
スニペットを挿入する位置は、import文の後がよいでしょう。

```Groovy
/* BOT Script Utility Snippet Start */

// SnakeCaseの使用はAPI特別するため

def key_action = {func, ... args -> {
		n=1 ->
		inDesktop{
			for(i = 0; i< n; i++){
				sendKeys(func.call(args))
			}
		}
	}
}

def key_press_action = key_action.curry(StringTransformations.&getKeyPressText)

def hot_key_action = key_action.curry(StringTransformations.&getHotKeyText)

// キーマップがわかっていればキー操作関数を自由に定義可能

def enter_key = key_press_action(28,13,10,10)

def win_r_key = hot_key_action(114,4)

def type_text(text){
	inDesktop {
	    // すでに他のタスクプロセスで宣言されている変数を使用する場合、toString()が必要
        // あらかじめつけておく
		sendKeys(StringTransformations.escapeAutoitText(text.toString()))
	}
}

/* BOT Script Utility Snippet End */
```


これにより、先の26行目～49行目のスクリプトは、以下のように整理されます。

```Groovy

win_r_key()

type_text("notepad")

enter_key()

type_text("Hello World!")

```

何をしているスクリプトなのか、読んですぐわかるようになりました。


### スニペットは外部ライブラリ化できるか？

結論から言うと、できます。
BOTスクリプトは、GroovyスクリプトをXMLが内包しているというフォーマットなので、
ちょっと面倒なのですが、自分がやった方法は、

1. スニペット部分を拡張子groovyで別ファイルに保存
2. WorkFusionがアクセス可能なS3ストレージに配置
3. 呼び出したいスクリプト上でファイルを読み込んでevaluateする
4. 適当にthisに関数をバインドする

ただ、その場合でも3と4のコードは残ってしまいますので、
どれだけ効果があるか？微妙でしたので、やりませんでした。
開発の規模に応じて、このあたりを作り込むと良いと思います。


### おわりに

今回の記事は以上です。

この記事が「WorkFusionをやることになった！」という方の、一助になれば幸いです:grinning: